Пример #1
0
        public object GetBagValue()
        {
            if (Type.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
            {
                return(new Pkcs8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo.GetInstance(safeBag.BagValue)));
            }
            if (Type.Equals(PkcsObjectIdentifiers.CertBag))
            {
                CertBag certBag = CertBag.GetInstance(safeBag.BagValue);

                return(new X509Certificate(X509CertificateStructure.GetInstance(Asn1OctetString.GetInstance(certBag.CertValue).GetOctets())));
            }
            if (Type.Equals(PkcsObjectIdentifiers.KeyBag))
            {
                return(PrivateKeyInfo.GetInstance(safeBag.BagValue));
            }
            if (Type.Equals(PkcsObjectIdentifiers.CrlBag))
            {
                CrlBag crlBag = CrlBag.GetInstance(safeBag.BagValue);

                return(new X509Crl(CertificateList.GetInstance(Asn1OctetString.GetInstance(crlBag.CrlValue).GetOctets())));
            }

            return(safeBag.BagValue);
        }
Пример #2
0
        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");
            }

            //
            // 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)
                {
                    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);
                    IAsymmetricKeyParameter pubKey       = ct.Certificate.GetPublicKey();
                    SubjectKeyIdentifier    subjectKeyID = CreateSubjectKeyID(pubKey);

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

                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());
            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)
                {
                    IAsymmetricKeyParameter pubKey       = certEntry.Certificate.GetPublicKey();
                    SubjectKeyIdentifier    subjectKeyID = CreateSubjectKeyID(pubKey);

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

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

                certSeq.Add(sBag);

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

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

                certSeq.Add(sBag);

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

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

                certSeq.Add(sBag);
            }

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

            byte[] certBytes = CryptPbeData(true, cAlgId, password, false, derEncodedBytes);

            EncryptedData cInfo = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes));

            ContentInfo[] info = new ContentInfo[]
            {
                new ContentInfo(PkcsObjectIdentifiers.Data, keyString),
                new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object())
            };

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

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

            //
            // create the mac
            //
            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 mData = new MacData(dInfo, mSalt, MinIterations);

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

            DerOutputStream derOut;

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

            derOut.WriteObject(pfx);
        }
Пример #3
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;
                    }
                }
            }
        }
Пример #4
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;
                    }
                }
            }
        }
Пример #5
0
        public static void Save(this Pkcs12Store store,
                                Stream stream,
                                string encryptionPassword,
                                string integrityPassword,
                                SecureRandom random)
        {
            const int saltSize      = 20;
            const int minIterations = 1024;

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            //if (null != encryptionPassword && encryptionPassword == integrityPassword)
            //{
            //    store.Save(stream, encryptionPassword.ToArray(), random);
            //    return;
            //}
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }

            var T = store.GetType();
            Func <AsymmetricKeyParameter, SubjectKeyIdentifier> CreateSubjectKeyID = (pubKey_) =>
            {
                var method = T.GetMethod("CreateSubjectKeyID", BindingFlags.NonPublic | BindingFlags.Static);
                return((SubjectKeyIdentifier)method.Invoke(store, new object[] { pubKey_ }));
            };

            Func <DerObjectIdentifier> keyAlgorithm = () =>
            {
                var property = T.GetField("keyAlgorithm", BindingFlags.NonPublic | BindingFlags.Instance);
                return((DerObjectIdentifier)property.GetValue(store));
            };


            Func <DerObjectIdentifier> certAlgorithm = () =>
            {
                var property = T.GetField("certAlgorithm", BindingFlags.NonPublic | BindingFlags.Instance);
                return((DerObjectIdentifier)property.GetValue(store));
            };
            //
            // handle the key
            //
            Asn1EncodableVector keyS = new Asn1EncodableVector();
            var keys = store.Aliases.OfType <string>().ToDictionary(alias => alias, store.GetKey);

            foreach (string name in store.Aliases.OfType <string>())
            {
                byte[] kSalt = new byte[saltSize];
                random.NextBytes(kSalt);

                AsymmetricKeyEntry privKey = keys[name];
                Asn1Encodable      kInfo   = null;
                if (!string.IsNullOrEmpty(encryptionPassword))
                {
                    kInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(keyAlgorithm(), encryptionPassword.ToArray(), kSalt, minIterations, privKey.Key);
                }
                else
                {
                    kInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(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           = store.GetCertificate(name);
                    AsymmetricKeyParameter pubKey       = ct.Certificate.GetPublicKey();
                    SubjectKeyIdentifier   subjectKeyID = CreateSubjectKeyID(pubKey);

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

                SafeBag kBag = null;
                if (!string.IsNullOrEmpty(encryptionPassword))
                {
                    kBag = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, kInfo.ToAsn1Object(), new DerSet(kName));
                }
                else
                {
                    kBag = new SafeBag(PkcsObjectIdentifiers.KeyBag, 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());
            ISet doneCerts = new HashSet();

            foreach (string name in keys.Keys)
            {
                X509CertificateEntry certEntry = store.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)));
                }

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

                certSeq.Add(sBag);

                doneCerts.Add(certEntry.Certificate);
            }

            var certs = store.Aliases.OfType <string>().Select(store.GetCertificate);

            foreach (var cert in certs)
            {
                //X509CertificateEntry cert = (X509CertificateEntry)certs[certId];

                //if (keys[certId] != null)
                //    continue;
                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;
                    }

                    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))));
                    fName.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(CreateSubjectKeyID(cert.Certificate.GetPublicKey()).GetKeyIdentifier()))));
                }

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

                certSeq.Add(sBag);

                doneCerts.Add(cert.Certificate);
            }

            var chainCerts = store.Aliases.OfType <string>().Select(store.GetCertificateChain).Aggregate <IEnumerable <X509CertificateEntry>, IEnumerable <X509CertificateEntry> >(new List <X509CertificateEntry>(), (list, entries) => list.Union(entries));

            foreach (var cert in chainCerts)
            {
                //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])));
                }

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

                certSeq.Add(sBag);
            }

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

            Func <bool, AlgorithmIdentifier, char[], bool, byte[], byte[]> CryptPbeData = (forEncryption_, algId_, password_, wrongPkcs12Zero_, data_) =>
            {
                var method = T.GetMethod("CryptPbeData", BindingFlags.NonPublic | BindingFlags.Static);
                return((byte[])method.Invoke(store, new object[] { forEncryption_, algId_, password_, wrongPkcs12Zero_, data_ }));
            };

            ContentInfo[] info = null;
            if (null != encryptionPassword)
            {
                byte[] certBytes = CryptPbeData(true, cAlgId, encryptionPassword.ToArray(), false, derEncodedBytes);

                var cInfo = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes));

                info = new ContentInfo[]
                {
                    new ContentInfo(PkcsObjectIdentifiers.Data, keyString),
                    new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object())
                };
            }
            else
            {
                var cInfo = new BerOctetString(derEncodedBytes);

                info = new ContentInfo[]
                {
                    new ContentInfo(PkcsObjectIdentifiers.Data, keyString),
                    new ContentInfo(PkcsObjectIdentifiers.Data, cInfo.ToAsn1Object())
                };
            }

            byte[] data = new AuthenticatedSafe(info).GetEncoded(Asn1Encodable.Der);

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

            //
            // create the mac
            //
            byte[] mSalt = new byte[saltSize];
            random.NextBytes(mSalt);

            Func <DerObjectIdentifier, byte[], int, char[], bool, byte[], byte[]> CalculatePbeMac = (oid_, salt_, itCount_, password_, wrongPkcs12Zero_, data_) =>
            {
                var method = T.GetMethod("CalculatePbeMac", BindingFlags.NonPublic | BindingFlags.Static);
                return((byte[])method.Invoke(store, new object[] { oid_, salt_, itCount_, password_, wrongPkcs12Zero_, data_ }));
            };


            MacData mData = null;

            if (null != integrityPassword)
            {
                //byte[] mac = CalculatePbeMac(OiwObjectIdentifiers.IdSha1, mSalt, minIterations, integrityPassword.ToArray(), false, data);
                byte[] mac = CalculatePbeMac(PbeUtilities.GetObjectIdentifier("PBEwithHmacSHA-256"), mSalt, minIterations, integrityPassword.ToArray(), false, data);

                //AlgorithmIdentifier algId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
                AlgorithmIdentifier algId = new AlgorithmIdentifier(PbeUtilities.GetObjectIdentifier("PBEwithHmacSHA-256"), DerNull.Instance);

                DigestInfo dInfo = new DigestInfo(algId, mac);

                mData = new MacData(dInfo, mSalt, minIterations);
            }

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

            DerOutputStream derOut = new DerOutputStream(stream);

            derOut.WriteObject(pfx);
        }
Пример #6
0
        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();

            MacData mData = null;

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

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

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

            BerOutputStream berOut = new BerOutputStream(stream);

            berOut.WriteObject(pfx);
        }
Пример #7
0
        public Pkcs12Store(
            Stream input,
            char[]      password)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }

            Asn1InputStream bIn             = new Asn1InputStream(input);
            Asn1Sequence    obj             = (Asn1Sequence)bIn.ReadObject();
            Pfx             bag             = new Pfx(obj);
            ContentInfo     info            = bag.AuthSafe;
            ArrayList       chain           = new ArrayList();
            bool            unmarkedKey     = false;
            bool            wrongPkcs12Zero = false;

            if (bag.MacData != null)           // check the mac code
            {
                MacData             mData = bag.MacData;
                DigestInfo          dInfo = mData.Mac;
                AlgorithmIdentifier algId = dInfo.AlgorithmID;
                byte[] salt    = mData.GetSalt();
                int    itCount = mData.IterationCount.IntValue;

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

                Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters(
                    algId.ObjectID, salt, itCount);
                ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters(
                    algId.ObjectID, password, parameters);
                IMac mac = (IMac)PbeUtilities.CreateEngine(algId.ObjectID);

                mac.Init(keyParameters);

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

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

                byte[] dig = dInfo.GetDigest();

                if (!Arrays.AreEqual(res, dig))
                {
                    if (password.Length > 0)
                    {
                        throw new Exception("Pkcs12 key store mac invalid - wrong password or corrupted file.");
                    }

                    //
                    // may be incorrect zero length password
                    //
                    keyParameters = PbeUtilities.GenerateCipherParameters(
                        algId.ObjectID, password, true, parameters);

                    mac.Init(keyParameters);

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

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

                    if (!Arrays.AreEqual(res, dig))
                    {
                        throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
                    }

                    wrongPkcs12Zero = true;
                }
            }

            keys     = new Hashtable();
            localIds = new Hashtable();

            if (info.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[]            octs     = ((Asn1OctetString)info.Content).GetOctets();
                AuthenticatedSafe authSafe = new AuthenticatedSafe(
                    (Asn1Sequence)Asn1OctetString.FromByteArray(octs));
                ContentInfo[] c = authSafe.GetContentInfo();

                for (int i = 0; i != c.Length; i++)
                {
                    if (c[i].ContentType.Equals(PkcsObjectIdentifiers.Data))
                    {
                        byte[]       octets = ((Asn1OctetString)c[i].Content).GetOctets();
                        Asn1Sequence seq    = (Asn1Sequence)Asn1Object.FromByteArray(octets);

                        for (int j = 0; j != seq.Count; j++)
                        {
                            SafeBag b = new SafeBag((Asn1Sequence)seq[j]);
                            if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn      = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo          privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                Hashtable          attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key  = new AsymmetricKeyEntry(privKey, attributes);
                                string             alias      = null;
                                Asn1OctetString    localId    = null;

                                if (b.BagAttributes != null)
                                {
                                    foreach (Asn1Sequence sq in b.BagAttributes)
                                    {
                                        DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                                        Asn1Set             attrSet = (Asn1Set)sq[1];
                                        Asn1Encodable       attr    = null;

                                        if (attrSet.Count > 0)
                                        {
                                            attr = attrSet[0];

                                            attributes.Add(aOid.Id, attr);
                                        }

                                        if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                        {
                                            alias       = ((DerBmpString)attr).GetString();
                                            keys[alias] = pkcs12Key;
                                        }
                                        else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                        {
                                            localId = (Asn1OctetString)attr;
                                        }
                                    }
                                }

                                if (localId != null)
                                {
                                    string name = Encoding.ASCII.GetString(Hex.Encode(localId.GetOctets()));

                                    if (alias == null)
                                    {
                                        keys[name] = pkcs12Key;
                                    }
                                    else
                                    {
                                        localIds[alias] = name;
                                    }
                                }
                                else
                                {
                                    unmarkedKey      = true;
                                    keys["unmarked"] = pkcs12Key;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.BagID);
                                Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else if (c[i].ContentType.Equals(PkcsObjectIdentifiers.EncryptedData))
                    {
                        EncryptedData d   = EncryptedData.GetInstance(c[i].Content);
                        Asn1Sequence  seq = DecryptData(d.EncryptionAlgorithm, d.Content.GetOctets(), password, wrongPkcs12Zero);

                        for (int j = 0; j != seq.Count; j++)
                        {
                            SafeBag b = new SafeBag((Asn1Sequence)seq[j]);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn      = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo          privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                Hashtable          attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key  = new AsymmetricKeyEntry(privKey, attributes);
                                string             alias      = null;
                                Asn1OctetString    localId    = null;

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                                    Asn1Set             attrSet = (Asn1Set)sq[1];
                                    Asn1Encodable       attr    = null;

                                    if (attrSet.Count > 0)
                                    {
                                        attr = attrSet[0];

                                        attributes.Add(aOid.Id, attr);
                                    }

                                    if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                    {
                                        alias       = ((DerBmpString)attr).GetString();
                                        keys[alias] = pkcs12Key;
                                    }
                                    else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                    {
                                        localId = (Asn1OctetString)attr;
                                    }
                                }

                                string name = Encoding.ASCII.GetString(Hex.Encode(localId.GetOctets()));

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    localIds[alias] = name;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                PrivateKeyInfo         privKeyInfo = PrivateKeyInfo.GetInstance(b.BagValue);
                                AsymmetricKeyParameter privKey     = PrivateKeyFactory.CreateKey(privKeyInfo);

                                //
                                // set the attributes on the key
                                //
                                string             alias      = null;
                                Asn1OctetString    localId    = null;
                                Hashtable          attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key  = new AsymmetricKeyEntry(privKey, attributes);

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                                    Asn1Set             attrSet = (Asn1Set)sq[1];
                                    Asn1Encodable       attr    = null;

                                    if (attrSet.Count > 0)
                                    {
                                        attr = attrSet[0];

                                        attributes.Add(aOid.Id, attr);
                                    }

                                    if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                    {
                                        alias       = ((DerBmpString)attr).GetString();
                                        keys[alias] = pkcs12Key;
                                    }
                                    else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                    {
                                        localId = (Asn1OctetString)attr;
                                    }
                                }

                                string name = Encoding.ASCII.GetString(Hex.Encode(localId.GetOctets()));

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    localIds[alias] = name;
                                }
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.BagID);
                                Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("extra " + c[i].ContentType.Id);
                        Console.WriteLine("extra " + Asn1Dump.DumpAsString(c[i].Content));
                    }
                }
            }

            certs      = new Hashtable();
            chainCerts = new Hashtable();
            keyCerts   = new Hashtable();

            for (int i = 0; i < chain.Count; ++i)
            {
                SafeBag         b      = (SafeBag)chain[i];
                CertBag         cb     = new CertBag((Asn1Sequence)b.BagValue);
                byte[]          octets = ((Asn1OctetString)cb.CertValue).GetOctets();
                X509Certificate cert   = new X509CertificateParser().ReadCertificate(octets);

                //
                // set the attributes
                //
                Hashtable            attributes = new Hashtable();
                X509CertificateEntry pkcs12Cert = new X509CertificateEntry(cert, attributes);
                Asn1OctetString      localId    = null;
                string alias = null;

                if (b.BagAttributes != null)
                {
                    foreach (Asn1Sequence sq in b.BagAttributes)
                    {
                        DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                        Asn1Set             attrSet = (Asn1Set)sq[1];

                        if (attrSet.Count > 0)
                        {
                            Asn1Encodable attr = attrSet[0];

                            attributes.Add(aOid.Id, attr);

                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                alias = ((DerBmpString)attr).GetString();
                            }
                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                localId = (Asn1OctetString)attr;
                            }
                        }
                    }
                }

                AsymmetricKeyParameter publicKey = cert.GetPublicKey();
                chainCerts[new CertId(publicKey)] = pkcs12Cert;

                if (unmarkedKey)
                {
                    if (keyCerts.Count == 0)
                    {
                        string name = Encoding.ASCII.GetString(
                            Hex.Encode(
                                new SubjectKeyIdentifier(
                                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey)).GetKeyIdentifier()));

                        keyCerts[name] = pkcs12Cert;

                        object temp = keys["unmarked"];
                        keys.Remove("unmarked");
                        keys[name] = temp;
                    }
                }
                else
                {
                    if (localId != null)
                    {
                        string name = Encoding.ASCII.GetString(
                            Hex.Encode(localId.GetOctets()));

                        keyCerts[name] = pkcs12Cert;
                    }

                    if (alias != null)
                    {
                        certs[alias] = pkcs12Cert;
                    }
                }
            }
        }
Пример #8
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);
        }
Пример #9
0
        public PKCS12Store(
            Stream input,
            char[] password)
        {
            if (password == null)
            {
                throw new ArgumentException("No password supplied for PKCS12Store.");
            }

            ASN1InputStream bIn         = new ASN1InputStream(input);
            ASN1Sequence    obj         = (ASN1Sequence)bIn.readObject();
            Pfx             bag         = new Pfx(obj);
            ContentInfo     info        = bag.getAuthSafe();
            ArrayList       chain       = new ArrayList();
            bool            unmarkedKey = false;

            if (bag.getMacData() != null)           // check the mac code
            {
                MemoryStream        bOut   = new MemoryStream();
                BEROutputStream     berOut = new BEROutputStream(bOut);
                MacData             mData  = bag.getMacData();
                DigestInfo          dInfo  = mData.getMac();
                AlgorithmIdentifier algId  = dInfo.getAlgorithmId();
                byte[] salt    = mData.getSalt();
                int    itCount = mData.getIterationCount().intValue();

                berOut.writeObject(info);

                byte[] data = ((ASN1OctetString)info.getContent()).getOctets();

                try
                {
                    ASN1Encodable    parameters    = PBEUtil.generateAlgorithmParameters(algId.getObjectId(), mData.getSalt(), mData.getIterationCount().intValue());
                    CipherParameters keyParameters = PBEUtil.generateCipherParameters(algId.getObjectId(), password, parameters);
                    Mac mac = (Mac)PBEUtil.createEngine(algId.getObjectId());

                    mac.init(keyParameters);

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

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

                    mac.doFinal(res, 0);

                    byte[] dig = dInfo.getDigest();

                    if (res.Length != dig.Length)
                    {
                        throw new Exception("PKCS12 key store mac invalid - wrong password or corrupted file.");
                    }

                    for (int i = 0; i != res.Length; i++)
                    {
                        if (res[i] != dig[i])
                        {
                            throw new Exception("PKCS12 key store mac invalid - wrong password or corrupted file.");
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new Exception("error constructing MAC: " + e.Message);
                }
            }

            keys     = new Hashtable();
            localIds = new Hashtable();

            if (info.getContentType().Equals(PKCSObjectIdentifiers.data))
            {
                bIn = new ASN1InputStream(new MemoryStream(((ASN1OctetString)info.getContent()).getOctets()));

                AuthenticatedSafe authSafe = new AuthenticatedSafe((ASN1Sequence)bIn.readObject());
                ContentInfo[]     c        = authSafe.getContentInfo();

                for (int i = 0; i != c.Length; i++)
                {
                    if (c[i].getContentType().Equals(PKCSObjectIdentifiers.data))
                    {
                        ASN1InputStream dIn = new ASN1InputStream(new MemoryStream(((ASN1OctetString)c[i].getContent()).getOctets()));
                        ASN1Sequence    seq = (ASN1Sequence)dIn.readObject();

                        for (int j = 0; j != seq.size(); j++)
                        {
                            SafeBag b = new SafeBag((ASN1Sequence)seq.getObjectAt(j));
                            if (b.getBagId().Equals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn      = EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
                                PrivateKeyInfo          privInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(password, 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.getBagAttributes() != null)
                                {
                                    IEnumerator e = b.getBagAttributes().getObjects();
                                    while (e.MoveNext())
                                    {
                                        ASN1Sequence        sq      = (ASN1Sequence)e.Current;
                                        DERObjectIdentifier aOid    = (DERObjectIdentifier)sq.getObjectAt(0);
                                        ASN1Set             attrSet = (ASN1Set)sq.getObjectAt(1);
                                        ASN1Encodable       attr    = null;

                                        if (attrSet.size() > 0)
                                        {
                                            attr = attrSet.getObjectAt(0);

                                            attributes.Add(aOid.getId(), attr);
                                        }

                                        if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_friendlyName))
                                        {
                                            alias = ((DERBMPString)attr).getString();
                                            keys.Add(alias, pkcs12Key);
                                        }
                                        else if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
                                        {
                                            localId = (ASN1OctetString)attr;
                                        }
                                    }
                                }

                                if (localId != null)
                                {
                                    String name = byteArrayToString(Hex.encode(localId.getOctets()));

                                    if (alias == null)
                                    {
                                        keys.Add(name, pkcs12Key);
                                    }
                                    else
                                    {
                                        localIds.Add(alias, name);
                                    }
                                }
                                else
                                {
                                    unmarkedKey = true;
                                    keys.Add("unmarked", privKey);
                                }
                            }
                            else if (b.getBagId().Equals(PKCSObjectIdentifiers.certBag))
                            {
                                chain.Add(b);
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.getBagId());
                                Console.WriteLine("extra " + ASN1Dump.dumpAsString(b));
                            }
                        }
                    }
                    else if (c[i].getContentType().Equals(PKCSObjectIdentifiers.encryptedData))
                    {
                        EncryptedData d   = new EncryptedData((ASN1Sequence)c[i].getContent());
                        ASN1Sequence  seq = decryptData(d.getEncryptionAlgorithm(), d.getContent().getOctets(), password);

                        for (int j = 0; j != seq.size(); j++)
                        {
                            SafeBag b = new SafeBag((ASN1Sequence)seq.getObjectAt(j));

                            if (b.getBagId().Equals(PKCSObjectIdentifiers.certBag))
                            {
                                chain.Add(b);
                            }
                            else if (b.getBagId().Equals(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn      = EncryptedPrivateKeyInfo.getInstance(b.getBagValue());
                                PrivateKeyInfo          privInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(password, 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;

                                IEnumerator e = b.getBagAttributes().getObjects();
                                while (e.MoveNext())
                                {
                                    ASN1Sequence        sq      = (ASN1Sequence)e.Current;
                                    DERObjectIdentifier aOid    = (DERObjectIdentifier)sq.getObjectAt(0);
                                    ASN1Set             attrSet = (ASN1Set)sq.getObjectAt(1);
                                    ASN1Encodable       attr    = null;

                                    if (attrSet.size() > 0)
                                    {
                                        attr = attrSet.getObjectAt(0);

                                        attributes.Add(aOid.getId(), attr);
                                    }

                                    if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_friendlyName))
                                    {
                                        alias = ((DERBMPString)attr).getString();
                                        keys.Add(alias, pkcs12Key);
                                    }
                                    else if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
                                    {
                                        localId = (ASN1OctetString)attr;
                                    }
                                }

                                String name = byteArrayToString(Hex.encode(localId.getOctets()));

                                if (alias == null)
                                {
                                    keys.Add(name, pkcs12Key);
                                }
                                else
                                {
                                    localIds.Add(alias, name);
                                }
                            }
                            else if (b.getBagId().Equals(PKCSObjectIdentifiers.keyBag))
                            {
                                PrivateKeyInfo         pIn     = PrivateKeyInfo.getInstance(b.getBagValue());
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(pIn);

                                //
                                // set the attributes on the key
                                //
                                String             alias      = null;
                                ASN1OctetString    localId    = null;
                                Hashtable          attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key  = new AsymmetricKeyEntry(privKey, attributes);

                                IEnumerator e = b.getBagAttributes().getObjects();
                                while (e.MoveNext())
                                {
                                    ASN1Sequence        sq      = (ASN1Sequence)e.Current;
                                    DERObjectIdentifier aOid    = (DERObjectIdentifier)sq.getObjectAt(0);
                                    ASN1Set             attrSet = (ASN1Set)sq.getObjectAt(1);
                                    ASN1Encodable       attr    = null;

                                    if (attrSet.size() > 0)
                                    {
                                        attr = attrSet.getObjectAt(0);

                                        attributes.Add(aOid.getId(), attr);
                                    }

                                    if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_friendlyName))
                                    {
                                        alias = ((DERBMPString)attr).getString();
                                        keys.Add(alias, pkcs12Key);
                                    }
                                    else if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
                                    {
                                        localId = (ASN1OctetString)attr;
                                    }
                                }

                                String name = byteArrayToString(Hex.encode(localId.getOctets()));

                                if (alias == null)
                                {
                                    keys.Add(name, pkcs12Key);
                                }
                                else
                                {
                                    localIds.Add(alias, name);
                                }
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.getBagId());
                                Console.WriteLine("extra " + ASN1Dump.dumpAsString(b));
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("extra " + c[i].getContentType().getId());
                        Console.WriteLine("extra " + ASN1Dump.dumpAsString(c[i].getContent()));
                    }
                }
            }

            certs      = new Hashtable();
            chainCerts = new Hashtable();
            keyCerts   = new Hashtable();

            for (int i = 0; i != chain.Count; i++)
            {
                SafeBag         b    = (SafeBag)chain[i];
                CertBag         cb   = new CertBag((ASN1Sequence)b.getBagValue());
                X509Certificate cert = new X509Certificate(((ASN1OctetString)cb.getCertValue()).getOctets());

                //
                // set the attributes
                //
                Hashtable            attributes = new Hashtable();
                X509CertificateEntry pkcs12cert = new X509CertificateEntry(cert, attributes);
                ASN1OctetString      localId    = null;
                String alias = null;

                if (b.getBagAttributes() != null)
                {
                    IEnumerator e = b.getBagAttributes().getObjects();
                    while (e.MoveNext())
                    {
                        ASN1Sequence        sq      = (ASN1Sequence)e.Current;
                        DERObjectIdentifier aOid    = (DERObjectIdentifier)sq.getObjectAt(0);
                        ASN1Set             attrSet = (ASN1Set)sq.getObjectAt(1);

                        if (attrSet.size() > 0)
                        {
                            ASN1Encodable attr = attrSet.getObjectAt(0);

                            attributes.Add(aOid.getId(), attr);

                            if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_friendlyName))
                            {
                                alias = ((DERBMPString)attr).getString();
                            }
                            else if (aOid.Equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
                            {
                                localId = (ASN1OctetString)attr;
                            }
                        }
                    }
                }

                chainCerts.Add(new CertId(cert.getPublicKey()), pkcs12cert);

                if (unmarkedKey)
                {
                    if (keyCerts.Count == 0)
                    {
                        String name = byteArrayToString(Hex.encode(new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(cert.getPublicKey())).getKeyIdentifier()));

                        keyCerts.Add(name, pkcs12cert);
                        keys.Add(name, keys["unmarked"]);

                        keys.Remove("unmarked");
                    }
                }
                else
                {
                    if (alias == null)
                    {
                        if (localId != null)
                        {
                            String name = byteArrayToString(Hex.encode(localId.getOctets()));

                            keyCerts.Add(name, pkcs12cert);
                        }
                    }
                    else
                    {
                        certs.Add(alias, pkcs12cert);
                    }
                }
            }
        }
Пример #10
0
        public void Save(Stream stream, char[] password, SecureRandom random)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }
            Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(new Asn1Encodable[0]);

            foreach (string text in this.keys.Keys)
            {
                byte[] array = new byte[20];
                random.NextBytes(array);
                AsymmetricKeyEntry  asymmetricKeyEntry = (AsymmetricKeyEntry)this.keys[text];
                DerObjectIdentifier oid;
                Asn1Encodable       asn1Encodable;
                if (password == null)
                {
                    oid           = PkcsObjectIdentifiers.KeyBag;
                    asn1Encodable = PrivateKeyInfoFactory.CreatePrivateKeyInfo(asymmetricKeyEntry.Key);
                }
                else
                {
                    oid           = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag;
                    asn1Encodable = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(this.keyAlgorithm, password, array, 1024, asymmetricKeyEntry.Key);
                }
                Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(new Asn1Encodable[0]);
                foreach (string text2 in asymmetricKeyEntry.BagAttributeKeys)
                {
                    Asn1Encodable obj = asymmetricKeyEntry[text2];
                    if (!text2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                    {
                        asn1EncodableVector2.Add(new Asn1Encodable[]
                        {
                            new DerSequence(new Asn1Encodable[]
                            {
                                new DerObjectIdentifier(text2),
                                new DerSet(obj)
                            })
                        });
                    }
                }
                asn1EncodableVector2.Add(new Asn1Encodable[]
                {
                    new DerSequence(new Asn1Encodable[]
                    {
                        PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                        new DerSet(new DerBmpString(text))
                    })
                });
                if (asymmetricKeyEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    X509CertificateEntry   certificate = this.GetCertificate(text);
                    AsymmetricKeyParameter publicKey   = certificate.Certificate.GetPublicKey();
                    SubjectKeyIdentifier   obj2        = Pkcs12Store.CreateSubjectKeyID(publicKey);
                    asn1EncodableVector2.Add(new Asn1Encodable[]
                    {
                        new DerSequence(new Asn1Encodable[]
                        {
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(obj2)
                        })
                    });
                }
                asn1EncodableVector.Add(new Asn1Encodable[]
                {
                    new SafeBag(oid, asn1Encodable.ToAsn1Object(), new DerSet(asn1EncodableVector2))
                });
            }
            byte[]      derEncoded  = new DerSequence(asn1EncodableVector).GetDerEncoded();
            ContentInfo contentInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded));

            byte[] array2 = new byte[20];
            random.NextBytes(array2);
            Asn1EncodableVector asn1EncodableVector3 = new Asn1EncodableVector(new Asn1Encodable[0]);
            Pkcs12PbeParams     pkcs12PbeParams      = new Pkcs12PbeParams(array2, 1024);
            AlgorithmIdentifier algorithmIdentifier  = new AlgorithmIdentifier(this.certAlgorithm, pkcs12PbeParams.ToAsn1Object());
            ISet set = new HashSet();

            foreach (string text3 in this.keys.Keys)
            {
                X509CertificateEntry certificate2        = this.GetCertificate(text3);
                CertBag             certBag              = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(certificate2.Certificate.GetEncoded()));
                Asn1EncodableVector asn1EncodableVector4 = new Asn1EncodableVector(new Asn1Encodable[0]);
                foreach (string text4 in certificate2.BagAttributeKeys)
                {
                    Asn1Encodable obj3 = certificate2[text4];
                    if (!text4.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                    {
                        asn1EncodableVector4.Add(new Asn1Encodable[]
                        {
                            new DerSequence(new Asn1Encodable[]
                            {
                                new DerObjectIdentifier(text4),
                                new DerSet(obj3)
                            })
                        });
                    }
                }
                asn1EncodableVector4.Add(new Asn1Encodable[]
                {
                    new DerSequence(new Asn1Encodable[]
                    {
                        PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                        new DerSet(new DerBmpString(text3))
                    })
                });
                if (certificate2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    AsymmetricKeyParameter publicKey2 = certificate2.Certificate.GetPublicKey();
                    SubjectKeyIdentifier   obj4       = Pkcs12Store.CreateSubjectKeyID(publicKey2);
                    asn1EncodableVector4.Add(new Asn1Encodable[]
                    {
                        new DerSequence(new Asn1Encodable[]
                        {
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(obj4)
                        })
                    });
                }
                asn1EncodableVector3.Add(new Asn1Encodable[]
                {
                    new SafeBag(PkcsObjectIdentifiers.CertBag, certBag.ToAsn1Object(), new DerSet(asn1EncodableVector4))
                });
                set.Add(certificate2.Certificate);
            }
            foreach (string text5 in this.certs.Keys)
            {
                X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)this.certs[text5];
                if (this.keys[text5] == null)
                {
                    CertBag             certBag2             = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry.Certificate.GetEncoded()));
                    Asn1EncodableVector asn1EncodableVector5 = new Asn1EncodableVector(new Asn1Encodable[0]);
                    foreach (string text6 in x509CertificateEntry.BagAttributeKeys)
                    {
                        if (!text6.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                        {
                            Asn1Encodable obj5 = x509CertificateEntry[text6];
                            if (!text6.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                            {
                                asn1EncodableVector5.Add(new Asn1Encodable[]
                                {
                                    new DerSequence(new Asn1Encodable[]
                                    {
                                        new DerObjectIdentifier(text6),
                                        new DerSet(obj5)
                                    })
                                });
                            }
                        }
                    }
                    asn1EncodableVector5.Add(new Asn1Encodable[]
                    {
                        new DerSequence(new Asn1Encodable[]
                        {
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(text5))
                        })
                    });
                    asn1EncodableVector3.Add(new Asn1Encodable[]
                    {
                        new SafeBag(PkcsObjectIdentifiers.CertBag, certBag2.ToAsn1Object(), new DerSet(asn1EncodableVector5))
                    });
                    set.Add(x509CertificateEntry.Certificate);
                }
            }
            foreach (Pkcs12Store.CertId key in this.chainCerts.Keys)
            {
                X509CertificateEntry x509CertificateEntry2 = (X509CertificateEntry)this.chainCerts[key];
                if (!set.Contains(x509CertificateEntry2.Certificate))
                {
                    CertBag             certBag3             = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry2.Certificate.GetEncoded()));
                    Asn1EncodableVector asn1EncodableVector6 = new Asn1EncodableVector(new Asn1Encodable[0]);
                    foreach (string text7 in x509CertificateEntry2.BagAttributeKeys)
                    {
                        if (!text7.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                        {
                            asn1EncodableVector6.Add(new Asn1Encodable[]
                            {
                                new DerSequence(new Asn1Encodable[]
                                {
                                    new DerObjectIdentifier(text7),
                                    new DerSet(x509CertificateEntry2[text7])
                                })
                            });
                        }
                    }
                    asn1EncodableVector3.Add(new Asn1Encodable[]
                    {
                        new SafeBag(PkcsObjectIdentifiers.CertBag, certBag3.ToAsn1Object(), new DerSet(asn1EncodableVector6))
                    });
                }
            }
            byte[]      derEncoded2 = new DerSequence(asn1EncodableVector3).GetDerEncoded();
            ContentInfo contentInfo2;

            if (password == null)
            {
                contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded2));
            }
            else
            {
                byte[]        str           = Pkcs12Store.CryptPbeData(true, algorithmIdentifier, password, false, derEncoded2);
                EncryptedData encryptedData = new EncryptedData(PkcsObjectIdentifiers.Data, algorithmIdentifier, new BerOctetString(str));
                contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, encryptedData.ToAsn1Object());
            }
            ContentInfo[] info = new ContentInfo[]
            {
                contentInfo,
                contentInfo2
            };
            byte[]      encoded      = new AuthenticatedSafe(info).GetEncoded(this.useDerEncoding ? "DER" : "BER");
            ContentInfo contentInfo3 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encoded));
            MacData     macData      = null;

            if (password != null)
            {
                byte[] array3 = new byte[20];
                random.NextBytes(array3);
                byte[] digest               = Pkcs12Store.CalculatePbeMac(OiwObjectIdentifiers.IdSha1, array3, 1024, password, false, encoded);
                AlgorithmIdentifier algID   = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
                DigestInfo          digInfo = new DigestInfo(algID, digest);
                macData = new MacData(digInfo, array3, 1024);
            }
            Pfx             obj6 = new Pfx(contentInfo3, macData);
            DerOutputStream derOutputStream;

            if (this.useDerEncoding)
            {
                derOutputStream = new DerOutputStream(stream);
            }
            else
            {
                derOutputStream = new BerOutputStream(stream);
            }
            derOutputStream.WriteObject(obj6);
        }
Пример #11
0
        public void Load(Stream input, char[] password)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            Asn1Sequence seq             = (Asn1Sequence)Asn1Object.FromStream(input);
            Pfx          pfx             = new Pfx(seq);
            ContentInfo  authSafe        = pfx.AuthSafe;
            bool         wrongPkcs12Zero = false;

            if (password != null && pfx.MacData != null)
            {
                MacData             macData     = pfx.MacData;
                DigestInfo          mac         = macData.Mac;
                AlgorithmIdentifier algorithmID = mac.AlgorithmID;
                byte[] salt     = macData.GetSalt();
                int    intValue = macData.IterationCount.IntValue;
                byte[] octets   = ((Asn1OctetString)authSafe.Content).GetOctets();
                byte[] a        = Pkcs12Store.CalculatePbeMac(algorithmID.ObjectID, salt, intValue, password, false, octets);
                byte[] digest   = mac.GetDigest();
                if (!Arrays.ConstantTimeAreEqual(a, digest))
                {
                    if (password.Length > 0)
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }
                    a = Pkcs12Store.CalculatePbeMac(algorithmID.ObjectID, salt, intValue, password, true, octets);
                    if (!Arrays.ConstantTimeAreEqual(a, digest))
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }
                    wrongPkcs12Zero = true;
                }
            }
            this.keys.Clear();
            this.localIds.Clear();
            this.unmarkedKeyEntry = null;
            IList list = Platform.CreateArrayList();

            if (authSafe.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[]            octets2           = ((Asn1OctetString)authSafe.Content).GetOctets();
                AuthenticatedSafe authenticatedSafe = new AuthenticatedSafe((Asn1Sequence)Asn1Object.FromByteArray(octets2));
                ContentInfo[]     contentInfo       = authenticatedSafe.GetContentInfo();
                ContentInfo[]     array             = contentInfo;
                for (int i = 0; i < array.Length; i++)
                {
                    ContentInfo         contentInfo2 = array[i];
                    DerObjectIdentifier contentType  = contentInfo2.ContentType;
                    byte[] array2 = null;
                    if (contentType.Equals(PkcsObjectIdentifiers.Data))
                    {
                        array2 = ((Asn1OctetString)contentInfo2.Content).GetOctets();
                    }
                    else if (contentType.Equals(PkcsObjectIdentifiers.EncryptedData) && password != null)
                    {
                        EncryptedData instance = EncryptedData.GetInstance(contentInfo2.Content);
                        array2 = Pkcs12Store.CryptPbeData(false, instance.EncryptionAlgorithm, password, wrongPkcs12Zero, instance.Content.GetOctets());
                    }
                    if (array2 != null)
                    {
                        Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(array2);
                        foreach (Asn1Sequence seq2 in asn1Sequence)
                        {
                            SafeBag safeBag = new SafeBag(seq2);
                            if (safeBag.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                list.Add(safeBag);
                            }
                            else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                this.LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes, password, wrongPkcs12Zero);
                            }
                            else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                this.LoadKeyBag(PrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes);
                            }
                        }
                    }
                }
            }
            this.certs.Clear();
            this.chainCerts.Clear();
            this.keyCerts.Clear();
            foreach (SafeBag safeBag2 in list)
            {
                CertBag         certBag         = new CertBag((Asn1Sequence)safeBag2.BagValue);
                byte[]          octets3         = ((Asn1OctetString)certBag.CertValue).GetOctets();
                X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(octets3);
                IDictionary     dictionary      = Platform.CreateHashtable();
                Asn1OctetString asn1OctetString = null;
                string          text            = null;
                if (safeBag2.BagAttributes != null)
                {
                    foreach (Asn1Sequence asn1Sequence2 in safeBag2.BagAttributes)
                    {
                        DerObjectIdentifier instance2 = DerObjectIdentifier.GetInstance(asn1Sequence2[0]);
                        Asn1Set             instance3 = Asn1Set.GetInstance(asn1Sequence2[1]);
                        if (instance3.Count > 0)
                        {
                            Asn1Encodable asn1Encodable = instance3[0];
                            if (dictionary.Contains(instance2.Id))
                            {
                                if (!dictionary[instance2.Id].Equals(asn1Encodable))
                                {
                                    throw new IOException("attempt to add existing attribute with different value");
                                }
                            }
                            else
                            {
                                dictionary.Add(instance2.Id, asn1Encodable);
                            }
                            if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                text = ((DerBmpString)asn1Encodable).GetString();
                            }
                            else if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                asn1OctetString = (Asn1OctetString)asn1Encodable;
                            }
                        }
                    }
                }
                Pkcs12Store.CertId   certId = new Pkcs12Store.CertId(x509Certificate.GetPublicKey());
                X509CertificateEntry value  = new X509CertificateEntry(x509Certificate, dictionary);
                this.chainCerts[certId] = value;
                if (this.unmarkedKeyEntry != null)
                {
                    if (this.keyCerts.Count == 0)
                    {
                        string text2 = Hex.ToHexString(certId.Id);
                        this.keyCerts[text2] = value;
                        this.keys[text2]     = this.unmarkedKeyEntry;
                    }
                }
                else
                {
                    if (asn1OctetString != null)
                    {
                        string key = Hex.ToHexString(asn1OctetString.GetOctets());
                        this.keyCerts[key] = value;
                    }
                    if (text != null)
                    {
                        this.certs[text] = value;
                    }
                }
            }
        }