private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature) { // SEQUENCE { // INTEGER 1 if (cs.Version != 1) { return(false); } // SEQUENCE { // SEQUENCE { string contentType = null; ASN1 messageDigest = null; for (int i = 0; i < cs.AuthenticatedAttributes.Count; i++) { // SEQUENCE { // OBJECT IDENTIFIER ASN1 attr = (ASN1)cs.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid(attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid(attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.2.840.113549.1.9.5": // SEQUENCE { // OBJECT IDENTIFIER // signingTime (1 2 840 113549 1 9 5) // SET { // UTCTime '030124013651Z' // } // } timestamp = ASN1Convert.ToDateTime(attr[1][0]); break; default: break; } } if (contentType != PKCS7.Oid.data) { return(false); } // verify message digest if (messageDigest == null) { return(false); } // TODO: must be read from the ASN.1 structure string hashName = null; switch (messageDigest.Length) { case 16: hashName = "MD5"; break; case 20: hashName = "SHA1"; break; } HashAlgorithm ha = HashAlgorithm.Create(hashName); if (!messageDigest.CompareValue(ha.ComputeHash(signature))) { return(false); } // verify signature byte[] counterSignature = cs.Signature; // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1(0x31); foreach (ASN1 a in cs.AuthenticatedAttributes) { aa.Add(a); } byte[] p7hash = ha.ComputeHash(aa.GetBytes()); // we need to try all certificates string issuer = cs.IssuerName; byte[] serial = cs.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial(issuer, serial, x509)) { if (x509.PublicKey.Length > counterSignature.Length) { RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.RSA; // we need to HACK around bad (PKCS#1 1.5) signatures made by Verisign Timestamp Service // and this means copying stuff into our own RSAManaged to get the required flexibility RSAManaged rsam = new RSAManaged(); rsam.ImportParameters(rsa.ExportParameters(false)); if (PKCS1.Verify_v15(rsam, ha, p7hash, counterSignature, true)) { timestampChain.LoadCertificates(coll); return(timestampChain.Build(x509)); } } } } // no certificate can verify this signature! return(false); }
private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature) { if (cs.Version != 1) { return(false); } string a = null; ASN1 asn = null; int i = 0; while (i < cs.AuthenticatedAttributes.Count) { ASN1 asn2 = (ASN1)cs.AuthenticatedAttributes[i]; string text = ASN1Convert.ToOid(asn2[0]); string text2 = text; switch (text2) { case "1.2.840.113549.1.9.3": a = ASN1Convert.ToOid(asn2[1][0]); break; case "1.2.840.113549.1.9.4": asn = asn2[1][0]; break; case "1.2.840.113549.1.9.5": this.timestamp = ASN1Convert.ToDateTime(asn2[1][0]); break; } IL_FC: i++; continue; goto IL_FC; } if (a != "1.2.840.113549.1.7.1") { return(false); } if (asn == null) { return(false); } string hashName = null; int length = asn.Length; if (length != 16) { if (length == 20) { hashName = "SHA1"; } } else { hashName = "MD5"; } HashAlgorithm hashAlgorithm = HashAlgorithm.Create(hashName); if (!asn.CompareValue(hashAlgorithm.ComputeHash(signature))) { return(false); } byte[] signature2 = cs.Signature; ASN1 asn3 = new ASN1(49); foreach (object obj in cs.AuthenticatedAttributes) { ASN1 asn4 = (ASN1)obj; asn3.Add(asn4); } byte[] hashValue = hashAlgorithm.ComputeHash(asn3.GetBytes()); string issuerName = cs.IssuerName; byte[] serialNumber = cs.SerialNumber; foreach (X509Certificate x509Certificate in this.coll) { if (this.CompareIssuerSerial(issuerName, serialNumber, x509Certificate) && x509Certificate.PublicKey.Length > signature2.Length) { RSACryptoServiceProvider rsacryptoServiceProvider = (RSACryptoServiceProvider)x509Certificate.RSA; RSAManaged rsamanaged = new RSAManaged(); rsamanaged.ImportParameters(rsacryptoServiceProvider.ExportParameters(false)); if (PKCS1.Verify_v15(rsamanaged, hashAlgorithm, hashValue, signature2, true)) { this.timestampChain.LoadCertificates(this.coll); return(this.timestampChain.Build(x509Certificate)); } } } return(false); }
//private bool VerifySignature (ASN1 cs, byte[] calculatedMessageDigest, string hashName) private bool VerifySignature(PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) { string contentType = null; ASN1 messageDigest = null; // string spcStatementType = null; // string spcSpOpusInfo = null; for (int i = 0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1)sd.SignerInfo.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid(attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid(attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.3.6.1.4.1.311.2.1.11": // spcStatementType (Microsoft code signing) // possible values // - individualCodeSigning (1 3 6 1 4 1 311 2 1 21) // - commercialCodeSigning (1 3 6 1 4 1 311 2 1 22) // spcStatementType = ASN1Convert.ToOid (attr[1][0][0]); break; case "1.3.6.1.4.1.311.2.1.12": // spcSpOpusInfo (Microsoft code signing) /* try { * spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][0][0].Value); * } * catch (NullReferenceException) { * spcSpOpusInfo = null; * }*/ break; default: break; } } if (contentType != spcIndirectDataContext) { return(false); } // verify message digest if (messageDigest == null) { return(false); } if (!messageDigest.CompareValue(calculatedMessageDigest)) { return(false); } // verify signature string hashOID = CryptoConfig.MapNameToOID(ha.ToString()); // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1(0x31); foreach (ASN1 a in sd.SignerInfo.AuthenticatedAttributes) { aa.Add(a); } ha.Initialize(); byte[] p7hash = ha.ComputeHash(aa.GetBytes()); byte[] signature = sd.SignerInfo.Signature; // we need to find the specified certificate string issuer = sd.SignerInfo.IssuerName; byte[] serial = sd.SignerInfo.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial(issuer, serial, x509)) { // don't verify is key size don't match if (x509.PublicKey.Length > (signature.Length >> 3)) { // return the signing certificate even if the signature isn't correct // (required behaviour for 2.0 support) signingCertificate = x509; RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.RSA; if (rsa.VerifyHash(p7hash, hashOID, signature)) { signerChain.LoadCertificates(coll); trustedRoot = signerChain.Build(x509); break; } } } } // timestamp signature is optional if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { trustedTimestampRoot = true; } else { for (int i = 0; i < sd.SignerInfo.UnauthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1)sd.SignerInfo.UnauthenticatedAttributes[i]; string oid = ASN1Convert.ToOid(attr[0]); switch (oid) { case PKCS7.Oid.countersignature: // SEQUENCE { // OBJECT IDENTIFIER // countersignature (1 2 840 113549 1 9 6) // SET { PKCS7.SignerInfo cs = new PKCS7.SignerInfo(attr[1]); trustedTimestampRoot = VerifyCounterSignature(cs, signature); break; default: // we don't support other unauthenticated attributes break; } } } return(trustedRoot && trustedTimestampRoot); }
//private bool VerifySignature (ASN1 cs, byte[] calculatedMessageDigest, string hashName) private bool VerifySignature (PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) { string contentType = null; ASN1 messageDigest = null; // string spcStatementType = null; // string spcSpOpusInfo = null; for (int i=0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1) sd.SignerInfo.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid (attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid (attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.3.6.1.4.1.311.2.1.11": // spcStatementType (Microsoft code signing) // possible values // - individualCodeSigning (1 3 6 1 4 1 311 2 1 21) // - commercialCodeSigning (1 3 6 1 4 1 311 2 1 22) // spcStatementType = ASN1Convert.ToOid (attr[1][0][0]); break; case "1.3.6.1.4.1.311.2.1.12": // spcSpOpusInfo (Microsoft code signing) /* try { spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][0][0].Value); } catch (NullReferenceException) { spcSpOpusInfo = null; }*/ break; default: break; } } if (contentType != spcIndirectDataContext) return false; // verify message digest if (messageDigest == null) return false; if (!messageDigest.CompareValue (calculatedMessageDigest)) return false; // verify signature string hashOID = CryptoConfig.MapNameToOID (ha.ToString ()); // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1 (0x31); foreach (ASN1 a in sd.SignerInfo.AuthenticatedAttributes) aa.Add (a); ha.Initialize (); byte[] p7hash = ha.ComputeHash (aa.GetBytes ()); byte[] signature = sd.SignerInfo.Signature; // we need to find the specified certificate string issuer = sd.SignerInfo.IssuerName; byte[] serial = sd.SignerInfo.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial (issuer, serial, x509)) { // don't verify is key size don't match if (x509.PublicKey.Length > (signature.Length >> 3)) { // return the signing certificate even if the signature isn't correct // (required behaviour for 2.0 support) signingCertificate = x509; RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA; if (rsa.VerifyHash (p7hash, hashOID, signature)) { signerChain.LoadCertificates (coll); trustedRoot = signerChain.Build (x509); break; } } } } // timestamp signature is optional if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { trustedTimestampRoot = true; } else { for (int i = 0; i < sd.SignerInfo.UnauthenticatedAttributes.Count; i++) { ASN1 attr = (ASN1) sd.SignerInfo.UnauthenticatedAttributes[i]; string oid = ASN1Convert.ToOid (attr[0]); switch (oid) { case PKCS7.Oid.countersignature: // SEQUENCE { // OBJECT IDENTIFIER // countersignature (1 2 840 113549 1 9 6) // SET { PKCS7.SignerInfo cs = new PKCS7.SignerInfo (attr[1]); trustedTimestampRoot = VerifyCounterSignature (cs, signature); break; default: // we don't support other unauthenticated attributes break; } } } return (trustedRoot && trustedTimestampRoot); }
private bool VerifySignature(PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) { string a = null; ASN1 asn = null; int i = 0; while (i < sd.SignerInfo.AuthenticatedAttributes.Count) { ASN1 asn2 = (ASN1)sd.SignerInfo.AuthenticatedAttributes[i]; string text = ASN1Convert.ToOid(asn2[0]); string text2 = text; switch (text2) { case "1.2.840.113549.1.9.3": a = ASN1Convert.ToOid(asn2[1][0]); break; case "1.2.840.113549.1.9.4": asn = asn2[1][0]; break; } IL_F1: i++; continue; goto IL_F1; } if (a != "1.3.6.1.4.1.311.2.1.4") { return(false); } if (asn == null) { return(false); } if (!asn.CompareValue(calculatedMessageDigest)) { return(false); } string str = CryptoConfig.MapNameToOID(ha.ToString()); ASN1 asn3 = new ASN1(49); foreach (object obj in sd.SignerInfo.AuthenticatedAttributes) { ASN1 asn4 = (ASN1)obj; asn3.Add(asn4); } ha.Initialize(); byte[] rgbHash = ha.ComputeHash(asn3.GetBytes()); byte[] signature = sd.SignerInfo.Signature; string issuerName = sd.SignerInfo.IssuerName; byte[] serialNumber = sd.SignerInfo.SerialNumber; foreach (X509Certificate x509Certificate in this.coll) { if (this.CompareIssuerSerial(issuerName, serialNumber, x509Certificate) && x509Certificate.PublicKey.Length > signature.Length >> 3) { this.signingCertificate = x509Certificate; RSACryptoServiceProvider rsacryptoServiceProvider = (RSACryptoServiceProvider)x509Certificate.RSA; if (rsacryptoServiceProvider.VerifyHash(rgbHash, str, signature)) { this.signerChain.LoadCertificates(this.coll); this.trustedRoot = this.signerChain.Build(x509Certificate); break; } } } if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { this.trustedTimestampRoot = true; } else { int j = 0; while (j < sd.SignerInfo.UnauthenticatedAttributes.Count) { ASN1 asn5 = (ASN1)sd.SignerInfo.UnauthenticatedAttributes[j]; string text3 = ASN1Convert.ToOid(asn5[0]); string text2 = text3; if (text2 != null) { if (AuthenticodeDeformatter.< > f__switch$map2 == null) { AuthenticodeDeformatter.< > f__switch$map2 = new Dictionary <string, int>(1) { { "1.2.840.113549.1.9.6", 0 } }; } int num; if (AuthenticodeDeformatter.< > f__switch$map2.TryGetValue(text2, out num)) { if (num == 0) { PKCS7.SignerInfo cs = new PKCS7.SignerInfo(asn5[1]); this.trustedTimestampRoot = this.VerifyCounterSignature(cs, signature); } } } IL_35D: j++; continue; goto IL_35D; } } return(this.trustedRoot && this.trustedTimestampRoot); }
private bool VerifySignature(PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) { string str = null; ASN1 asn = null; string str3; Dictionary <string, int> dictionary; for (int i = 0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++) { ASN1 asn2 = (ASN1)sd.SignerInfo.AuthenticatedAttributes[i]; str3 = ASN1Convert.ToOid(asn2[0]); if (str3 != null) { if (__f__switch_map1 == null) { dictionary = new Dictionary <string, int>(4) { { "1.2.840.113549.1.9.3", 0 }, { "1.2.840.113549.1.9.4", 1 }, { "1.3.6.1.4.1.311.2.1.11", 2 }, { "1.3.6.1.4.1.311.2.1.12", 3 } }; __f__switch_map1 = dictionary; } if (__f__switch_map1.TryGetValue(str3, out int num2)) { switch (num2) { case 0: str = ASN1Convert.ToOid(asn2[1][0]); break; case 1: asn = asn2[1][0]; break; } } } } if (str != "1.3.6.1.4.1.311.2.1.4") { return(false); } if (asn == null) { return(false); } if (!asn.CompareValue(calculatedMessageDigest)) { return(false); } string str4 = CryptoConfig.MapNameToOID(ha.ToString()); ASN1 asn3 = new ASN1(0x31); IEnumerator enumerator = sd.SignerInfo.AuthenticatedAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { ASN1 current = (ASN1)enumerator.Current; asn3.Add(current); } } finally { if (enumerator is IDisposable disposable) { disposable.Dispose(); } } ha.Initialize(); byte[] rgbHash = ha.ComputeHash(asn3.GetBytes()); byte[] signature = sd.SignerInfo.Signature; string issuerName = sd.SignerInfo.IssuerName; byte[] serialNumber = sd.SignerInfo.SerialNumber; X509CertificateCollection.X509CertificateEnumerator enumerator2 = this.coll.GetEnumerator(); try { while (enumerator2.MoveNext()) { X509Certificate current = enumerator2.Current; if (this.CompareIssuerSerial(issuerName, serialNumber, current) && (current.PublicKey.Length > (signature.Length >> 3))) { this.signingCertificate = current; RSACryptoServiceProvider rSA = (RSACryptoServiceProvider)current.RSA; if (rSA.VerifyHash(rgbHash, str4, signature)) { this.signerChain.LoadCertificates(this.coll); this.trustedRoot = this.signerChain.Build(current); goto Label_0295; } } } } finally { if (enumerator2 is IDisposable disposable2) { disposable2.Dispose(); } } Label_0295: if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { this.trustedTimestampRoot = true; } else { for (int j = 0; j < sd.SignerInfo.UnauthenticatedAttributes.Count; j++) { ASN1 asn5 = (ASN1)sd.SignerInfo.UnauthenticatedAttributes[j]; str3 = ASN1Convert.ToOid(asn5[0]); if (str3 != null) { if (__f__switch_map2 == null) { dictionary = new Dictionary <string, int>(1) { { "1.2.840.113549.1.9.6", 0 } }; __f__switch_map2 = dictionary; } if (__f__switch_map2.TryGetValue(str3, out int num2) && (num2 == 0)) { PKCS7.SignerInfo cs = new PKCS7.SignerInfo(asn5[1]); this.trustedTimestampRoot = this.VerifyCounterSignature(cs, signature); } } } } return(this.trustedRoot && this.trustedTimestampRoot); }
private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature) { if (cs.Version == 1) { string str = null; ASN1 asn = null; for (int i = 0; i < cs.AuthenticatedAttributes.Count; i++) { ASN1 asn2 = (ASN1)cs.AuthenticatedAttributes[i]; string key = ASN1Convert.ToOid(asn2[0]); if (key != null) { if (__f__switch_map3 == null) { Dictionary <string, int> dictionary = new Dictionary <string, int>(3) { { "1.2.840.113549.1.9.3", 0 }, { "1.2.840.113549.1.9.4", 1 }, { "1.2.840.113549.1.9.5", 2 } }; __f__switch_map3 = dictionary; } if (__f__switch_map3.TryGetValue(key, out int num2)) { switch (num2) { case 0: str = ASN1Convert.ToOid(asn2[1][0]); break; case 1: asn = asn2[1][0]; break; case 2: this.timestamp = ASN1Convert.ToDateTime(asn2[1][0]); break; } } } } if (str != "1.2.840.113549.1.7.1") { return(false); } if (asn == null) { return(false); } string hashName = null; switch (asn.Length) { case 0x10: hashName = "MD5"; break; case 20: hashName = "SHA1"; break; } HashAlgorithm hash = HashAlgorithm.Create(hashName); if (asn.CompareValue(hash.ComputeHash(signature))) { byte[] buffer = cs.Signature; ASN1 asn3 = new ASN1(0x31); IEnumerator enumerator = cs.AuthenticatedAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { ASN1 current = (ASN1)enumerator.Current; asn3.Add(current); } } finally { if (enumerator is IDisposable disposable) { disposable.Dispose(); } } byte[] hashValue = hash.ComputeHash(asn3.GetBytes()); string issuerName = cs.IssuerName; byte[] serialNumber = cs.SerialNumber; X509CertificateCollection.X509CertificateEnumerator enumerator2 = this.coll.GetEnumerator(); try { while (enumerator2.MoveNext()) { X509Certificate current = enumerator2.Current; if (this.CompareIssuerSerial(issuerName, serialNumber, current) && (current.PublicKey.Length > buffer.Length)) { RSACryptoServiceProvider rSA = (RSACryptoServiceProvider)current.RSA; RSAManaged rsa = new RSAManaged(); rsa.ImportParameters(rSA.ExportParameters(false)); if (PKCS1.Verify_v15(rsa, hash, hashValue, buffer, true)) { this.timestampChain.LoadCertificates(this.coll); return(this.timestampChain.Build(current)); } } } } finally { if (enumerator2 is IDisposable disposable2) { disposable2.Dispose(); } } } } return(false); }
private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature) { if (cs.Version != 1) { return(false); } string a = null; ASN1 aSN = null; for (int i = 0; i < cs.AuthenticatedAttributes.Count; i++) { ASN1 aSN2 = (ASN1)cs.AuthenticatedAttributes[i]; switch (ASN1Convert.ToOid(aSN2[0])) { case "1.2.840.113549.1.9.3": a = ASN1Convert.ToOid(aSN2[1][0]); break; case "1.2.840.113549.1.9.4": aSN = aSN2[1][0]; break; case "1.2.840.113549.1.9.5": timestamp = ASN1Convert.ToDateTime(aSN2[1][0]); break; } } if (a != "1.2.840.113549.1.7.1") { return(false); } if (aSN == null) { return(false); } string hashName = null; switch (aSN.Length) { case 16: hashName = "MD5"; break; case 20: hashName = "SHA1"; break; } HashAlgorithm hashAlgorithm = HashAlgorithm.Create(hashName); if (!aSN.CompareValue(hashAlgorithm.ComputeHash(signature))) { return(false); } byte[] signature2 = cs.Signature; ASN1 aSN3 = new ASN1(49); foreach (ASN1 authenticatedAttribute in cs.AuthenticatedAttributes) { aSN3.Add(authenticatedAttribute); } byte[] hashValue = hashAlgorithm.ComputeHash(aSN3.GetBytes()); string issuerName = cs.IssuerName; byte[] serialNumber = cs.SerialNumber; foreach (X509Certificate item in coll) { if (CompareIssuerSerial(issuerName, serialNumber, item) && item.PublicKey.Length > signature2.Length) { RSACryptoServiceProvider rSACryptoServiceProvider = (RSACryptoServiceProvider)item.RSA; RSAManaged rSAManaged = new RSAManaged(); rSAManaged.ImportParameters(rSACryptoServiceProvider.ExportParameters(includePrivateParameters: false)); if (PKCS1.Verify_v15(rSAManaged, hashAlgorithm, hashValue, signature2, tryNonStandardEncoding: true)) { timestampChain.LoadCertificates(coll); return(timestampChain.Build(item)); } } } return(false); }
private bool VerifySignature(PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha) { string a = null; ASN1 aSN = null; for (int i = 0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++) { ASN1 aSN2 = (ASN1)sd.SignerInfo.AuthenticatedAttributes[i]; switch (ASN1Convert.ToOid(aSN2[0])) { case "1.2.840.113549.1.9.3": a = ASN1Convert.ToOid(aSN2[1][0]); break; case "1.2.840.113549.1.9.4": aSN = aSN2[1][0]; break; } } if (a != "1.3.6.1.4.1.311.2.1.4") { return(false); } if (aSN == null) { return(false); } if (!aSN.CompareValue(calculatedMessageDigest)) { return(false); } string str = CryptoConfig.MapNameToOID(ha.ToString()); ASN1 aSN3 = new ASN1(49); foreach (ASN1 authenticatedAttribute in sd.SignerInfo.AuthenticatedAttributes) { aSN3.Add(authenticatedAttribute); } ha.Initialize(); byte[] rgbHash = ha.ComputeHash(aSN3.GetBytes()); byte[] signature = sd.SignerInfo.Signature; string issuerName = sd.SignerInfo.IssuerName; byte[] serialNumber = sd.SignerInfo.SerialNumber; foreach (X509Certificate item in coll) { if (CompareIssuerSerial(issuerName, serialNumber, item) && item.PublicKey.Length > signature.Length >> 3) { signingCertificate = item; RSACryptoServiceProvider rSACryptoServiceProvider = (RSACryptoServiceProvider)item.RSA; if (rSACryptoServiceProvider.VerifyHash(rgbHash, str, signature)) { signerChain.LoadCertificates(coll); trustedRoot = signerChain.Build(item); break; } } } if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0) { trustedTimestampRoot = true; } else { for (int j = 0; j < sd.SignerInfo.UnauthenticatedAttributes.Count; j++) { ASN1 aSN4 = (ASN1)sd.SignerInfo.UnauthenticatedAttributes[j]; switch (ASN1Convert.ToOid(aSN4[0])) { case "1.2.840.113549.1.9.6": { PKCS7.SignerInfo cs = new PKCS7.SignerInfo(aSN4[1]); trustedTimestampRoot = VerifyCounterSignature(cs, signature); break; } } } } return(trustedRoot && trustedTimestampRoot); }
private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature) { // SEQUENCE { // INTEGER 1 if (cs.Version != 1) { return(false); } // SEQUENCE { // SEQUENCE { string contentType = null; ASN1 messageDigest = null; for (int i = 0; i < cs.AuthenticatedAttributes.Count; i++) { // SEQUENCE { // OBJECT IDENTIFIER ASN1 attr = (ASN1)cs.AuthenticatedAttributes [i]; string oid = ASN1Convert.ToOid(attr[0]); switch (oid) { case "1.2.840.113549.1.9.3": // contentType contentType = ASN1Convert.ToOid(attr[1][0]); break; case "1.2.840.113549.1.9.4": // messageDigest messageDigest = attr[1][0]; break; case "1.2.840.113549.1.9.5": // SEQUENCE { // OBJECT IDENTIFIER // signingTime (1 2 840 113549 1 9 5) // SET { // UTCTime '030124013651Z' // } // } timestamp = ASN1Convert.ToDateTime(attr[1][0]); break; default: break; } } if (contentType != PKCS7.Oid.data) { return(false); } // verify message digest if (messageDigest == null) { return(false); } // TODO: must be read from the ASN.1 structure string hashName = null; switch (messageDigest.Length) { case 16: hashName = "MD5"; break; case 20: hashName = "SHA1"; break; } HashAlgorithm ha = HashAlgorithm.Create(hashName); if (!messageDigest.CompareValue(ha.ComputeHash(signature))) { return(false); } // verify signature byte[] counterSignature = cs.Signature; string hashOID = CryptoConfig.MapNameToOID(hashName); // change to SET OF (not [0]) as per PKCS #7 1.5 ASN1 aa = new ASN1(0x31); foreach (ASN1 a in cs.AuthenticatedAttributes) { aa.Add(a); } byte[] p7hash = ha.ComputeHash(aa.GetBytes()); // we need to try all certificates string issuer = cs.IssuerName; byte[] serial = cs.SerialNumber; foreach (X509Certificate x509 in coll) { if (CompareIssuerSerial(issuer, serial, x509)) { // don't verify if key size don't match if (x509.PublicKey.Length > (counterSignature.Length >> 3)) { RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.RSA; if (rsa.VerifyHash(p7hash, hashOID, counterSignature)) { timestampChain.LoadCertificates(coll); return(timestampChain.Build(x509)); } } } } // no certificate can verify this signature! return(false); }