コード例 #1
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);
                    }
                }
            }
        }