private ASN1 Find(byte[] oid, ASN1 dn) { if (dn.Count == 0) { return(null); } // process SET for (int i = 0; i < dn.Count; i++) { ASN1 set = dn [i]; for (int j = 0; j < set.Count; j++) { ASN1 pair = set [j]; if (pair.Count != 2) { continue; } ASN1 poid = pair [0]; if (poid == null) { continue; } if (poid.CompareValue(oid)) { return(pair); } } } return(null); }
private ASN1 Find(byte[] oid, ASN1 dn) { if (dn.Count == 0) { return(null); } for (int i = 0; i < dn.Count; i++) { ASN1 asn = dn[i]; for (int j = 0; j < asn.Count; j++) { ASN1 asn2 = asn[j]; if (asn2.Count == 2) { ASN1 asn3 = asn2[0]; if (asn3 != null) { if (asn3.CompareValue(oid)) { return(asn2); } } } } } return(null); }
private bool CheckSignature(string fileName) { filename = fileName; Open(filename); entry = GetSecurityEntry(); if (entry == null) { reason = 1; Close(); return(false); } PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo(entry); if (contentInfo.ContentType != "1.2.840.113549.1.7.2") { Close(); return(false); } PKCS7.SignedData signedData = new PKCS7.SignedData(contentInfo.Content); if (signedData.ContentInfo.ContentType != "1.3.6.1.4.1.311.2.1.4") { Close(); return(false); } coll = signedData.Certificates; ASN1 content = signedData.ContentInfo.Content; signedHash = content[0][1][1]; HashAlgorithm hashAlgorithm = null; switch (signedHash.Length) { case 16: hashAlgorithm = HashAlgorithm.Create("MD5"); hash = GetHash(hashAlgorithm); break; case 20: hashAlgorithm = HashAlgorithm.Create("SHA1"); hash = GetHash(hashAlgorithm); break; default: reason = 5; Close(); return(false); } Close(); if (!signedHash.CompareValue(hash)) { reason = 2; } byte[] value = content[0].Value; hashAlgorithm.Initialize(); byte[] calculatedMessageDigest = hashAlgorithm.ComputeHash(value); return(VerifySignature(signedData, calculatedMessageDigest, hashAlgorithm) && reason == 0); }
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 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 CheckSignature (string fileName) { filename = fileName; Open (filename); entry = GetSecurityEntry (); if (entry == null) { // no signature is present reason = 1; Close (); return false; } PKCS7.ContentInfo ci = new PKCS7.ContentInfo (entry); if (ci.ContentType != PKCS7.Oid.signedData) { Close (); return false; } PKCS7.SignedData sd = new PKCS7.SignedData (ci.Content); if (sd.ContentInfo.ContentType != spcIndirectDataContext) { Close (); return false; } coll = sd.Certificates; ASN1 spc = sd.ContentInfo.Content; signedHash = spc [0][1][1]; HashAlgorithm ha = null; switch (signedHash.Length) { case 16: ha = HashAlgorithm.Create ("MD5"); hash = GetHash (ha); break; case 20: ha = HashAlgorithm.Create ("SHA1"); hash = GetHash (ha); break; default: reason = 5; Close (); return false; } Close (); if (!signedHash.CompareValue (hash)) { reason = 2; } // messageDigest is a hash of spcIndirectDataContext (which includes the file hash) byte[] spcIDC = spc [0].Value; ha.Initialize (); // re-using hash instance byte[] messageDigest = ha.ComputeHash (spcIDC); bool sign = VerifySignature (sd, messageDigest, ha); return (sign && (reason == 0)); }
private static void AppendEntry(StringBuilder sb, ASN1 entry, bool quotes) { for (int i = 0; i < entry.Count; i++) { ASN1 asn = entry[i]; ASN1 asn2 = asn[1]; if (asn2 != null) { ASN1 asn3 = asn[0]; if (asn3 != null) { if (asn3.CompareValue(X501.countryName)) { sb.Append("C="); } else if (asn3.CompareValue(X501.organizationName)) { sb.Append("O="); } else if (asn3.CompareValue(X501.organizationalUnitName)) { sb.Append("OU="); } else if (asn3.CompareValue(X501.commonName)) { sb.Append("CN="); } else if (asn3.CompareValue(X501.localityName)) { sb.Append("L="); } else if (asn3.CompareValue(X501.stateOrProvinceName)) { sb.Append("S="); } else if (asn3.CompareValue(X501.streetAddress)) { sb.Append("STREET="); } else if (asn3.CompareValue(X501.domainComponent)) { sb.Append("DC="); } else if (asn3.CompareValue(X501.userid)) { sb.Append("UID="); } else if (asn3.CompareValue(X501.email)) { sb.Append("E="); } else if (asn3.CompareValue(X501.dnQualifier)) { sb.Append("dnQualifier="); } else if (asn3.CompareValue(X501.title)) { sb.Append("T="); } else if (asn3.CompareValue(X501.surname)) { sb.Append("SN="); } else if (asn3.CompareValue(X501.givenName)) { sb.Append("G="); } else if (asn3.CompareValue(X501.initial)) { sb.Append("I="); } else { sb.Append("OID."); sb.Append(ASN1Convert.ToOid(asn3)); sb.Append("="); } string text; if (asn2.Tag == 30) { StringBuilder stringBuilder = new StringBuilder(); for (int j = 1; j < asn2.Value.Length; j += 2) { stringBuilder.Append((char)asn2.Value[j]); } text = stringBuilder.ToString(); } else { if (asn2.Tag == 20) { text = Encoding.UTF7.GetString(asn2.Value); } else { text = Encoding.UTF8.GetString(asn2.Value); } char[] anyOf = new char[] { ',', '+', '"', '\\', '<', '>', ';' }; if (quotes && (text.IndexOfAny(anyOf, 0, text.Length) > 0 || text.StartsWith(" ") || text.EndsWith(" "))) { text = "\"" + text + "\""; } } sb.Append(text); if (i < entry.Count - 1) { sb.Append(", "); } } } } }
static private void AppendEntry(StringBuilder sb, ASN1 entry, bool quotes) { // multiple entries are valid for (int k = 0; k < entry.Count; k++) { ASN1 pair = entry [k]; ASN1 s = pair [1]; if (s == null) { continue; } ASN1 poid = pair [0]; if (poid == null) { continue; } if (poid.CompareValue(countryName)) { sb.Append("C="); } else if (poid.CompareValue(organizationName)) { sb.Append("O="); } else if (poid.CompareValue(organizationalUnitName)) { sb.Append("OU="); } else if (poid.CompareValue(commonName)) { sb.Append("CN="); } else if (poid.CompareValue(localityName)) { sb.Append("L="); } else if (poid.CompareValue(stateOrProvinceName)) { sb.Append("S="); // NOTE: RFC2253 uses ST= } else if (poid.CompareValue(streetAddress)) { sb.Append("STREET="); } else if (poid.CompareValue(domainComponent)) { sb.Append("DC="); } else if (poid.CompareValue(userid)) { sb.Append("UID="); } else if (poid.CompareValue(email)) { sb.Append("E="); // NOTE: Not part of RFC2253 } else if (poid.CompareValue(dnQualifier)) { sb.Append("dnQualifier="); } else if (poid.CompareValue(title)) { sb.Append("T="); } else if (poid.CompareValue(surname)) { sb.Append("SN="); } else if (poid.CompareValue(givenName)) { sb.Append("G="); } else if (poid.CompareValue(initial)) { sb.Append("I="); } else { // unknown OID sb.Append("OID."); // NOTE: Not present as RFC2253 sb.Append(ASN1Convert.ToOid(poid)); sb.Append("="); } string sValue = null; // 16bits or 8bits string ? TODO not complete (+special chars!) if (s.Tag == 0x1E) { // BMPSTRING StringBuilder sb2 = new StringBuilder(); for (int j = 1; j < s.Value.Length; j += 2) { sb2.Append((char)s.Value[j]); } sValue = sb2.ToString(); } else { if (s.Tag == 0x14) { sValue = Encoding.UTF7.GetString(s.Value); } else { sValue = Encoding.UTF8.GetString(s.Value); } // in some cases we must quote (") the value // Note: this doesn't seems to conform to RFC2253 char[] specials = { ',', '+', '"', '\\', '<', '>', ';' }; if (quotes) { if ((sValue.IndexOfAny(specials, 0, sValue.Length) > 0) || sValue.StartsWith(" ") || (sValue.EndsWith(" "))) { sValue = "\"" + sValue + "\""; } } } sb.Append(sValue); // separator (not on last iteration) if (k < entry.Count - 1) { sb.Append(", "); } } }
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(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); }