diff options
author | Sebastien Pouliot <sebastien@ximian.com> | 2004-05-19 15:24:52 +0400 |
---|---|---|
committer | Sebastien Pouliot <sebastien@ximian.com> | 2004-05-19 15:24:52 +0400 |
commit | 66bce2561f4aff51acc0e4c67141f58a65601038 (patch) | |
tree | 0d73c9eb82d800ae76b01026419c573978ff2c81 /mcs/class/Mono.Security | |
parent | bce2e1bb6a7a78221a5ec82f3853e45a18f99f90 (diff) |
2004-05-19 Jesper Pedersen <jep@itplus.dk>
* PKCS7.cs: Added SignedData.VerifySignature(AsymmetricAlgorithm aa).
Added support for calculating signature from SignedData content (i.e.
when UseAuthenticatedAttributes is false). Added contentType to
AuthenticatedAttributes (when SignedData.UseAuthenticatedAttributes
is true).
svn path=/trunk/mcs/; revision=27662
Diffstat (limited to 'mcs/class/Mono.Security')
-rw-r--r-- | mcs/class/Mono.Security/Mono.Security/ChangeLog | 8 | ||||
-rw-r--r-- | mcs/class/Mono.Security/Mono.Security/PKCS7.cs | 124 |
2 files changed, 114 insertions, 18 deletions
diff --git a/mcs/class/Mono.Security/Mono.Security/ChangeLog b/mcs/class/Mono.Security/Mono.Security/ChangeLog index 297a69983f3..a2ae1882129 100644 --- a/mcs/class/Mono.Security/Mono.Security/ChangeLog +++ b/mcs/class/Mono.Security/Mono.Security/ChangeLog @@ -1,3 +1,11 @@ +2004-05-19 Jesper Pedersen <jep@itplus.dk> + + * PKCS7.cs: Added SignedData.VerifySignature(AsymmetricAlgorithm aa). + Added support for calculating signature from SignedData content (i.e. + when UseAuthenticatedAttributes is false). Added contentType to + AuthenticatedAttributes (when SignedData.UseAuthenticatedAttributes + is true). + 2004-05-11 Sebastien Pouliot <sebastien@ximian.com> * ASN1Convert.cs: Added better exceptions. Fixed bugs found by new diff --git a/mcs/class/Mono.Security/Mono.Security/PKCS7.cs b/mcs/class/Mono.Security/Mono.Security/PKCS7.cs index ccacafc685f..fd52bbb5673 100644 --- a/mcs/class/Mono.Security/Mono.Security/PKCS7.cs +++ b/mcs/class/Mono.Security/Mono.Security/PKCS7.cs @@ -527,7 +527,7 @@ namespace Mono.Security { private X509CertificateCollection certs; private ArrayList crls; private SignerInfo signerInfo; - private ASN1 mda; + private bool mda; public SignedData () { @@ -536,6 +536,7 @@ namespace Mono.Security { certs = new X509CertificateCollection (); crls = new ArrayList (); signerInfo = new SignerInfo (); + mda = true; } public SignedData (byte[] data) @@ -552,8 +553,6 @@ namespace Mono.Security { throw new ArgumentException ("Invalid version"); version = asn1[0][0].Value[0]; - // digestInfo - contentInfo = new ContentInfo (asn1[0][2]); int n = 3; @@ -575,6 +574,14 @@ namespace Mono.Security { signerInfo = new SignerInfo (asn1[0][n]); else signerInfo = new SignerInfo (); + + // Exchange hash algorithm Oid from SignerInfo + if (signerInfo.HashName != null) { + HashName = OidToName(signerInfo.HashName); + } + + // Check if SignerInfo has authenticated attributes + mda = (signerInfo.AuthenticatedAttributes.Count > 0); } public ASN1 ASN1 { @@ -611,6 +618,62 @@ namespace Mono.Security { set { version = value; } } + public bool UseAuthenticatedAttributes { + get { return mda; } + set { mda = value; } + } + + public bool VerifySignature (AsymmetricAlgorithm aa) + { + if (aa == null) { + return false; + } + + RSAPKCS1SignatureDeformatter r = new RSAPKCS1SignatureDeformatter (aa); + r.SetHashAlgorithm (hashAlgorithm); + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + + byte[] signature = signerInfo.Signature; + byte[] hash = null; + + if (mda) { + ASN1 asn = new ASN1 (0x31); + foreach (ASN1 attr in signerInfo.AuthenticatedAttributes) + asn.Add (attr); + + hash = ha.ComputeHash (asn.GetBytes ()); + } else { + hash = ha.ComputeHash (contentInfo.Content[0].Value); + } + + if (hash != null && signature != null) { + return r.VerifySignature (hash, signature); + } + return false; + } + + internal string OidToName (string oid) + { + switch (oid) { + case "1.3.14.3.2.26" : + return "SHA1"; + case "1.2.840.113549.2.2" : + return "MD2"; + case "1.2.840.113549.2.5" : + return "MD5"; + case "2.16.840.1.101.3.4.1" : + return "SHA256"; + case "2.16.840.1.101.3.4.2" : + return "SHA384"; + case "2.16.840.1.101.3.4.3" : + return "SHA512"; + default : + break; + } + // Unknown Oid + return oid; + } + internal ASN1 GetASN1 () { // SignedData ::= SEQUENCE { @@ -628,13 +691,28 @@ namespace Mono.Security { // contentInfo ContentInfo, ASN1 ci = contentInfo.ASN1; signedData.Add (ci); - if ((mda == null) && (hashAlgorithm != null)) { - // automatically add the messageDigest authenticated attribute - HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); - byte[] idcHash = ha.ComputeHash (ci[1][0].Value); - ASN1 md = new ASN1 (0x30); - mda = Attribute (Oid.messageDigest, md.Add (new ASN1 (0x04, idcHash))); - signerInfo.AuthenticatedAttributes.Add (mda); + if (hashAlgorithm != null) { + if (mda) { + // Use authenticated attributes for signature + + // Automatically add the contentType authenticated attribute + ASN1 ctattr = Attribute (Oid.contentType, ci[0]); + signerInfo.AuthenticatedAttributes.Add (ctattr); + + // Automatically add the messageDigest authenticated attribute + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + byte[] idcHash = ha.ComputeHash (ci[1][0].Value); + ASN1 md = new ASN1 (0x30); + ASN1 mdattr = Attribute (Oid.messageDigest, md.Add (new ASN1 (0x04, idcHash))); + signerInfo.AuthenticatedAttributes.Add (mdattr); + } else { + // Don't use authenticated attributes for signature -- signature is content + RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (signerInfo.Key); + r.SetHashAlgorithm (hashAlgorithm); + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + byte[] sig = ha.ComputeHash (ci[1][0].Value); + signerInfo.Signature = r.CreateSignature (sig); + } } // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, @@ -798,6 +876,12 @@ namespace Mono.Security { return null; return (byte[]) signature.Clone (); } + + set { + if (value != null) { + signature = (byte[]) value.Clone (); + } + } } public ArrayList UnauthenticatedAttributes { @@ -823,8 +907,9 @@ namespace Mono.Security { string hashOid = CryptoConfig.MapNameToOID (hashAlgorithm); signerInfo.Add (AlgorithmIdentifier (hashOid)); // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, - ASN1 aa = signerInfo.Add (new ASN1 (0xA0)); + ASN1 aa = null; if (authenticatedAttributes.Count > 0) { + aa = signerInfo.Add (new ASN1 (0xA0)); foreach (ASN1 attr in authenticatedAttributes) aa.Add (attr); } @@ -832,13 +917,16 @@ namespace Mono.Security { if (key is RSA) { signerInfo.Add (AlgorithmIdentifier (PKCS7.Oid.rsaEncryption)); - RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (key); - r.SetHashAlgorithm (hashAlgorithm); - byte[] tbs = aa.GetBytes (); - tbs [0] = 0x31; // not 0xA0 for signature - HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); - byte[] tbsHash = ha.ComputeHash (tbs); - signature = r.CreateSignature (tbsHash); + if (aa != null) { + // Calculate the signature here; otherwise it must be set from SignedData + RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (key); + r.SetHashAlgorithm (hashAlgorithm); + byte[] tbs = aa.GetBytes (); + tbs [0] = 0x31; // not 0xA0 for signature + HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm); + byte[] tbsHash = ha.ComputeHash (tbs); + signature = r.CreateSignature (tbsHash); + } } else if (key is DSA) { throw new NotImplementedException ("not yet"); |