コード例 #1
0
            public override bool Equals(
                Object o)
            {
                if (!(o is CertId))
                {
                    return(false);
                }

                CertId cId = (CertId)o;

                if (cId.id.Length != id.Length)
                {
                    return(false);
                }

                for (int i = 0; i != id.Length; i++)
                {
                    if (cId.id[i] != id[i])
                    {
                        return(false);
                    }
                }

                return(true);
            }
コード例 #2
0
        private static void AclCert(CertId certId, string accountName)
        {
            X509Store store = null;

            try
            {
                store = new X509Store(certId.StoreName, StoreLocation.LocalMachine);
                store.Open(OpenFlags.ReadWrite | OpenFlags.OpenExistingOnly);

                X509Certificate2Collection certs = store.Certificates.Find(ConvertToX509FindType(certId.FindType), certId.FindValue, validOnly: false);
                if (certs == null || certs.Count == 0)
                {
                    DeployerTrace.WriteInfo("AclCert is skipped for {0} because it's not installed", certId);
                    return;
                }

                foreach (X509Certificate2 cert in certs)
                {
                    if (cert.PrivateKey == null)
                    {
                        DeployerTrace.WriteWarning("AclCert is skipped for {0} because its private key is null", certId);
                        continue;
                    }

                    RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider;
                    if (privateKey == null)
                    {
                        DeployerTrace.WriteWarning("AclCert is skipped for {0} because its private key type {1} is not supported ", certId, cert.PrivateKey.GetType());
                        continue;
                    }

                    CspParameters csp = new CspParameters(privateKey.CspKeyContainerInfo.ProviderType, privateKey.CspKeyContainerInfo.ProviderName, privateKey.CspKeyContainerInfo.KeyContainerName);
                    csp.Flags     = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore;
                    csp.KeyNumber = (int)privateKey.CspKeyContainerInfo.KeyNumber;
#if !DotNetCoreClr
                    csp.CryptoKeySecurity = privateKey.CspKeyContainerInfo.CryptoKeySecurity;

                    CryptoKeyAccessRule accessRule = new CryptoKeyAccessRule(accountName, CryptoKeyRights.FullControl, AccessControlType.Allow);
                    csp.CryptoKeySecurity.AddAccessRule(accessRule);
#endif

                    using (RSACryptoServiceProvider newCsp = new RSACryptoServiceProvider(csp))
                    {
                        DeployerTrace.WriteInfo("AclCert success: {0}", certId);
                    }
                }
            }
            catch (Exception ex)
            {
                DeployerTrace.WriteError("AclCert error with {0}: {1}", certId, ex);
            }
            finally
            {
                if (store != null)
                {
                    store.Close();
                }
            }
        }
コード例 #3
0
 public virtual RevRepContentBuilder Add(PkiStatusInfo status, CertId certId)
 {
     if (this.status.Count != revCerts.Count)
     {
         throw new InvalidOperationException("status and revCerts sequence must be in common order");
     }
     this.status.Add(status);
     revCerts.Add(certId);
     return(this);
 }
コード例 #4
0
 private RevAnnContent(Asn1Sequence seq)
 {
     status          = PkiStatusEncodable.GetInstance(seq[0]);
     certId          = CertId.GetInstance(seq[1]);
     willBeRevokedAt = DerGeneralizedTime.GetInstance(seq[2]);
     badSinceDate    = DerGeneralizedTime.GetInstance(seq[3]);
     if (seq.Count > 4)
     {
         crlDetails = X509Extensions.GetInstance(seq[4]);
     }
 }
コード例 #5
0
 public virtual RevRepContentBuilder Add(PkiStatusInfo status, CertId certId)
 {
     //IL_001d: Unknown result type (might be due to invalid IL or missing references)
     if (this.status.Count != revCerts.Count)
     {
         throw new InvalidOperationException("status and revCerts sequence must be in common order");
     }
     this.status.Add(status);
     revCerts.Add(certId);
     return(this);
 }
コード例 #6
0
 public virtual CertId[] GetRevCerts()
 {
     if (this.revCerts == null)
     {
         return(null);
     }
     CertId[] array = new CertId[this.revCerts.Count];
     for (int num = 0; num != array.Length; num++)
     {
         array[num] = CertId.GetInstance(this.revCerts[num]);
     }
     return(array);
 }
コード例 #7
0
 public virtual CertId[] GetRevCerts()
 {
     if (revCerts == null)
     {
         return(null);
     }
     CertId[] array = new CertId[revCerts.Count];
     for (int i = 0; i != array.Length; i++)
     {
         array[i] = CertId.GetInstance(revCerts[i]);
     }
     return(array);
 }
コード例 #8
0
            public override bool Equals(object obj)
            {
                if (obj == null || !(obj is CertId))
                {
                    return(false);
                }

                CertId theOther = (CertId)obj;

                return(this.FindType == theOther.FindType &&
                       this.FindValue == theOther.FindValue &&
                       this.StoreName == theOther.StoreName);
            }
コード例 #9
0
			public override bool Equals(
				object obj)
			{
				if (obj == this)
					return true;

				CertId other = obj as CertId;

				if (other == null)
					return false;

				return Arrays.AreEqual(id, other.id);
			}
コード例 #10
0
        public virtual CertId[] GetRevCerts()
        {
            if (revCerts == null)
            {
                return(null);
            }

            CertId[] results = new CertId[revCerts.Count];
            for (int i = 0; i != results.Length; ++i)
            {
                results[i] = CertId.GetInstance(revCerts[i]);
            }
            return(results);
        }
コード例 #11
0
        /// <summary>
        /// Encodes OCSPSingleRequest object to a ASN.1-encoded byte aray.
        /// </summary>
        /// <returns>ASN.1-encoded byte array.</returns>
        public Byte[] Encode()
        {
            if (String.IsNullOrEmpty(CertId.SerialNumber))
            {
                throw new UninitializedObjectException();
            }
            List <Byte> rawData = new List <Byte>();

            rawData.AddRange(CertId.Encode());
            if (Extensions.Count > 0)
            {
                Byte[] contentspecific0 = Extensions.Encode();
                rawData.AddRange(Asn1Utils.Encode(contentspecific0, 160));
            }
            return(Asn1Utils.Encode(rawData.ToArray(), 48)); // Request
        }
コード例 #12
0
            public override bool Equals(
                object obj)
            {
                if (obj == this)
                {
                    return(true);
                }

                CertId other = obj as CertId;

                if (other == null)
                {
                    return(false);
                }

                return(Arrays.AreEqual(id, other.id));
            }
コード例 #13
0
        private OobCertHash(Asn1Sequence seq)
        {
            int num = seq.Count - 1;

            this.hashVal = DerBitString.GetInstance(seq[num--]);
            for (int i = num; i >= 0; i--)
            {
                Asn1TaggedObject asn1TaggedObject = (Asn1TaggedObject)seq[i];
                if (asn1TaggedObject.TagNo == 0)
                {
                    this.hashAlg = AlgorithmIdentifier.GetInstance(asn1TaggedObject, true);
                }
                else
                {
                    this.certId = CertId.GetInstance(asn1TaggedObject, true);
                }
            }
        }
コード例 #14
0
ファイル: OobCertHash.cs プロジェクト: smdx24/CPI-Source-Code
        private OobCertHash(Asn1Sequence seq)
        {
            int num = seq.Count - 1;

            hashVal = DerBitString.GetInstance(seq[num--]);
            for (int num2 = num; num2 >= 0; num2--)
            {
                Asn1TaggedObject asn1TaggedObject = (Asn1TaggedObject)seq[num2];
                if (asn1TaggedObject.TagNo == 0)
                {
                    hashAlg = AlgorithmIdentifier.GetInstance(asn1TaggedObject, explicitly: true);
                }
                else
                {
                    certId = CertId.GetInstance(asn1TaggedObject, isExplicit: true);
                }
            }
        }
コード例 #15
0
        private OobCertHash(Asn1Sequence seq)
        {
            int index = seq.Count - 1;

            hashVal = DerBitString.GetInstance(seq[index--]);

            for (int i = index; i >= 0; i--)
            {
                Asn1TaggedObject tObj = (Asn1TaggedObject)seq[i];

                if (tObj.TagNo == 0)
                {
                    hashAlg = AlgorithmIdentifier.GetInstance(tObj, true);
                }
                else
                {
                    certId = CertId.GetInstance(tObj, true);
                }
            }
        }
コード例 #16
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);
                                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;
                    }
                }
            }
        }
コード例 #17
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.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;
                    }
                }
            }
        }
コード例 #18
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;
                    }
                }
            }
        }
コード例 #19
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;
                    }
                }
            }
        }
コード例 #20
0
        public void save(Stream stream, char[] password, SecureRandom random)
        {
            if (password == null)
            {
                throw new ArgumentException("No password supplied for PKCS12Store.");
            }

            ContentInfo[] c = new ContentInfo[2];


            //
            // handle the key
            //
            ASN1EncodableVector keyS = new ASN1EncodableVector();


            IEnumerator ks = keys.Keys.GetEnumerator();

            while (ks.MoveNext())
            {
                byte[] kSalt = new byte[saltSize];

                random.nextBytes(kSalt);

                String                  name    = (String)ks.Current;
                AsymmetricKeyEntry      privKey = (AsymmetricKeyEntry)keys[name];
                EncryptedPrivateKeyInfo kInfo   = EncryptedPrivateKeyInfoFactory.createEncryptedPrivateKeyInfo(keyAlgorithm, password, kSalt, minIterations, privKey.getKey());
                ASN1EncodableVector     kName   = new ASN1EncodableVector();

                IEnumerator e = privKey.getBagAttributeKeys();

                while (e.MoveNext())
                {
                    String oid = (String)e.Current;
                    ASN1EncodableVector kSeq = new ASN1EncodableVector();

                    kSeq.add(new DERObjectIdentifier(oid));
                    kSeq.add(new DERSet(privKey.getBagAttribute(new DERObjectIdentifier(oid))));

                    kName.add(new DERSequence(kSeq));
                }

                //
                // make sure we have a local key-id
                //
                if (privKey.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) == null)
                {
                    ASN1EncodableVector  kSeq = new ASN1EncodableVector();
                    X509CertificateEntry ct   = getCertificate(name);

                    kSeq.add(PKCSObjectIdentifiers.pkcs_9_at_localKeyId);
                    kSeq.add(new DERSet(new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(ct.getCertificate().getPublicKey()))));

                    kName.add(new DERSequence(kSeq));
                }

                //
                // make sure we are using the local alias on store
                //
                DERBMPString nm = (DERBMPString)privKey.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                if (nm == null || !nm.getString().Equals(name))
                {
                    ASN1EncodableVector kSeq = new ASN1EncodableVector();

                    kSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                    kSeq.add(new DERSet(new DERBMPString(name)));

                    kName.add(new DERSequence(kSeq));
                }

                SafeBag kBag = new SafeBag(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, kInfo.toASN1Object(), new DERSet(kName));
                keyS.add(kBag);
            }

            MemoryStream    bOut = new MemoryStream();
            DEROutputStream dOut = new DEROutputStream(bOut);

            dOut.writeObject(new DERSequence(keyS));

            BEROctetString keyString = new BEROctetString(bOut.ToArray());

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

            IEnumerator cs = keys.Keys.GetEnumerator();

            while (cs.MoveNext())
            {
                try
                {
                    String name = (String)cs.Current;
                    X509CertificateEntry cert = getCertificate(name);
                    CertBag cBag = new CertBag(
                        PKCSObjectIdentifiers.x509certType,
                        new DEROctetString(cert.getCertificate().getEncoded()));
                    ASN1EncodableVector fName = new ASN1EncodableVector();

                    IEnumerator e = cert.getBagAttributeKeys();

                    while (e.MoveNext())
                    {
                        String oid = (String)e.Current;
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(new DERObjectIdentifier(oid));
                        fSeq.add(new DERSet(cert.getBagAttribute(new DERObjectIdentifier(oid))));
                        fName.add(new DERSequence(fSeq));
                    }

                    //
                    // make sure we are using the local alias on store
                    //
                    DERBMPString nm = (DERBMPString)cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                    if (nm == null || !nm.getString().Equals(name))
                    {
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                        fSeq.add(new DERSet(new DERBMPString(name)));

                        fName.add(new DERSequence(fSeq));
                    }

                    //
                    // make sure we have a local key-id
                    //
                    if (cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) == null)
                    {
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_localKeyId);
                        fSeq.add(new DERSet(new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(cert.getCertificate().getPublicKey()))));
                        fName.add(new DERSequence(fSeq));
                    }

                    SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName));

                    certSeq.add(sBag);

                    doneCerts.Add(cert, cert);
                }
                catch (Exception e)
                {
                    throw new Exception("Error encoding certificate: " + e.Message);
                }
            }

            cs = certs.Keys.GetEnumerator();
            while (cs.MoveNext())
            {
                try
                {
                    String certId             = (String)cs.Current;
                    X509CertificateEntry cert = (X509CertificateEntry)certs[certId];

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

                    CertBag cBag = new CertBag(
                        PKCSObjectIdentifiers.x509certType,
                        new DEROctetString(cert.getCertificate().getEncoded()));
                    ASN1EncodableVector fName = new ASN1EncodableVector();
                    IEnumerator         e     = cert.getBagAttributeKeys();

                    while (e.MoveNext())
                    {
                        String oid = (String)e.Current;
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(new DERObjectIdentifier(oid));
                        fSeq.add(new DERSet(cert.getBagAttribute(new DERObjectIdentifier(oid))));
                        fName.add(new DERSequence(fSeq));
                    }

                    //
                    // make sure we are using the local alias on store
                    //
                    DERBMPString nm = (DERBMPString)cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                    if (nm == null || !nm.getString().Equals(certId))
                    {
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                        fSeq.add(new DERSet(new DERBMPString(certId)));

                        fName.add(new DERSequence(fSeq));
                    }

                    SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName));

                    certSeq.add(sBag);

                    doneCerts.Add(cert, cert);
                }
                catch (Exception e)
                {
                    throw new Exception("Error encoding certificate: " + e.Message);
                }
            }

            cs = chainCerts.Keys.GetEnumerator();
            while (cs.MoveNext())
            {
                try
                {
                    CertId certId             = (CertId)cs.Current;
                    X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId];

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

                    CertBag cBag = new CertBag(
                        PKCSObjectIdentifiers.x509certType,
                        new DEROctetString(cert.getCertificate().getEncoded()));
                    ASN1EncodableVector fName = new ASN1EncodableVector();

                    IEnumerator e = cert.getBagAttributeKeys();

                    while (e.MoveNext())
                    {
                        DERObjectIdentifier oid  = (DERObjectIdentifier)e.Current;
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(oid);
                        fSeq.add(new DERSet(cert.getBagAttribute(oid)));
                        fName.add(new DERSequence(fSeq));
                    }

                    SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName));

                    certSeq.add(sBag);
                }
                catch (Exception e)
                {
                    throw new Exception("Error encoding certificate: " + e.Message);
                }
            }

            bOut = new MemoryStream();

            dOut = new DEROutputStream(bOut);

            dOut.writeObject(new DERSequence(certSeq));

            dOut.Close();

            byte[]        certBytes = encryptData(new AlgorithmIdentifier(certAlgorithm, cParams), bOut.ToArray(), 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);

            bOut = new MemoryStream();

            BEROutputStream berOut = new BEROutputStream(bOut);

            berOut.writeObject(auth);

            byte[] pkg = bOut.ToArray();

            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.getContent()).getOctets();

            MacData mData = null;

            try
            {
                ASN1Encodable    parameters    = PBEUtil.generateAlgorithmParameters(OIWObjectIdentifiers.id_SHA1, mSalt, itCount);
                CipherParameters keyParameters = PBEUtil.generateCipherParameters(OIWObjectIdentifiers.id_SHA1, password, parameters);
                Mac mac = (Mac)PBEUtil.createEngine(OIWObjectIdentifiers.id_SHA1);

                mac.init(keyParameters);

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

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

                mac.doFinal(res, 0);

                AlgorithmIdentifier algId = new AlgorithmIdentifier(OIWObjectIdentifiers.id_SHA1, new DERNull());
                DigestInfo          dInfo = new DigestInfo(algId, res);

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

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

            berOut = new BEROutputStream(stream);

            berOut.writeObject(pfx);
        }