private static void CheckAsn1(byte[] result) { Assert.IsNotNull(result); DigestInfo digestInfo = DigestInfo.GetInstance(Asn1Object.FromByteArray(result)); Assert.IsNotNull(digestInfo.AlgorithmID.Algorithm); Assert.IsNotNull(digestInfo.GetDigest()); }
private bool VerifyDigest(byte[] digest, AsymmetricKeyParameter key, byte[] signature) { string encryptionAlgName = SignerInformation.Helper.GetEncryptionAlgName(this.EncryptionAlgOid); bool result; try { if (encryptionAlgName.Equals("RSA")) { IBufferedCipher bufferedCipher = CmsEnvelopedHelper.Instance.CreateAsymmetricCipher("RSA/ECB/PKCS1Padding"); bufferedCipher.Init(false, key); byte[] encoding = bufferedCipher.DoFinal(signature); DigestInfo digestInfo = this.DerDecode(encoding); if (!digestInfo.AlgorithmID.ObjectID.Equals(this.digestAlgorithm.ObjectID)) { result = false; } else if (!this.IsNull(digestInfo.AlgorithmID.Parameters)) { result = false; } else { byte[] digest2 = digestInfo.GetDigest(); result = Arrays.ConstantTimeAreEqual(digest, digest2); } } else { if (!encryptionAlgName.Equals("DSA")) { throw new CmsException("algorithm: " + encryptionAlgName + " not supported in base signatures."); } ISigner signer = SignerUtilities.GetSigner("NONEwithDSA"); signer.Init(false, key); signer.BlockUpdate(digest, 0, digest.Length); result = signer.VerifySignature(signature); } } catch (SecurityUtilityException ex) { throw ex; } catch (GeneralSecurityException ex2) { throw new CmsException("Exception processing signature: " + ex2, ex2); } catch (IOException ex3) { throw new CmsException("Exception decoding signature: " + ex3, ex3); } return(result); }
private bool VerifyDigest(byte[] digest, AsymmetricKeyParameter key, byte[] signature) { //IL_010a: Expected O, but got Unknown string encryptionAlgName = Helper.GetEncryptionAlgName(EncryptionAlgOid); try { if (encryptionAlgName.Equals("RSA")) { IBufferedCipher bufferedCipher = CmsEnvelopedHelper.Instance.CreateAsymmetricCipher("RSA/ECB/PKCS1Padding"); bufferedCipher.Init(forEncryption: false, key); byte[] encoding = bufferedCipher.DoFinal(signature); DigestInfo digestInfo = DerDecode(encoding); if (!digestInfo.AlgorithmID.Algorithm.Equals(digestAlgorithm.Algorithm)) { return(false); } if (!IsNull(digestInfo.AlgorithmID.Parameters)) { return(false); } byte[] digest2 = digestInfo.GetDigest(); return(Arrays.ConstantTimeAreEqual(digest, digest2)); } if (encryptionAlgName.Equals("DSA")) { ISigner signer = SignerUtilities.GetSigner("NONEwithDSA"); signer.Init(forSigning: false, key); signer.BlockUpdate(digest, 0, digest.Length); return(signer.VerifySignature(signature)); } throw new CmsException("algorithm: " + encryptionAlgName + " not supported in base signatures."); } catch (SecurityUtilityException ex) { throw ex; } catch (GeneralSecurityException ex2) { throw new CmsException(string.Concat((object)"Exception processing signature: ", (object)ex2), ex2); } catch (IOException val) { IOException val2 = val; throw new CmsException(string.Concat((object)"Exception decoding signature: ", (object)val2), (global::System.Exception)(object) val2); } }
private bool VerifyDigest( byte[] digest, AsymmetricKeyParameter key, byte[] signature) { string algorithm = Helper.GetEncryptionAlgName(this.EncryptionAlgOid); try { if (algorithm.Equals("RSA")) { IBufferedCipher c = CmsEnvelopedHelper.Instance.CreateAsymmetricCipher("RSA/ECB/PKCS1Padding"); c.Init(false, key); byte[] decrypt = c.DoFinal(signature); DigestInfo digInfo = DerDecode(decrypt); if (!digInfo.AlgorithmID.ObjectID.Equals(digestAlgorithm.ObjectID)) { return(false); } if (!IsNull(digInfo.AlgorithmID.Parameters)) { return(false); } byte[] sigHash = digInfo.GetDigest(); return(Arrays.ConstantTimeAreEqual(digest, sigHash)); } else if (algorithm.Equals("DSA")) { ISigner sig = SignerUtilities.GetSigner("NONEwithDSA"); sig.Init(false, key); sig.BlockUpdate(digest, 0, digest.Length); return(sig.VerifySignature(signature)); } else { throw new CmsException("algorithm: " + algorithm + " not supported in base signatures."); } } catch (SecurityUtilityException e) { throw e; } catch (GeneralSecurityException e) { throw new CmsException("Exception processing signature: " + e, e); } catch (IOException e) { throw new CmsException("Exception decoding signature: " + e, e); } }
public void Load( Stream input, char[] password) { if (input == null) { throw new ArgumentNullException("input"); } if (password == null) { throw new ArgumentNullException("password"); } Asn1Sequence obj = (Asn1Sequence)Asn1Object.FromStream(input); Pfx bag = new Pfx(obj); ContentInfo info = bag.AuthSafe; bool unmarkedKey = false; bool wrongPkcs12Zero = false; if (bag.MacData != null) // check the mac code { MacData mData = bag.MacData; DigestInfo dInfo = mData.Mac; AlgorithmIdentifier algId = dInfo.AlgorithmID; byte[] salt = mData.GetSalt(); int itCount = mData.IterationCount.IntValue; byte[] data = ((Asn1OctetString)info.Content).GetOctets(); byte[] mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, false, data); byte[] dig = dInfo.GetDigest(); if (!Arrays.ConstantTimeAreEqual(mac, dig)) { if (password.Length > 0) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } // Try with incorrect zero length password mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, true, data); if (!Arrays.ConstantTimeAreEqual(mac, dig)) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } wrongPkcs12Zero = true; } } keys.Clear(); localIds.Clear(); IList chain = Platform.CreateArrayList(); if (info.ContentType.Equals(PkcsObjectIdentifiers.Data)) { byte[] octs = ((Asn1OctetString)info.Content).GetOctets(); AuthenticatedSafe authSafe = new AuthenticatedSafe( (Asn1Sequence)Asn1OctetString.FromByteArray(octs)); ContentInfo[] cis = authSafe.GetContentInfo(); foreach (ContentInfo ci in cis) { DerObjectIdentifier oid = ci.ContentType; if (oid.Equals(PkcsObjectIdentifiers.Data)) { byte[] octets = ((Asn1OctetString)ci.Content).GetOctets(); Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(octets); foreach (Asn1Sequence subSeq in seq) { SafeBag b = new SafeBag(subSeq); if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue); PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo( password, wrongPkcs12Zero, eIn); IAsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo); // // set the attributes on the key // IDictionary attributes = Platform.CreateHashtable(); AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes); string alias = null; Asn1OctetString localId = null; if (b.BagAttributes != null) { foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; Asn1Encodable attr = null; if (attrSet.Count > 0) { // TODO We should be adding all attributes in the set attr = attrSet[0]; // TODO We might want to "merge" attribute sets with // the same OID - currently, differing values give an error if (attributes.Contains(aOid.Id)) { // OK, but the value has to be the same if (!attributes[aOid.Id].Equals(attr)) { throw new IOException("attempt to add existing attribute with different value"); } } else { attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); // TODO Do these in a separate loop, just collect aliases here keys[alias] = pkcs12Key; } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } } } if (localId != null) { string name = Hex.ToHexString(localId.GetOctets()); if (alias == null) { keys[name] = pkcs12Key; } else { // TODO There may have been more than one alias localIds[alias] = name; } } else { unmarkedKey = true; keys["unmarked"] = pkcs12Key; } } else if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag)) { chain.Add(b); } else { #if !NETFX_CORE Console.WriteLine("extra " + b.BagID); Console.WriteLine("extra " + Asn1Dump.DumpAsString(b)); #endif } } } else if (oid.Equals(PkcsObjectIdentifiers.EncryptedData)) { EncryptedData d = EncryptedData.GetInstance(ci.Content); byte[] octets = CryptPbeData(false, d.EncryptionAlgorithm, password, wrongPkcs12Zero, d.Content.GetOctets()); Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(octets); foreach (Asn1Sequence subSeq in seq) { SafeBag b = new SafeBag(subSeq); if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag)) { chain.Add(b); } else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue); PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo( password, wrongPkcs12Zero, eIn); IAsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo); // // set the attributes on the key // IDictionary attributes = Platform.CreateHashtable(); AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes); string alias = null; Asn1OctetString localId = null; foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; Asn1Encodable attr = null; if (attrSet.Count > 0) { // TODO We should be adding all attributes in the set attr = attrSet[0]; // TODO We might want to "merge" attribute sets with // the same OID - currently, differing values give an error if (attributes.Contains(aOid.Id)) { // OK, but the value has to be the same if (!attributes[aOid.Id].Equals(attr)) { throw new IOException("attempt to add existing attribute with different value"); } } else { attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); // TODO Do these in a separate loop, just collect aliases here keys[alias] = pkcs12Key; } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } } // TODO Should we be checking localIds != null here // as for PkcsObjectIdentifiers.Data version above? string name = Hex.ToHexString(localId.GetOctets()); if (alias == null) { keys[name] = pkcs12Key; } else { // TODO There may have been more than one alias localIds[alias] = name; } } else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag)) { PrivateKeyInfo privKeyInfo = PrivateKeyInfo.GetInstance(b.BagValue); IAsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyInfo); // // set the attributes on the key // string alias = null; Asn1OctetString localId = null; IDictionary attributes = Platform.CreateHashtable(); AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes); foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; Asn1Encodable attr = null; if (attrSet.Count > 0) { // TODO We should be adding all attributes in the set attr = attrSet[0]; // TODO We might want to "merge" attribute sets with // the same OID - currently, differing values give an error if (attributes.Contains(aOid.Id)) { // OK, but the value has to be the same if (!attributes[aOid.Id].Equals(attr)) { throw new IOException("attempt to add existing attribute with different value"); } } else { attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); // TODO Do these in a separate loop, just collect aliases here keys[alias] = pkcs12Key; } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } } // TODO Should we be checking localIds != null here // as for PkcsObjectIdentifiers.Data version above? string name = Hex.ToHexString(localId.GetOctets()); if (alias == null) { keys[name] = pkcs12Key; } else { // TODO There may have been more than one alias localIds[alias] = name; } } else { #if !NETFX_CORE Console.WriteLine("extra " + b.BagID); Console.WriteLine("extra " + Asn1Dump.DumpAsString(b)); #endif } } } else { #if !NETFX_CORE Console.WriteLine("extra " + oid); Console.WriteLine("extra " + Asn1Dump.DumpAsString(ci.Content)); #endif } } } certs.Clear(); chainCerts.Clear(); keyCerts.Clear(); foreach (SafeBag b in chain) { CertBag cb = new CertBag((Asn1Sequence)b.BagValue); byte[] octets = ((Asn1OctetString)cb.CertValue).GetOctets(); X509Certificate cert = new X509CertificateParser().ReadCertificate(octets); // // set the attributes // IDictionary attributes = Platform.CreateHashtable(); Asn1OctetString localId = null; string alias = null; if (b.BagAttributes != null) { foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; if (attrSet.Count > 0) { // TODO We should be adding all attributes in the set Asn1Encodable attr = attrSet[0]; // TODO We might want to "merge" attribute sets with // the same OID - currently, differing values give an error if (attributes.Contains(aOid.Id)) { // OK, but the value has to be the same if (!attributes[aOid.Id].Equals(attr)) { throw new IOException("attempt to add existing attribute with different value"); } } else { attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } } } CertId certId = new CertId(cert.GetPublicKey()); X509CertificateEntry pkcs12Cert = new X509CertificateEntry(cert, attributes); chainCerts[certId] = pkcs12Cert; if (unmarkedKey) { if (keyCerts.Count == 0) { string name = Hex.ToHexString(certId.Id); keyCerts[name] = pkcs12Cert; object temp = keys["unmarked"]; keys.Remove("unmarked"); keys[name] = temp; } } else { if (localId != null) { string name = Hex.ToHexString(localId.GetOctets()); keyCerts[name] = pkcs12Cert; } if (alias != null) { // TODO There may have been more than one alias certs[alias] = pkcs12Cert; } } } }
public void Load( Stream input, char[] password) { if (input == null) { throw new ArgumentNullException("input"); } Asn1Sequence obj = (Asn1Sequence)Asn1Object.FromStream(input); Pfx bag = new Pfx(obj); ContentInfo info = bag.AuthSafe; bool wrongPkcs12Zero = false; if (password != null && bag.MacData != null) // check the mac code { MacData mData = bag.MacData; DigestInfo dInfo = mData.Mac; AlgorithmIdentifier algId = dInfo.AlgorithmID; byte[] salt = mData.GetSalt(); int itCount = mData.IterationCount.IntValue; byte[] data = ((Asn1OctetString)info.Content).GetOctets(); byte[] mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, false, data); byte[] dig = dInfo.GetDigest(); if (!Arrays.ConstantTimeAreEqual(mac, dig)) { if (password.Length > 0) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } // Try with incorrect zero length password mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, true, data); if (!Arrays.ConstantTimeAreEqual(mac, dig)) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } wrongPkcs12Zero = true; } } keys.Clear(); localIds.Clear(); unmarkedKeyEntry = null; IList certBags = Platform.CreateArrayList(); if (info.ContentType.Equals(PkcsObjectIdentifiers.Data)) { byte[] octs = ((Asn1OctetString)info.Content).GetOctets(); AuthenticatedSafe authSafe = new AuthenticatedSafe( (Asn1Sequence)Asn1OctetString.FromByteArray(octs)); ContentInfo[] cis = authSafe.GetContentInfo(); foreach (ContentInfo ci in cis) { DerObjectIdentifier oid = ci.ContentType; byte[] octets = null; if (oid.Equals(PkcsObjectIdentifiers.Data)) { octets = ((Asn1OctetString)ci.Content).GetOctets(); } else if (oid.Equals(PkcsObjectIdentifiers.EncryptedData)) { if (password != null) { EncryptedData d = EncryptedData.GetInstance(ci.Content); octets = CryptPbeData(false, d.EncryptionAlgorithm, password, wrongPkcs12Zero, d.Content.GetOctets()); } } else { // TODO Other data types } if (octets != null) { Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(octets); foreach (Asn1Sequence subSeq in seq) { SafeBag b = new SafeBag(subSeq); if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag)) { certBags.Add(b); } else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(b.BagValue), b.BagAttributes, password, wrongPkcs12Zero); } else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag)) { LoadKeyBag(PrivateKeyInfo.GetInstance(b.BagValue), b.BagAttributes); } else { // TODO Other bag types } } } } } certs.Clear(); chainCerts.Clear(); keyCerts.Clear(); foreach (SafeBag b in certBags) { CertBag certBag = new CertBag((Asn1Sequence)b.BagValue); byte[] octets = ((Asn1OctetString)certBag.CertValue).GetOctets(); X509Certificate cert = new X509CertificateParser().ReadCertificate(octets); // // set the attributes // IDictionary attributes = Platform.CreateHashtable(); Asn1OctetString localId = null; string alias = null; if (b.BagAttributes != null) { foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = DerObjectIdentifier.GetInstance(sq[0]); Asn1Set attrSet = Asn1Set.GetInstance(sq[1]); if (attrSet.Count > 0) { // TODO We should be adding all attributes in the set Asn1Encodable attr = attrSet[0]; // TODO We might want to "merge" attribute sets with // the same OID - currently, differing values give an error if (attributes.Contains(aOid.Id)) { // OK, but the value has to be the same if (!attributes[aOid.Id].Equals(attr)) { throw new IOException("attempt to add existing attribute with different value"); } } else { attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } } } CertId certId = new CertId(cert.GetPublicKey()); X509CertificateEntry certEntry = new X509CertificateEntry(cert, attributes); chainCerts[certId] = certEntry; if (unmarkedKeyEntry != null) { if (keyCerts.Count == 0) { string name = Hex.ToHexString(certId.Id); keyCerts[name] = certEntry; keys[name] = unmarkedKeyEntry; } } else { if (localId != null) { string name = Hex.ToHexString(localId.GetOctets()); keyCerts[name] = certEntry; } if (alias != null) { // TODO There may have been more than one alias certs[alias] = certEntry; } } } }
public override void PerformTest() { Pfx bag = Pfx.GetInstance(pkcs12); ContentInfo info = bag.AuthSafe; MacData mData = bag.MacData; DigestInfo dInfo = mData.Mac; AlgorithmIdentifier algId = dInfo.AlgorithmID; byte[] salt = mData.GetSalt(); int itCount = mData.IterationCount.IntValue; Asn1OctetString content = Asn1OctetString.GetInstance(info.Content); AuthenticatedSafe authSafe = AuthenticatedSafe.GetInstance(content.GetOctets()); ContentInfo[] c = authSafe.GetContentInfo(); // // private key section // if (!c[0].ContentType.Equals(PkcsObjectIdentifiers.Data)) { Fail("Failed comparison data test"); } Asn1OctetString authSafeContent = Asn1OctetString.GetInstance(c[0].Content); Asn1Sequence seq = Asn1Sequence.GetInstance(authSafeContent.GetOctets()); SafeBag b = SafeBag.GetInstance(seq[0]); if (!b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { Fail("Failed comparison shroudedKeyBag test"); } EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.GetInstance(b.BagValue); encInfo = new EncryptedPrivateKeyInfo(encInfo.EncryptionAlgorithm, encInfo.GetEncryptedData()); b = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, encInfo.ToAsn1Object(), b.BagAttributes); byte[] contentOctets = new DerSequence(b).GetEncoded(); c[0] = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(contentOctets)); // // certificates // if (!c[1].ContentType.Equals(PkcsObjectIdentifiers.EncryptedData)) { Fail("Failed comparison encryptedData test"); } EncryptedData eData = EncryptedData.GetInstance(c[1].Content); c[1] = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, eData); // // create an octet stream to represent the BER encoding of authSafe // authSafe = new AuthenticatedSafe(c); contentOctets = authSafe.GetEncoded(); info = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(contentOctets)); mData = new MacData(new DigestInfo(algId, dInfo.GetDigest()), salt, itCount); bag = new Pfx(info, mData); // // comparison test // byte[] pfxEncoding = bag.GetEncoded(); if (!Arrays.AreEqual(pfxEncoding, pkcs12)) { Fail("Failed comparison test"); } }
public Pkcs12Store( Stream input, char[] password) { if (input == null) { throw new ArgumentNullException("input"); } if (password == null) { throw new ArgumentNullException("password"); } Asn1InputStream bIn = new Asn1InputStream(input); Asn1Sequence obj = (Asn1Sequence)bIn.ReadObject(); Pfx bag = new Pfx(obj); ContentInfo info = bag.AuthSafe; ArrayList chain = new ArrayList(); bool unmarkedKey = false; bool wrongPkcs12Zero = false; if (bag.MacData != null) // check the mac code { MacData mData = bag.MacData; DigestInfo dInfo = mData.Mac; AlgorithmIdentifier algId = dInfo.AlgorithmID; byte[] salt = mData.GetSalt(); int itCount = mData.IterationCount.IntValue; byte[] data = ((Asn1OctetString)info.Content).GetOctets(); Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters( algId.ObjectID, salt, itCount); ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters( algId.ObjectID, password, parameters); IMac mac = (IMac)PbeUtilities.CreateEngine(algId.ObjectID); mac.Init(keyParameters); mac.BlockUpdate(data, 0, data.Length); byte[] res = new byte[mac.GetMacSize()]; mac.DoFinal(res, 0); byte[] dig = dInfo.GetDigest(); if (!Arrays.AreEqual(res, dig)) { if (password.Length > 0) { throw new Exception("Pkcs12 key store mac invalid - wrong password or corrupted file."); } // // may be incorrect zero length password // keyParameters = PbeUtilities.GenerateCipherParameters( algId.ObjectID, password, true, parameters); mac.Init(keyParameters); mac.BlockUpdate(data, 0, data.Length); res = new byte[mac.GetMacSize()]; mac.DoFinal(res, 0); if (!Arrays.AreEqual(res, dig)) { throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); } wrongPkcs12Zero = true; } } keys = new Hashtable(); localIds = new Hashtable(); if (info.ContentType.Equals(PkcsObjectIdentifiers.Data)) { byte[] octs = ((Asn1OctetString)info.Content).GetOctets(); AuthenticatedSafe authSafe = new AuthenticatedSafe( (Asn1Sequence)Asn1OctetString.FromByteArray(octs)); ContentInfo[] c = authSafe.GetContentInfo(); for (int i = 0; i != c.Length; i++) { if (c[i].ContentType.Equals(PkcsObjectIdentifiers.Data)) { byte[] octets = ((Asn1OctetString)c[i].Content).GetOctets(); Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(octets); for (int j = 0; j != seq.Count; j++) { SafeBag b = new SafeBag((Asn1Sequence)seq[j]); if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue); PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo( password, wrongPkcs12Zero, eIn); AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo); // // set the attributes on the key // Hashtable attributes = new Hashtable(); AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes); string alias = null; Asn1OctetString localId = null; if (b.BagAttributes != null) { foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; Asn1Encodable attr = null; if (attrSet.Count > 0) { attr = attrSet[0]; attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); keys[alias] = pkcs12Key; } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } } if (localId != null) { string name = Encoding.ASCII.GetString(Hex.Encode(localId.GetOctets())); if (alias == null) { keys[name] = pkcs12Key; } else { localIds[alias] = name; } } else { unmarkedKey = true; keys["unmarked"] = pkcs12Key; } } else if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag)) { chain.Add(b); } else { Console.WriteLine("extra " + b.BagID); Console.WriteLine("extra " + Asn1Dump.DumpAsString(b)); } } } else if (c[i].ContentType.Equals(PkcsObjectIdentifiers.EncryptedData)) { EncryptedData d = EncryptedData.GetInstance(c[i].Content); Asn1Sequence seq = DecryptData(d.EncryptionAlgorithm, d.Content.GetOctets(), password, wrongPkcs12Zero); for (int j = 0; j != seq.Count; j++) { SafeBag b = new SafeBag((Asn1Sequence)seq[j]); if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag)) { chain.Add(b); } else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue); PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo( password, wrongPkcs12Zero, eIn); AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo); // // set the attributes on the key // Hashtable attributes = new Hashtable(); AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes); string alias = null; Asn1OctetString localId = null; foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; Asn1Encodable attr = null; if (attrSet.Count > 0) { attr = attrSet[0]; attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); keys[alias] = pkcs12Key; } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } string name = Encoding.ASCII.GetString(Hex.Encode(localId.GetOctets())); if (alias == null) { keys[name] = pkcs12Key; } else { localIds[alias] = name; } } else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag)) { PrivateKeyInfo privKeyInfo = PrivateKeyInfo.GetInstance(b.BagValue); AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyInfo); // // set the attributes on the key // string alias = null; Asn1OctetString localId = null; Hashtable attributes = new Hashtable(); AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes); foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; Asn1Encodable attr = null; if (attrSet.Count > 0) { attr = attrSet[0]; attributes.Add(aOid.Id, attr); } if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); keys[alias] = pkcs12Key; } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } string name = Encoding.ASCII.GetString(Hex.Encode(localId.GetOctets())); if (alias == null) { keys[name] = pkcs12Key; } else { localIds[alias] = name; } } else { Console.WriteLine("extra " + b.BagID); Console.WriteLine("extra " + Asn1Dump.DumpAsString(b)); } } } else { Console.WriteLine("extra " + c[i].ContentType.Id); Console.WriteLine("extra " + Asn1Dump.DumpAsString(c[i].Content)); } } } certs = new Hashtable(); chainCerts = new Hashtable(); keyCerts = new Hashtable(); for (int i = 0; i < chain.Count; ++i) { SafeBag b = (SafeBag)chain[i]; CertBag cb = new CertBag((Asn1Sequence)b.BagValue); byte[] octets = ((Asn1OctetString)cb.CertValue).GetOctets(); X509Certificate cert = new X509CertificateParser().ReadCertificate(octets); // // set the attributes // Hashtable attributes = new Hashtable(); X509CertificateEntry pkcs12Cert = new X509CertificateEntry(cert, attributes); Asn1OctetString localId = null; string alias = null; if (b.BagAttributes != null) { foreach (Asn1Sequence sq in b.BagAttributes) { DerObjectIdentifier aOid = (DerObjectIdentifier)sq[0]; Asn1Set attrSet = (Asn1Set)sq[1]; if (attrSet.Count > 0) { Asn1Encodable attr = attrSet[0]; attributes.Add(aOid.Id, attr); if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { alias = ((DerBmpString)attr).GetString(); } else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { localId = (Asn1OctetString)attr; } } } } AsymmetricKeyParameter publicKey = cert.GetPublicKey(); chainCerts[new CertId(publicKey)] = pkcs12Cert; if (unmarkedKey) { if (keyCerts.Count == 0) { string name = Encoding.ASCII.GetString( Hex.Encode( new SubjectKeyIdentifier( SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey)).GetKeyIdentifier())); keyCerts[name] = pkcs12Cert; object temp = keys["unmarked"]; keys.Remove("unmarked"); keys[name] = temp; } } else { if (localId != null) { string name = Encoding.ASCII.GetString( Hex.Encode(localId.GetOctets())); keyCerts[name] = pkcs12Cert; } if (alias != null) { certs[alias] = pkcs12Cert; } } } }
public void Load(Stream input, char[] password) { if (input == null) { throw new ArgumentNullException("input"); } Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromStream(input); Pfx pfx = new Pfx(seq); ContentInfo authSafe = pfx.AuthSafe; bool wrongPkcs12Zero = false; if (password != null && pfx.MacData != null) { MacData macData = pfx.MacData; DigestInfo mac = macData.Mac; AlgorithmIdentifier algorithmID = mac.AlgorithmID; byte[] salt = macData.GetSalt(); int intValue = macData.IterationCount.IntValue; byte[] octets = ((Asn1OctetString)authSafe.Content).GetOctets(); byte[] a = Pkcs12Store.CalculatePbeMac(algorithmID.ObjectID, salt, intValue, password, false, octets); byte[] digest = mac.GetDigest(); if (!Arrays.ConstantTimeAreEqual(a, digest)) { if (password.Length > 0) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } a = Pkcs12Store.CalculatePbeMac(algorithmID.ObjectID, salt, intValue, password, true, octets); if (!Arrays.ConstantTimeAreEqual(a, digest)) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } wrongPkcs12Zero = true; } } this.keys.Clear(); this.localIds.Clear(); this.unmarkedKeyEntry = null; IList list = Platform.CreateArrayList(); if (authSafe.ContentType.Equals(PkcsObjectIdentifiers.Data)) { byte[] octets2 = ((Asn1OctetString)authSafe.Content).GetOctets(); AuthenticatedSafe authenticatedSafe = new AuthenticatedSafe((Asn1Sequence)Asn1Object.FromByteArray(octets2)); ContentInfo[] contentInfo = authenticatedSafe.GetContentInfo(); ContentInfo[] array = contentInfo; for (int i = 0; i < array.Length; i++) { ContentInfo contentInfo2 = array[i]; DerObjectIdentifier contentType = contentInfo2.ContentType; byte[] array2 = null; if (contentType.Equals(PkcsObjectIdentifiers.Data)) { array2 = ((Asn1OctetString)contentInfo2.Content).GetOctets(); } else if (contentType.Equals(PkcsObjectIdentifiers.EncryptedData) && password != null) { EncryptedData instance = EncryptedData.GetInstance(contentInfo2.Content); array2 = Pkcs12Store.CryptPbeData(false, instance.EncryptionAlgorithm, password, wrongPkcs12Zero, instance.Content.GetOctets()); } if (array2 != null) { Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(array2); foreach (Asn1Sequence seq2 in asn1Sequence) { SafeBag safeBag = new SafeBag(seq2); if (safeBag.BagID.Equals(PkcsObjectIdentifiers.CertBag)) { list.Add(safeBag); } else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { this.LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes, password, wrongPkcs12Zero); } else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.KeyBag)) { this.LoadKeyBag(PrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes); } } } } } this.certs.Clear(); this.chainCerts.Clear(); this.keyCerts.Clear(); foreach (SafeBag safeBag2 in list) { CertBag certBag = new CertBag((Asn1Sequence)safeBag2.BagValue); byte[] octets3 = ((Asn1OctetString)certBag.CertValue).GetOctets(); X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(octets3); IDictionary dictionary = Platform.CreateHashtable(); Asn1OctetString asn1OctetString = null; string text = null; if (safeBag2.BagAttributes != null) { foreach (Asn1Sequence asn1Sequence2 in safeBag2.BagAttributes) { DerObjectIdentifier instance2 = DerObjectIdentifier.GetInstance(asn1Sequence2[0]); Asn1Set instance3 = Asn1Set.GetInstance(asn1Sequence2[1]); if (instance3.Count > 0) { Asn1Encodable asn1Encodable = instance3[0]; if (dictionary.Contains(instance2.Id)) { if (!dictionary[instance2.Id].Equals(asn1Encodable)) { throw new IOException("attempt to add existing attribute with different value"); } } else { dictionary.Add(instance2.Id, asn1Encodable); } if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { text = ((DerBmpString)asn1Encodable).GetString(); } else if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { asn1OctetString = (Asn1OctetString)asn1Encodable; } } } } Pkcs12Store.CertId certId = new Pkcs12Store.CertId(x509Certificate.GetPublicKey()); X509CertificateEntry value = new X509CertificateEntry(x509Certificate, dictionary); this.chainCerts[certId] = value; if (this.unmarkedKeyEntry != null) { if (this.keyCerts.Count == 0) { string text2 = Hex.ToHexString(certId.Id); this.keyCerts[text2] = value; this.keys[text2] = this.unmarkedKeyEntry; } } else { if (asn1OctetString != null) { string key = Hex.ToHexString(asn1OctetString.GetOctets()); this.keyCerts[key] = value; } if (text != null) { this.certs[text] = value; } } } }