public bool Sign(string fileName) { try { base.Open(fileName); HashAlgorithm hashAlgorithm = HashAlgorithm.Create(this.Hash); byte[] fileHash = base.GetHash(hashAlgorithm); byte[] signature = this.Header(fileHash, this.Hash); if (this.timestamp != null) { byte[] response = this.Timestamp(signature); this.ProcessTimestamp(response); } PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo("1.2.840.113549.1.7.2"); contentInfo.Content.Add(this.pkcs7.ASN1); this.authenticode = contentInfo.ASN1; base.Close(); return(this.Save(fileName, this.authenticode.GetBytes())); } catch (Exception value) { Console.WriteLine(value); } return(false); }
public static Oid GetContentType(byte[] encodedMessage) { if (encodedMessage == null) { throw new ArgumentNullException("algorithm"); } try { PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage); switch (ci.ContentType) { case PKCS7.Oid.data: case PKCS7.Oid.signedData: // see SignedCms class case PKCS7.Oid.envelopedData: // see EnvelopedCms class case PKCS7.Oid.digestedData: case PKCS7.Oid.encryptedData: return(new Oid(ci.ContentType)); default: // Note: the constructor will accept any "valid" OID (but that // doesn't mean it's a valid ContentType structure - ASN.1 wise). string msg = Locale.GetText("Bad ASN1 - invalid OID '{0}'"); throw new CryptographicException(String.Format(msg, ci.ContentType)); } } catch (Exception e) { throw new CryptographicException(Locale.GetText("Bad ASN1 - invalid structure"), e); } }
// in case we just want to timestamp the file public bool Timestamp(string fileName) { try { AuthenticodeDeformatter def = new AuthenticodeDeformatter(fileName); byte[] signature = def.Signature; if (signature != null) { Open(fileName); PKCS7.ContentInfo ci = new PKCS7.ContentInfo(signature); pkcs7 = new PKCS7.SignedData(ci.Content); byte[] response = Timestamp(pkcs7.SignerInfo.Signature); ASN1 ts = new ASN1(Convert.FromBase64String(Encoding.ASCII.GetString(response))); // insert new certificates and countersignature into the original signature ASN1 asn = new ASN1(signature); ASN1 content = asn.Element(1, 0xA0); if (content == null) { return(false); } ASN1 signedData = content.Element(0, 0x30); if (signedData == null) { return(false); } // add the supplied certificates inside our signature ASN1 certificates = signedData.Element(3, 0xA0); if (certificates == null) { certificates = new ASN1(0xA0); signedData.Add(certificates); } for (int i = 0; i < ts[1][0][3].Count; i++) { certificates.Add(ts[1][0][3][i]); } // add an unauthentified attribute to our signature ASN1 signerInfoSet = signedData[signedData.Count - 1]; ASN1 signerInfo = signerInfoSet[0]; ASN1 unauthenticated = signerInfo[signerInfo.Count - 1]; if (unauthenticated.Tag != 0xA1) { unauthenticated = new ASN1(0xA1); signerInfo.Add(unauthenticated); } unauthenticated.Add(Attribute(countersignature, ts[1][0][4][0])); return(Save(fileName, asn.GetBytes())); } } catch (Exception e) { Console.WriteLine(e); } return(false); }
public bool Sign(string fileName) { try { Open(fileName); HashAlgorithm hashAlgorithm = HashAlgorithm.Create(Hash); byte[] fileHash = GetHash(hashAlgorithm); byte[] signature = Header(fileHash, Hash); if (timestamp != null) { byte[] response = Timestamp(signature); ProcessTimestamp(response); } PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo("1.2.840.113549.1.7.2"); contentInfo.Content.Add(pkcs7.ASN1); authenticode = contentInfo.ASN1; Close(); return(Save(fileName, authenticode.GetBytes())); IL_0099 :; } catch (Exception value) { Console.WriteLine(value); } return(false); }
public bool Sign(string fileName) { try { Open(fileName); HashAlgorithm hash = HashAlgorithm.Create(Hash); // 0 to 215 (216) then skip 4 (checksum) byte[] digest = GetHash(hash); byte[] signature = Header(digest, Hash); if (timestamp != null) { byte[] ts = Timestamp(signature); // add timestamp information inside the current pkcs7 SignedData instance // (this is possible because the data isn't yet signed) ProcessTimestamp(ts); } PKCS7.ContentInfo sign = new PKCS7.ContentInfo(signedData); sign.Content.Add(pkcs7.ASN1); authenticode = sign.ASN1; Close(); return(Save(fileName, authenticode.GetBytes())); } catch (Exception e) { Console.WriteLine(e); } return(false); }
private bool CheckSignature(string fileName) { this.filename = fileName; base.Open(this.filename); this.entry = base.GetSecurityEntry(); if (this.entry == null) { this.reason = 1; base.Close(); return(false); } PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo(this.entry); if (contentInfo.ContentType != "1.2.840.113549.1.7.2") { base.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") { base.Close(); return(false); } this.coll = signedData.Certificates; ASN1 content = signedData.ContentInfo.Content; this.signedHash = content[0][1][1]; int length = this.signedHash.Length; HashAlgorithm hashAlgorithm; if (length != 16) { if (length != 20) { this.reason = 5; base.Close(); return(false); } hashAlgorithm = HashAlgorithm.Create("SHA1"); this.hash = base.GetHash(hashAlgorithm); } else { hashAlgorithm = HashAlgorithm.Create("MD5"); this.hash = base.GetHash(hashAlgorithm); } base.Close(); if (!this.signedHash.CompareValue(this.hash)) { this.reason = 2; } byte[] value = content[0].Value; hashAlgorithm.Initialize(); byte[] calculatedMessageDigest = hashAlgorithm.ComputeHash(value); bool flag = this.VerifySignature(signedData, calculatedMessageDigest, hashAlgorithm); return(flag && this.reason == 0); }
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); }
public bool Timestamp(string fileName) { try { AuthenticodeDeformatter authenticodeDeformatter = new AuthenticodeDeformatter(fileName); byte[] signature = authenticodeDeformatter.Signature; if (signature != null) { Open(fileName); PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo(signature); pkcs7 = new PKCS7.SignedData(contentInfo.Content); byte[] bytes = Timestamp(pkcs7.SignerInfo.Signature); ASN1 aSN = new ASN1(Convert.FromBase64String(Encoding.ASCII.GetString(bytes))); ASN1 aSN2 = new ASN1(signature); ASN1 aSN3 = aSN2.Element(1, 160); if (aSN3 == null) { return(false); } ASN1 aSN4 = aSN3.Element(0, 48); if (aSN4 == null) { return(false); } ASN1 aSN5 = aSN4.Element(3, 160); if (aSN5 == null) { aSN5 = new ASN1(160); aSN4.Add(aSN5); } for (int i = 0; i < aSN[1][0][3].Count; i++) { aSN5.Add(aSN[1][0][3][i]); } ASN1 aSN6 = aSN4[aSN4.Count - 1]; ASN1 aSN7 = aSN6[0]; ASN1 aSN8 = aSN7[aSN7.Count - 1]; if (aSN8.Tag != 161) { aSN8 = new ASN1(161); aSN7.Add(aSN8); } aSN8.Add(Attribute("1.2.840.113549.1.9.6", aSN[1][0][4][0])); return(Save(fileName, aSN2.GetBytes())); } } catch (Exception value) { Console.WriteLine(value); } return(false); }
public bool Timestamp(string fileName) { try { AuthenticodeDeformatter authenticodeDeformatter = new AuthenticodeDeformatter(fileName); byte[] signature = authenticodeDeformatter.Signature; if (signature != null) { base.Open(fileName); PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo(signature); this.pkcs7 = new PKCS7.SignedData(contentInfo.Content); byte[] bytes = this.Timestamp(this.pkcs7.SignerInfo.Signature); ASN1 asn = new ASN1(Convert.FromBase64String(Encoding.ASCII.GetString(bytes))); ASN1 asn2 = new ASN1(signature); ASN1 asn3 = asn2.Element(1, 160); if (asn3 == null) { return(false); } ASN1 asn4 = asn3.Element(0, 48); if (asn4 == null) { return(false); } ASN1 asn5 = asn4.Element(3, 160); if (asn5 == null) { asn5 = new ASN1(160); asn4.Add(asn5); } for (int i = 0; i < asn[1][0][3].Count; i++) { asn5.Add(asn[1][0][3][i]); } ASN1 asn6 = asn4[asn4.Count - 1]; ASN1 asn7 = asn6[0]; ASN1 asn8 = asn7[asn7.Count - 1]; if (asn8.Tag != 161) { asn8 = new ASN1(161); asn7.Add(asn8); } asn8.Add(this.Attribute("1.2.840.113549.1.9.6", asn[1][0][4][0])); return(this.Save(fileName, asn2.GetBytes())); } } catch (Exception value) { Console.WriteLine(value); } return(false); }
public SoftwarePublisherCertificate(byte[] data) : this() { if (data == null) throw new ArgumentNullException ("data"); PKCS7.ContentInfo ci = new PKCS7.ContentInfo (data); if (ci.ContentType != PKCS7.Oid.signedData) { throw new ArgumentException ( Locale.GetText ("Unsupported ContentType")); } pkcs7 = new PKCS7.SignedData (ci.Content); }
public SoftwarePublisherCertificate(byte[] data) : this() { if (data == null) { throw new ArgumentNullException("data"); } PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo(data); if (contentInfo.ContentType != "1.2.840.113549.1.7.2") { throw new ArgumentException(Locale.GetText("Unsupported ContentType")); } this.pkcs7 = new PKCS7.SignedData(contentInfo.Content); }
public SoftwarePublisherCertificate(byte[] data) : this() { if (data == null) { throw new ArgumentNullException("data"); } PKCS7.ContentInfo ci = new PKCS7.ContentInfo(data); if (ci.ContentType != PKCS7.Oid.signedData) { throw new ArgumentException("Invalid signed data"); } pkcs7 = new PKCS7.SignedData(ci.Content); }
public void Decode(byte[] encodedMessage) { if (encodedMessage == null) { throw new ArgumentNullException("encodedMessage"); } PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage); if (ci.ContentType != PKCS7.Oid.envelopedData) { throw new Exception(""); } PKCS7.EnvelopedData ed = new PKCS7.EnvelopedData(ci.Content); Oid oid = new Oid(ed.ContentInfo.ContentType); _content = new ContentInfo(oid, new byte [0]); //ed.ContentInfo.Content.Value); foreach (PKCS7.RecipientInfo ri in ed.RecipientInfos) { Oid o = new Oid(ri.Oid); AlgorithmIdentifier ai = new AlgorithmIdentifier(o); SubjectIdentifier si = null; if (ri.SubjectKeyIdentifier != null) { si = new SubjectIdentifier(SubjectIdentifierType.SubjectKeyIdentifier, ri.SubjectKeyIdentifier); } else if ((ri.Issuer != null) && (ri.Serial != null)) { X509IssuerSerial xis = GetIssuerSerial(ri.Issuer, ri.Serial); si = new SubjectIdentifier(SubjectIdentifierType.IssuerAndSerialNumber, (object)xis); } KeyTransRecipientInfo _keyTrans = new KeyTransRecipientInfo(ri.Key, ai, si, ri.Version); _recipients.Add(_keyTrans); } // TODO - Certificates // TODO - UnprotectedAttributes _version = ed.Version; }
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)); }
public void RemoveCertificate (X509Certificate cert, IDictionary attrs) { int certIndex = -1; for (int i = 0; certIndex == -1 && i < _safeBags.Count; i++) { SafeBag sb = (SafeBag)_safeBags [i]; if (sb.BagOID.Equals (certBag)) { ASN1 safeBag = sb.ASN1; ASN1 bagValue = safeBag [1]; PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); X509Certificate c = new X509Certificate (crt.Content [0].Value); if (Compare (cert.RawData, c.RawData)) { if (attrs != null) { if (safeBag.Count == 3) { ASN1 bagAttributes = safeBag [2]; int bagAttributesFound = 0; for (int j = 0; j < bagAttributes.Count; j++) { ASN1 pkcs12Attribute = bagAttributes [j]; ASN1 attrId = pkcs12Attribute [0]; string ao = ASN1Convert.ToOid (attrId); ArrayList dattrValues = (ArrayList)attrs [ao]; if (dattrValues != null) { ASN1 attrValues = pkcs12Attribute [1]; if (dattrValues.Count == attrValues.Count) { int attrValuesFound = 0; for (int k = 0; k < attrValues.Count; k++) { ASN1 attrValue = attrValues [k]; byte[] value = (byte[])dattrValues [k]; if (Compare (value, attrValue.Value)) { attrValuesFound += 1; } } if (attrValuesFound == attrValues.Count) { bagAttributesFound += 1; } } } } if (bagAttributesFound == bagAttributes.Count) { certIndex = i; } } } else { certIndex = i; } } } } if (certIndex != -1) { _safeBags.RemoveAt (certIndex); _certsChanged = true; } }
public ASN1 TimestampRequest(byte[] signature) { PKCS7.ContentInfo ci = new PKCS7.ContentInfo(PKCS7.Oid.data); ci.Content.Add(new ASN1(0x04, signature)); return(PKCS7.AlgorithmIdentifier(timestampCountersignature, ci.ASN1)); }
public byte[] GetBytes() { PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo("1.2.840.113549.1.7.2"); contentInfo.Content.Add(this.pkcs7.ASN1); return(contentInfo.GetBytes()); }
public X509Certificate GetCertificate (IDictionary attrs) { foreach (SafeBag sb in _safeBags) { if (sb.BagOID.Equals (certBag)) { ASN1 safeBag = sb.ASN1; if (safeBag.Count == 3) { ASN1 bagAttributes = safeBag [2]; int bagAttributesFound = 0; for (int i = 0; i < bagAttributes.Count; i++) { ASN1 pkcs12Attribute = bagAttributes [i]; ASN1 attrId = pkcs12Attribute [0]; string ao = ASN1Convert.ToOid (attrId); ArrayList dattrValues = (ArrayList)attrs [ao]; if (dattrValues != null) { ASN1 attrValues = pkcs12Attribute [1]; if (dattrValues.Count == attrValues.Count) { int attrValuesFound = 0; for (int j = 0; j < attrValues.Count; j++) { ASN1 attrValue = attrValues [j]; byte[] value = (byte[])dattrValues [j]; if (Compare (value, attrValue.Value)) { attrValuesFound += 1; } } if (attrValuesFound == attrValues.Count) { bagAttributesFound += 1; } } } } if (bagAttributesFound == bagAttributes.Count) { ASN1 bagValue = safeBag [1]; PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); return new X509Certificate (crt.Content [0].Value); } } } } return null; }
private bool CheckSignature(string fileName) { this.filename = fileName; base.Open(this.filename); this.entry = base.GetSecurityEntry(); if (this.entry == null) { this.reason = 1; base.Close(); return(false); } PKCS7.ContentInfo info = new PKCS7.ContentInfo(this.entry); if (info.ContentType != "1.2.840.113549.1.7.2") { base.Close(); return(false); } PKCS7.SignedData sd = new PKCS7.SignedData(info.Content); if (sd.ContentInfo.ContentType != "1.3.6.1.4.1.311.2.1.4") { base.Close(); return(false); } this.coll = sd.Certificates; ASN1 content = sd.ContentInfo.Content; this.signedHash = content[0][1][1]; HashAlgorithm hash = null; switch (this.signedHash.Length) { case 0x10: hash = HashAlgorithm.Create("MD5"); this.hash = base.GetHash(hash); break; case 20: hash = HashAlgorithm.Create("SHA1"); this.hash = base.GetHash(hash); break; default: this.reason = 5; base.Close(); return(false); } base.Close(); if (!this.signedHash.CompareValue(this.hash)) { this.reason = 2; } byte[] buffer = content[0].Value; hash.Initialize(); byte[] calculatedMessageDigest = hash.ComputeHash(buffer); return(this.VerifySignature(sd, calculatedMessageDigest, hash) && (this.reason == 0)); }
public void AddCertificate (X509Certificate cert, IDictionary attributes) { bool found = false; for (int i = 0; !found && i < _safeBags.Count; i++) { SafeBag sb = (SafeBag)_safeBags [i]; if (sb.BagOID.Equals (certBag)) { ASN1 safeBag = sb.ASN1; ASN1 bagValue = safeBag [1]; PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); X509Certificate c = new X509Certificate (crt.Content [0].Value); if (Compare (cert.RawData, c.RawData)) { found = true; } } } if (!found) { _safeBags.Add (new SafeBag (certBag, CertificateSafeBag (cert, attributes))); _certsChanged = true; } }
public void Decode(byte[] encodedMessage) { PKCS7.ContentInfo ci = new PKCS7.ContentInfo(encodedMessage); if (ci.ContentType != PKCS7.Oid.signedData) { throw new Exception(""); } PKCS7.SignedData sd = new PKCS7.SignedData(ci.Content); SubjectIdentifierType type = SubjectIdentifierType.Unknown; object o = null; X509Certificate2 x509 = null; if (sd.SignerInfo.Certificate != null) { x509 = new X509Certificate2(sd.SignerInfo.Certificate.RawData); } else if ((sd.SignerInfo.IssuerName != null) && (sd.SignerInfo.SerialNumber != null)) { byte[] serial = sd.SignerInfo.SerialNumber; Array.Reverse(serial); // ??? type = SubjectIdentifierType.IssuerAndSerialNumber; X509IssuerSerial xis = new X509IssuerSerial(); xis.IssuerName = sd.SignerInfo.IssuerName; xis.SerialNumber = ToString(serial, true); o = xis; // TODO: move to a FindCertificate (issuer, serial, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (x.IssuerName == sd.SignerInfo.IssuerName) { if (ToString(x.SerialNumber, true) == xis.SerialNumber) { x509 = new X509Certificate2(x.RawData); break; } } } } else if (sd.SignerInfo.SubjectKeyIdentifier != null) { string ski = ToString(sd.SignerInfo.SubjectKeyIdentifier, false); type = SubjectIdentifierType.SubjectKeyIdentifier; o = (object)ski; // TODO: move to a FindCertificate (ski, collection) foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { if (ToString(GetKeyIdentifier(x), false) == ski) { x509 = new X509Certificate2(x.RawData); break; } } } SignerInfo si = new SignerInfo(sd.SignerInfo.HashName, x509, type, o, sd.SignerInfo.Version); // si.AuthenticatedAttributes // si.UnauthenticatedAttributes _info.Add(si); ASN1 content = sd.ContentInfo.Content; Oid oid = new Oid(sd.ContentInfo.ContentType); if (!_detached || _content == null) { if (content[0] == null) { throw new ArgumentException("ContentInfo has no content. Detached signature ?"); } _content = new ContentInfo(oid, content[0].Value); } foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) { _certs.Add(new X509Certificate2(x.RawData)); } _version = sd.Version; }
public ASN1 TimestampRequest(byte[] signature) { PKCS7.ContentInfo contentInfo = new PKCS7.ContentInfo("1.2.840.113549.1.7.1"); contentInfo.Content.Add(new ASN1(4, signature)); return(PKCS7.AlgorithmIdentifier("1.3.6.1.4.1.311.3.2.1", contentInfo.ASN1)); }
public IDictionary GetAttributes (X509Certificate cert) { IDictionary result = new Hashtable (); foreach (SafeBag sb in _safeBags) { if (sb.BagOID.Equals (certBag)) { ASN1 safeBag = sb.ASN1; ASN1 bagValue = safeBag [1]; PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value); X509Certificate xc = new X509Certificate (crt.Content [0].Value); if (Compare (cert.RawData, xc.RawData)) { if (safeBag.Count == 3) { ASN1 bagAttributes = safeBag [2]; for (int i = 0; i < bagAttributes.Count; i++) { ASN1 pkcs12Attribute = bagAttributes [i]; ASN1 attrId = pkcs12Attribute [0]; string aOid = ASN1Convert.ToOid (attrId); ArrayList aValues = new ArrayList (); ASN1 attrValues = pkcs12Attribute [1]; for (int j = 0; j < attrValues.Count; j++) { ASN1 attrValue = attrValues [j]; aValues.Add (attrValue.Value); } result.Add (aOid, aValues); } } } } } return result; }
private void Decode (byte[] data) { ASN1 pfx = new ASN1 (data); if (pfx.Tag != 0x30) throw new ArgumentException ("invalid data"); ASN1 version = pfx [0]; if (version.Tag != 0x02) throw new ArgumentException ("invalid PFX version"); //_version = version.Value [0]; PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (pfx [1]); if (authSafe.ContentType != PKCS7.Oid.data) throw new ArgumentException ("invalid authenticated safe"); // now that we know it's a PKCS#12 file, check the (optional) MAC // before decoding anything else in the file if (pfx.Count > 2) { ASN1 macData = pfx [2]; if (macData.Tag != 0x30) throw new ArgumentException ("invalid MAC"); ASN1 mac = macData [0]; if (mac.Tag != 0x30) throw new ArgumentException ("invalid MAC"); ASN1 macAlgorithm = mac [0]; string macOid = ASN1Convert.ToOid (macAlgorithm [0]); if (macOid != "1.3.14.3.2.26") throw new ArgumentException ("unsupported HMAC"); byte[] macValue = mac [1].Value; ASN1 macSalt = macData [1]; if (macSalt.Tag != 0x04) throw new ArgumentException ("missing MAC salt"); _iterations = 1; // default value if (macData.Count > 2) { ASN1 iters = macData [2]; if (iters.Tag != 0x02) throw new ArgumentException ("invalid MAC iteration"); _iterations = ASN1Convert.ToInt32 (iters); } byte[] authSafeData = authSafe.Content [0].Value; byte[] calculatedMac = MAC (_password, macSalt.Value, _iterations, authSafeData); if (!Compare (macValue, calculatedMac)) { byte[] nullPassword = {0, 0}; calculatedMac = MAC(nullPassword, macSalt.Value, _iterations, authSafeData); if (!Compare (macValue, calculatedMac)) throw new CryptographicException ("Invalid MAC - file may have been tampe red!"); _password = nullPassword; } } // we now returns to our original presentation - PFX ASN1 authenticatedSafe = new ASN1 (authSafe.Content [0].Value); for (int i=0; i < authenticatedSafe.Count; i++) { PKCS7.ContentInfo ci = new PKCS7.ContentInfo (authenticatedSafe [i]); switch (ci.ContentType) { case PKCS7.Oid.data: // unencrypted (by PKCS#12) ASN1 safeContents = new ASN1 (ci.Content [0].Value); for (int j=0; j < safeContents.Count; j++) { ASN1 safeBag = safeContents [j]; ReadSafeBag (safeBag); } break; case PKCS7.Oid.encryptedData: // password encrypted PKCS7.EncryptedData ed = new PKCS7.EncryptedData (ci.Content [0]); ASN1 decrypted = new ASN1 (Decrypt (ed)); for (int j=0; j < decrypted.Count; j++) { ASN1 safeBag = decrypted [j]; ReadSafeBag (safeBag); } break; case PKCS7.Oid.envelopedData: // public key encrypted throw new NotImplementedException ("public key encrypted"); default: throw new ArgumentException ("unknown authenticatedSafe"); } } }
private void ReadSafeBag (ASN1 safeBag) { if (safeBag.Tag != 0x30) throw new ArgumentException ("invalid safeBag"); ASN1 bagId = safeBag [0]; if (bagId.Tag != 0x06) throw new ArgumentException ("invalid safeBag id"); ASN1 bagValue = safeBag [1]; string oid = ASN1Convert.ToOid (bagId); switch (oid) { case keyBag: // NEED UNIT TEST AddPrivateKey (new PKCS8.PrivateKeyInfo (bagValue.Value)); break; case pkcs8ShroudedKeyBag: PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value); byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData); AddPrivateKey (new PKCS8.PrivateKeyInfo (decrypted)); Array.Clear (decrypted, 0, decrypted.Length); break; case certBag: PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); if (cert.ContentType != x509Certificate) throw new NotSupportedException ("unsupport certificate type"); X509Certificate x509 = new X509Certificate (cert.Content [0].Value); _certs.Add (x509); break; case crlBag: // TODO break; case secretBag: byte[] secret = bagValue.Value; _secretBags.Add(secret); break; case safeContentsBag: // TODO - ? recurse ? break; default: throw new ArgumentException ("unknown safeBag oid"); } if (safeBag.Count > 2) { ASN1 bagAttributes = safeBag [2]; if (bagAttributes.Tag != 0x31) throw new ArgumentException ("invalid safeBag attributes id"); for (int i = 0; i < bagAttributes.Count; i++) { ASN1 pkcs12Attribute = bagAttributes[i]; if (pkcs12Attribute.Tag != 0x30) throw new ArgumentException ("invalid PKCS12 attributes id"); ASN1 attrId = pkcs12Attribute [0]; if (attrId.Tag != 0x06) throw new ArgumentException ("invalid attribute id"); string attrOid = ASN1Convert.ToOid (attrId); ASN1 attrValues = pkcs12Attribute[1]; for (int j = 0; j < attrValues.Count; j++) { ASN1 attrValue = attrValues[j]; switch (attrOid) { case PKCS9.friendlyName: if (attrValue.Tag != 0x1e) throw new ArgumentException ("invalid attribute value id"); break; case PKCS9.localKeyId: if (attrValue.Tag != 0x04) throw new ArgumentException ("invalid attribute value id"); break; default: // Unknown OID -- don't check Tag break; } } } } _safeBags.Add (new SafeBag(oid, safeBag)); }
/* * SafeContents ::= SEQUENCE OF SafeBag * * SafeBag ::= SEQUENCE { * bagId BAG-TYPE.&id ({PKCS12BagSet}), * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), * bagAttributes SET OF PKCS12Attribute OPTIONAL * } */ public byte[] GetBytes () { // TODO (incomplete) ASN1 safeBagSequence = new ASN1 (0x30); // Sync Safe Bag list since X509CertificateCollection may be updated ArrayList scs = new ArrayList (); foreach (SafeBag sb in _safeBags) { if (sb.BagOID.Equals (certBag)) { ASN1 safeBag = sb.ASN1; ASN1 bagValue = safeBag [1]; PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value); scs.Add (new X509Certificate (cert.Content [0].Value)); } } ArrayList addcerts = new ArrayList (); ArrayList removecerts = new ArrayList (); foreach (X509Certificate c in Certificates) { bool found = false; foreach (X509Certificate lc in scs) { if (Compare (c.RawData, lc.RawData)) { found = true; } } if (!found) { addcerts.Add (c); } } foreach (X509Certificate c in scs) { bool found = false; foreach (X509Certificate lc in Certificates) { if (Compare (c.RawData, lc.RawData)) { found = true; } } if (!found) { removecerts.Add (c); } } foreach (X509Certificate c in removecerts) { RemoveCertificate (c); } foreach (X509Certificate c in addcerts) { AddCertificate (c); } // Sync done if (_safeBags.Count > 0) { ASN1 certsSafeBag = new ASN1 (0x30); foreach (SafeBag sb in _safeBags) { if (sb.BagOID.Equals (certBag)) { certsSafeBag.Add (sb.ASN1); } } if (certsSafeBag.Count > 0) { PKCS7.ContentInfo contentInfo = EncryptedContentInfo (certsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC); safeBagSequence.Add (contentInfo.ASN1); } } if (_safeBags.Count > 0) { ASN1 safeContents = new ASN1 (0x30); foreach (SafeBag sb in _safeBags) { if (sb.BagOID.Equals (keyBag) || sb.BagOID.Equals (pkcs8ShroudedKeyBag)) { safeContents.Add (sb.ASN1); } } if (safeContents.Count > 0) { ASN1 content = new ASN1 (0xA0); content.Add (new ASN1 (0x04, safeContents.GetBytes ())); PKCS7.ContentInfo keyBag = new PKCS7.ContentInfo (PKCS7.Oid.data); keyBag.Content = content; safeBagSequence.Add (keyBag.ASN1); } } // Doing SecretBags separately in case we want to change their encryption independently. if (_safeBags.Count > 0) { ASN1 secretsSafeBag = new ASN1 (0x30); foreach (SafeBag sb in _safeBags) { if (sb.BagOID.Equals (secretBag)) { secretsSafeBag.Add (sb.ASN1); } } if (secretsSafeBag.Count > 0) { PKCS7.ContentInfo contentInfo = EncryptedContentInfo (secretsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC); safeBagSequence.Add (contentInfo.ASN1); } } ASN1 encapsulates = new ASN1 (0x04, safeBagSequence.GetBytes ()); ASN1 ci = new ASN1 (0xA0); ci.Add (encapsulates); PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (PKCS7.Oid.data); authSafe.Content = ci; ASN1 macData = new ASN1 (0x30); if (_password != null) { // only for password based encryption byte[] salt = new byte [20]; RNG.GetBytes (salt); byte[] macValue = MAC (_password, salt, _iterations, authSafe.Content [0].Value); ASN1 oidSeq = new ASN1 (0x30); oidSeq.Add (ASN1Convert.FromOid ("1.3.14.3.2.26")); // SHA1 oidSeq.Add (new ASN1 (0x05)); ASN1 mac = new ASN1 (0x30); mac.Add (oidSeq); mac.Add (new ASN1 (0x04, macValue)); macData.Add (mac); macData.Add (new ASN1 (0x04, salt)); macData.Add (ASN1Convert.FromInt32 (_iterations)); } ASN1 version = new ASN1 (0x02, new byte [1] { 0x03 }); ASN1 pfx = new ASN1 (0x30); pfx.Add (version); pfx.Add (authSafe.ASN1); if (macData.Count > 0) { // only for password based encryption pfx.Add (macData); } return pfx.GetBytes (); }
// Creates an encrypted PKCS#7 ContentInfo with safeBags as its SafeContents. Used in GetBytes(), above. private PKCS7.ContentInfo EncryptedContentInfo(ASN1 safeBags, string algorithmOid) { byte[] salt = new byte [8]; RNG.GetBytes (salt); ASN1 seqParams = new ASN1 (0x30); seqParams.Add (new ASN1 (0x04, salt)); seqParams.Add (ASN1Convert.FromInt32 (_iterations)); ASN1 seqPbe = new ASN1 (0x30); seqPbe.Add (ASN1Convert.FromOid (algorithmOid)); seqPbe.Add (seqParams); byte[] encrypted = Encrypt (algorithmOid, salt, _iterations, safeBags.GetBytes ()); ASN1 encryptedContent = new ASN1 (0x80, encrypted); ASN1 seq = new ASN1 (0x30); seq.Add (ASN1Convert.FromOid (PKCS7.Oid.data)); seq.Add (seqPbe); seq.Add (encryptedContent); ASN1 version = new ASN1 (0x02, new byte [1] { 0x00 }); ASN1 encData = new ASN1 (0x30); encData.Add (version); encData.Add (seq); ASN1 finalContent = new ASN1 (0xA0); finalContent.Add (encData); PKCS7.ContentInfo bag = new PKCS7.ContentInfo (PKCS7.Oid.encryptedData); bag.Content = finalContent; return bag; }
public byte[] GetBytes() { PKCS7.ContentInfo ci = new PKCS7.ContentInfo(PKCS7.Oid.signedData); ci.Content.Add(pkcs7.ASN1); return(ci.GetBytes()); }
private ASN1 CertificateSafeBag (X509Certificate x509, IDictionary attributes) { ASN1 encapsulatedCertificate = new ASN1 (0x04, x509.RawData); PKCS7.ContentInfo ci = new PKCS7.ContentInfo (); ci.ContentType = x509Certificate; ci.Content.Add (encapsulatedCertificate); ASN1 bagValue = new ASN1 (0xA0); bagValue.Add (ci.ASN1); ASN1 safeBag = new ASN1 (0x30); safeBag.Add (ASN1Convert.FromOid (certBag)); safeBag.Add (bagValue); if (attributes != null) { ASN1 bagAttributes = new ASN1 (0x31); IDictionaryEnumerator de = attributes.GetEnumerator (); while (de.MoveNext ()) { string oid = (string)de.Key; switch (oid) { case PKCS9.friendlyName: ArrayList names = (ArrayList)de.Value; if (names.Count > 0) { ASN1 pkcs12Attribute = new ASN1 (0x30); pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName)); ASN1 attrValues = new ASN1 (0x31); foreach (byte[] name in names) { ASN1 attrValue = new ASN1 (0x1e); attrValue.Value = name; attrValues.Add (attrValue); } pkcs12Attribute.Add (attrValues); bagAttributes.Add (pkcs12Attribute); } break; case PKCS9.localKeyId: ArrayList keys = (ArrayList)de.Value; if (keys.Count > 0) { ASN1 pkcs12Attribute = new ASN1 (0x30); pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId)); ASN1 attrValues = new ASN1 (0x31); foreach (byte[] key in keys) { ASN1 attrValue = new ASN1 (0x04); attrValue.Value = key; attrValues.Add (attrValue); } pkcs12Attribute.Add (attrValues); bagAttributes.Add (pkcs12Attribute); } break; default: break; } } if (bagAttributes.Count > 0) { safeBag.Add (bagAttributes); } } return safeBag; }