Inheritance: Org.BouncyCastle.Asn1.Asn1Encodable
コード例 #1
0
		/**
		 * Just re-encode the outer layer of the PKCS#12 file to definite length encoding.
		 *
		 * @param berPKCS12File - original PKCS#12 file
		 * @return a byte array representing the DER encoding of the PFX structure
		 * @throws IOException
		 */
		public static byte[] ConvertToDefiniteLength(
			byte[] berPkcs12File)
		{
			Pfx pfx = new Pfx(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(berPkcs12File)));

			return pfx.GetEncoded(Asn1Encodable.Der);
		}
コード例 #2
0
		/**
		* Re-encode the PKCS#12 structure to definite length encoding at the inner layer
		* as well, recomputing the MAC accordingly.
		*
		* @param berPKCS12File - original PKCS12 file.
		* @param provider - provider to use for MAC calculation.
		* @return a byte array representing the DER encoding of the PFX structure.
		* @throws IOException on parsing, encoding errors.
		*/
		public static byte[] ConvertToDefiniteLength(
			byte[]	berPkcs12File,
			char[]	passwd)
		{
			Pfx pfx = new Pfx(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(berPkcs12File)));

			ContentInfo info = pfx.AuthSafe;

			Asn1OctetString content = Asn1OctetString.GetInstance(info.Content);
			Asn1Object obj = Asn1Object.FromByteArray(content.GetOctets());

			info = new ContentInfo(info.ContentType, new DerOctetString(obj.GetEncoded(Asn1Encodable.Der)));

			MacData mData = pfx.MacData;

			try
			{
				int itCount = mData.IterationCount.IntValue;
				byte[] data = Asn1OctetString.GetInstance(info.Content).GetOctets();
				byte[] res = Pkcs12Store.CalculatePbeMac(
					mData.Mac.AlgorithmID.ObjectID, mData.GetSalt(), itCount, passwd, false, data);

				AlgorithmIdentifier algId = new AlgorithmIdentifier(
					mData.Mac.AlgorithmID.ObjectID, DerNull.Instance);
				DigestInfo dInfo = new DigestInfo(algId, res);

				mData = new MacData(dInfo, mData.GetSalt(), itCount);
			}
			catch (Exception e)
			{
				throw new IOException("error constructing MAC: " + e.ToString());
			}

			pfx = new Pfx(info, mData);

			return pfx.GetEncoded(Asn1Encodable.Der);
		}
コード例 #3
0
        public void Save(
            Stream			stream,
            char[]			password,
            SecureRandom	random)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");
            if (random == null)
                throw new ArgumentNullException("random");

            //
            // handle the keys
            //
            Asn1EncodableVector keyBags = new Asn1EncodableVector();
            foreach (string name in keys.Keys)
            {
                byte[] kSalt = new byte[SaltSize];
                random.NextBytes(kSalt);

                AsymmetricKeyEntry privKey = (AsymmetricKeyEntry)keys[name];

                DerObjectIdentifier bagOid;
                Asn1Encodable bagData;

                if (password == null)
                {
                    bagOid = PkcsObjectIdentifiers.KeyBag;
                    bagData = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey.Key);
                }
                else
                {
                    bagOid = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag;
                    bagData = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
                        keyAlgorithm, password, kSalt, MinIterations, privKey.Key);
                }

                Asn1EncodableVector kName = new Asn1EncodableVector();

                foreach (string oid in privKey.BagAttributeKeys)
                {
                    Asn1Encodable entry = privKey[oid];

                    // NB: Ignore any existing FriendlyName
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                        continue;

                    kName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(entry)));
                }

                //
                // make sure we are using the local alias on store
                //
                // NB: We always set the FriendlyName based on 'name'
                //if (privKey[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null)
                {
                    kName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(name))));
                }

                //
                // make sure we have a local key-id
                //
                if (privKey[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    X509CertificateEntry ct = GetCertificate(name);
                    AsymmetricKeyParameter pubKey = ct.Certificate.GetPublicKey();
                    SubjectKeyIdentifier subjectKeyID = CreateSubjectKeyID(pubKey);

                    kName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(subjectKeyID)));
                }

                keyBags.Add(new SafeBag(bagOid, bagData.ToAsn1Object(), new DerSet(kName)));
            }

            byte[] keyBagsEncoding = new DerSequence(keyBags).GetDerEncoded();
            ContentInfo keysInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(keyBagsEncoding));

            //
            // certificate processing
            //
            byte[] cSalt = new byte[SaltSize];

            random.NextBytes(cSalt);

            Asn1EncodableVector	certBags = new Asn1EncodableVector();
            Pkcs12PbeParams		cParams = new Pkcs12PbeParams(cSalt, MinIterations);
            AlgorithmIdentifier	cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.ToAsn1Object());
            ISet				doneCerts = new HashSet();

            foreach (string name in keys.Keys)
            {
                X509CertificateEntry certEntry = GetCertificate(name);
                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509Certificate,
                    new DerOctetString(certEntry.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in certEntry.BagAttributeKeys)
                {
                    Asn1Encodable entry = certEntry[oid];

                    // NB: Ignore any existing FriendlyName
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                        continue;

                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(entry)));
                }

                //
                // make sure we are using the local alias on store
                //
                // NB: We always set the FriendlyName based on 'name'
                //if (certEntry[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null)
                {
                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(name))));
                }

                //
                // make sure we have a local key-id
                //
                if (certEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    AsymmetricKeyParameter pubKey = certEntry.Certificate.GetPublicKey();
                    SubjectKeyIdentifier subjectKeyID = CreateSubjectKeyID(pubKey);

                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(subjectKeyID)));
                }

                certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)));

                doneCerts.Add(certEntry.Certificate);
            }

            foreach (string certId in certs.Keys)
            {
                X509CertificateEntry cert = (X509CertificateEntry)certs[certId];

                if (keys[certId] != null)
                    continue;

                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509Certificate,
                    new DerOctetString(cert.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in cert.BagAttributeKeys)
                {
                    // a certificate not immediately linked to a key doesn't require
                    // a localKeyID and will confuse some PKCS12 implementations.
                    //
                    // If we find one, we'll prune it out.
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                        continue;

                    Asn1Encodable entry = cert[oid];

                    // NB: Ignore any existing FriendlyName
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                        continue;

                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(entry)));
                }

                //
                // make sure we are using the local alias on store
                //
                // NB: We always set the FriendlyName based on 'certId'
                //if (cert[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null)
                {
                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(certId))));
                }

                certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)));

                doneCerts.Add(cert.Certificate);
            }

            foreach (CertId certId in chainCerts.Keys)
            {
                X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId];

                if (doneCerts.Contains(cert.Certificate))
                    continue;

                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509Certificate,
                    new DerOctetString(cert.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in cert.BagAttributeKeys)
                {
                    // a certificate not immediately linked to a key doesn't require
                    // a localKeyID and will confuse some PKCS12 implementations.
                    //
                    // If we find one, we'll prune it out.
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                        continue;

                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(cert[oid])));
                }

                certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)));
            }

            byte[] certBagsEncoding = new DerSequence(certBags).GetDerEncoded();

            ContentInfo certsInfo;
            if (password == null)
            {
                certsInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(certBagsEncoding));
            }
            else
            {
                byte[] certBytes = CryptPbeData(true, cAlgId, password, false, certBagsEncoding);
                EncryptedData cInfo = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes));
                certsInfo = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object());
            }

            ContentInfo[] info = new ContentInfo[]{ keysInfo, certsInfo };

            byte[] data = new AuthenticatedSafe(info).GetEncoded(
                useDerEncoding ? Asn1Encodable.Der : Asn1Encodable.Ber);

            ContentInfo mainInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(data));

            //
            // create the mac
            //
            MacData macData = null;
            if (password != null)
            {
                byte[] mSalt = new byte[20];
                random.NextBytes(mSalt);

                byte[] mac = CalculatePbeMac(OiwObjectIdentifiers.IdSha1,
                    mSalt, MinIterations, password, false, data);

                AlgorithmIdentifier algId = new AlgorithmIdentifier(
                    OiwObjectIdentifiers.IdSha1, DerNull.Instance);
                DigestInfo dInfo = new DigestInfo(algId, mac);

                macData = new MacData(dInfo, mSalt, MinIterations);
            }

            //
            // output the Pfx
            //
            Pfx pfx = new Pfx(mainInfo, macData);

            DerOutputStream derOut;
            if (useDerEncoding)
            {
                derOut = new DerOutputStream(stream);
            }
            else
            {
                derOut = new BerOutputStream(stream);
            }

            derOut.WriteObject(pfx);
        }
コード例 #4
0
		private void basicStoreTest(AsymmetricKeyEntry privKey, X509CertificateEntry[] chain,
			DerObjectIdentifier keyAlgorithm, DerObjectIdentifier certAlgorithm)
		{
			Pkcs12Store store = new Pkcs12StoreBuilder()
				.SetKeyAlgorithm(keyAlgorithm)
				.SetCertAlgorithm(certAlgorithm)
				.Build();

			store.SetKeyEntry("key", privKey, chain);

			MemoryStream bOut = new MemoryStream();

			store.Save(bOut, passwd, new SecureRandom());

			store.Load(new MemoryStream(bOut.ToArray(), false), passwd);

			AsymmetricKeyEntry k = store.GetKey("key");

			if (!k.Equals(privKey))
			{
				Fail("private key didn't match");
			}

			X509CertificateEntry[] c = store.GetCertificateChain("key");

			if (c.Length != chain.Length || !c[0].Equals(chain[0]))
			{
				Fail("certificates didn't match");
			}

			// check attributes
			Pkcs12Entry b1 = k;
			Pkcs12Entry b2 = chain[0];

			if (b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] != null)
			{
				DerBmpString name = (DerBmpString)b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName];

				if (!name.Equals(new DerBmpString("key")))
				{
					Fail("friendly name wrong");
				}
			}
			else
			{
				Fail("no friendly name found on key");
			}

			if (b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null)
			{
				Asn1OctetString id = (Asn1OctetString)b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID];

				if (!id.Equals(b2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID]))
				{
					Fail("local key id mismatch");
				}
			}
			else
			{
				Fail("no local key id found");
			}

			//
			// check algorithm types.
			//
			Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray());

			Pfx pfx = new Pfx((Asn1Sequence)aIn.ReadObject());

			ContentInfo cInfo = pfx.AuthSafe;

			Asn1OctetString auth = (Asn1OctetString)cInfo.Content;

			aIn = new Asn1InputStream(auth.GetOctets());
			Asn1Sequence s1 = (Asn1Sequence)aIn.ReadObject();

			ContentInfo c1 = ContentInfo.GetInstance(s1[0]);
			ContentInfo c2 = ContentInfo.GetInstance(s1[1]);

			aIn = new Asn1InputStream(((Asn1OctetString)c1.Content).GetOctets());

			SafeBag sb = new SafeBag((Asn1Sequence)(((Asn1Sequence)aIn.ReadObject())[0]));

			EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.GetInstance(sb.BagValue);

			// check the key encryption
            if (!encInfo.EncryptionAlgorithm.Algorithm.Equals(keyAlgorithm))
			{
				Fail("key encryption algorithm wrong");
			}

			// check the certificate encryption
			EncryptedData cb = EncryptedData.GetInstance(c2.Content);

            if (!cb.EncryptionAlgorithm.Algorithm.Equals(certAlgorithm))
			{
				Fail("cert encryption algorithm wrong");
			}
		}
コード例 #5
0
        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.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();
            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;
                    }
                }
            }
        }
コード例 #6
0
        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);
                                AsymmetricKeyParameter 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
                            {
                                //TODO: COMENTADO
                                //Console.WriteLine("extra " + b.BagID);
                                //Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    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);
                                AsymmetricKeyParameter 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);
                                AsymmetricKeyParameter 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
                            {
                                //TODO: COMENTADO
                                //Console.WriteLine("extra " + b.BagID);
                                //Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else
                    {
                        //TODO: COMENTADO
                        //Console.WriteLine("extra " + oid);
                        //Console.WriteLine("extra " + Asn1Dump.DumpAsString(ci.Content));
                    }
                }
            }

            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;
                    }
                }
            }
        }
コード例 #7
0
ファイル: PKCS12Test.cs プロジェクト: randombit/hacrypto
		public override void PerformTest()
		{
			Asn1Sequence obj = (Asn1Sequence) Asn1Object.FromByteArray(pkcs12);

			Pfx                 bag = new Pfx(obj);
			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;

			byte[] octets = ((Asn1OctetString) info.Content).GetOctets();
			AuthenticatedSafe authSafe = new AuthenticatedSafe(
				(Asn1Sequence) Asn1Object.FromByteArray(octets));
			ContentInfo[] c = authSafe.GetContentInfo();

			//
			// private key section
			//
			if (!c[0].ContentType.Equals(PkcsObjectIdentifiers.Data))
			{
				Fail("Failed comparison data test");
			}

			octets = ((Asn1OctetString)c[0].Content).GetOctets();
			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(octets);

			SafeBag b = new SafeBag((Asn1Sequence)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[] encodedBytes = new DerSequence(b).GetEncoded();

			c[0] = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encodedBytes));

			//
			// 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);

			info = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(authSafe.GetEncoded()));

			mData = new MacData(new DigestInfo(algId, dInfo.GetDigest()), salt, itCount);

			bag = new Pfx(info, mData);

			//
			// comparison test
			//
			if (!Arrays.AreEqual(bag.GetEncoded(), pkcs12))
			{
				Fail("Failed comparison test");
			}
		}
コード例 #8
0
ファイル: Pkcs12Store.cs プロジェクト: hjgode/iTextSharpCF
        public void Save(
        	Stream			stream,
        	char[]			password,
        	SecureRandom	random)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");
            if (password == null)
                throw new ArgumentNullException("password");
            if (random == null)
                throw new ArgumentNullException("random");

            ContentInfo[] c = new ContentInfo[2];

            //
            // handle the key
            //
            Asn1EncodableVector keyS = new Asn1EncodableVector();
            foreach (string name in keys.Keys)
            {
                byte[] kSalt = new byte[saltSize];
                random.NextBytes(kSalt);

                AsymmetricKeyEntry privKey = (AsymmetricKeyEntry) keys[name];
                EncryptedPrivateKeyInfo kInfo =
                    EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
                        keyAlgorithm, password, kSalt, minIterations, privKey.Key);

                Asn1EncodableVector kName = new Asn1EncodableVector();

                foreach (string oid in privKey.BagAttributeKeys)
                {
                    kName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(privKey[oid])));
                }

                //
                // make sure we have a local key-id
                //
                if (privKey[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    X509CertificateEntry ct = GetCertificate(name);

                    SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(
                        ct.Certificate.GetPublicKey());

                    kName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(new SubjectKeyIdentifier(info))));
                }

                //
                // make sure we are using the local alias on store
                //
                DerBmpString nm = (DerBmpString) privKey[PkcsObjectIdentifiers.Pkcs9AtFriendlyName];
                if (nm == null || !nm.GetString().Equals(name))
                {
                    kName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(name))));
                }

                SafeBag kBag = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, kInfo.ToAsn1Object(), new DerSet(kName));
                keyS.Add(kBag);
            }

            byte[] derEncodedBytes = new DerSequence(keyS).GetDerEncoded();

            BerOctetString keyString = new BerOctetString(derEncodedBytes);

            //
            // certificate processing
            //
            byte[] cSalt = new byte[saltSize];

            random.NextBytes(cSalt);

            Asn1EncodableVector	certSeq = new Asn1EncodableVector();
            Pkcs12PbeParams		cParams = new Pkcs12PbeParams(cSalt, minIterations);
            AlgorithmIdentifier	cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.ToAsn1Object());
            Hashtable			doneCerts = new Hashtable();

            foreach (string name in keys.Keys)
            {
                X509CertificateEntry certEntry = GetCertificate(name);
                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509CertType,
                    new DerOctetString(certEntry.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in certEntry.BagAttributeKeys)
                {
                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(certEntry[oid])));
                }

                //
                // make sure we are using the local alias on store
                //
                DerBmpString nm = (DerBmpString)certEntry[PkcsObjectIdentifiers.Pkcs9AtFriendlyName];
                if (nm == null || !nm.GetString().Equals(name))
                {
                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(name))));
                }

                //
                // make sure we have a local key-id
                //
                if (certEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(
                        certEntry.Certificate.GetPublicKey());

                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(new SubjectKeyIdentifier(info))));
                }

                SafeBag sBag = new SafeBag(
                    PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName));

                certSeq.Add(sBag);

                doneCerts.Add(certEntry.Certificate, certEntry.Certificate);
            }

            foreach (string certId in certs.Keys)
            {
                X509CertificateEntry cert = (X509CertificateEntry)certs[certId];

                if (keys[certId] != null)
                {
                    continue;
                }

                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509CertType,
                    new DerOctetString(cert.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in cert.BagAttributeKeys)
                {
                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(cert[oid])));
                }

                //
                // make sure we are using the local alias on store
                //
                DerBmpString nm = (DerBmpString) cert[PkcsObjectIdentifiers.Pkcs9AtFriendlyName];
                if (nm == null || !nm.GetString().Equals(certId))
                {
                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(certId))));
                }

                SafeBag sBag = new SafeBag(PkcsObjectIdentifiers.CertBag,
                    cBag.ToAsn1Object(), new DerSet(fName));

                certSeq.Add(sBag);

                doneCerts.Add(cert, cert);
            }

            foreach (CertId certId in chainCerts.Keys)
            {
                X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId];

                if (doneCerts[cert] != null)
                {
                    continue;
                }

                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509CertType,
                    new DerOctetString(cert.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in cert.BagAttributeKeys)
                {
                    fName.Add(new DerSequence(new DerObjectIdentifier(oid), new DerSet(cert[oid])));
                }

                SafeBag sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName));

                certSeq.Add(sBag);
            }

            derEncodedBytes = new DerSequence(certSeq).GetDerEncoded();

            byte[] certBytes = EncryptData(new AlgorithmIdentifier(certAlgorithm, cParams), derEncodedBytes, password);
            EncryptedData cInfo = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes));

            c[0] = new ContentInfo(PkcsObjectIdentifiers.Data, keyString);
            c[1] = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object());

            AuthenticatedSafe auth = new AuthenticatedSafe(c);

            byte[] pkg = auth.GetEncoded();

            ContentInfo mainInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(pkg));

            //
            // create the mac
            //
            byte[] mSalt = new byte[20];
            int itCount = minIterations;

            random.NextBytes(mSalt);

            byte[] data = ((Asn1OctetString)mainInfo.Content).GetOctets();

            Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters(OiwObjectIdentifiers.IdSha1, mSalt, itCount);
            ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters(
                OiwObjectIdentifiers.IdSha1, password, parameters);
            IMac mac = (IMac)PbeUtilities.CreateEngine(OiwObjectIdentifiers.IdSha1);

            mac.Init(keyParameters);

            mac.BlockUpdate(data, 0, data.Length);

            byte[] res = new byte[mac.GetMacSize()];

            mac.DoFinal(res, 0);

            AlgorithmIdentifier algId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
            DigestInfo dInfo = new DigestInfo(algId, res);

            MacData mData = new MacData(dInfo, mSalt, itCount);

            //
            // output the Pfx
            //
            Pfx pfx = new Pfx(mainInfo, mData);

            BerOutputStream berOut = new BerOutputStream(stream);

            berOut.WriteObject(pfx);
        }
コード例 #9
0
ファイル: Pkcs12Store.cs プロジェクト: hjgode/iTextSharpCF
        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 IgnoresCaseHashtable();
            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)
                                {
                                    // MASC 20070308. CF compatibility patch
                                    byte[] hex = Hex.Encode(localId.GetOctets());
                                    string name = Encoding.ASCII.GetString(hex,0,hex.Length);

                                    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;
                                    }
                                }

                                // MASC 20070308. CF compatibility patch
                                byte[] hex = Hex.Encode(localId.GetOctets());
                                string name = Encoding.ASCII.GetString(hex,0,hex.Length);

                                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;
                                    }
                                }

                                // MASC 20070308. CF compatibility patch
                                byte[] hex = Hex.Encode(localId.GetOctets());
                                string name = Encoding.ASCII.GetString(hex,0,hex.Length);

                                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 IgnoresCaseHashtable();
            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)
                    {
                        // MASC 20070308. CF compatibility patch
                        byte[] hex =
                            Hex.Encode(
                                new SubjectKeyIdentifier(
                                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey)).GetKeyIdentifier());

                        string name = Encoding.ASCII.GetString( hex,0,hex.Length );

                        keyCerts[name] = pkcs12Cert;

                        object temp = keys["unmarked"];
                        keys.Remove("unmarked");
                        keys[name] = temp;
                    }
                }
                else
                {
                    if (localId != null)
                    {
                        // MASC 20070308. CF compatibility patch
                        byte[] hex = Hex.Encode(localId.GetOctets());
                        string name = Encoding.ASCII.GetString( hex,0,hex.Length );

                        keyCerts[name] = pkcs12Cert;
                    }

                    if (alias != null)
                    {
                        certs[alias] = pkcs12Cert;
                    }
                }
            }
        }