// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.jcajce.provider.keystore.pkcs12;

import java.util.Collections;
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers;
import org.bouncycastle.util.Integers;
import java.util.HashMap;
import java.util.Map;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.provider.keystore.util.AdaptingKeyStoreSpi;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import javax.crypto.Mac;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.util.Strings;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.asn1.pkcs.PBMAC1Params;
import java.util.HashSet;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers;
import java.util.Set;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.pkcs.KeyDerivationFunc;
import org.bouncycastle.asn1.BEROctetString;
import org.bouncycastle.asn1.BERSequence;
import org.bouncycastle.asn1.DERSequence;
import java.security.cert.CertificateEncodingException;
import org.bouncycastle.asn1.ASN1EncodableVector;
import java.io.OutputStream;
import org.bouncycastle.jce.provider.JDKPKCS12StoreParameter;
import org.bouncycastle.jcajce.PKCS12StoreParameter;
import org.bouncycastle.internal.asn1.cms.GCMParameters;
import org.bouncycastle.asn1.DEROctetString;
import java.math.BigInteger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
import org.bouncycastle.asn1.x509.DigestInfo;
import org.bouncycastle.asn1.pkcs.MacData;
import org.bouncycastle.asn1.pkcs.ContentInfo;
import org.bouncycastle.util.Properties;
import org.bouncycastle.asn1.ASN1BMPString;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.asn1.ASN1Set;
import java.io.ByteArrayInputStream;
import org.bouncycastle.asn1.pkcs.CertBag;
import org.bouncycastle.asn1.pkcs.EncryptedData;
import org.bouncycastle.asn1.util.ASN1Dump;
import org.bouncycastle.asn1.pkcs.SafeBag;
import org.bouncycastle.asn1.pkcs.AuthenticatedSafe;
import org.bouncycastle.asn1.pkcs.Pfx;
import org.bouncycastle.asn1.ASN1InputStream;
import java.io.EOFException;
import java.io.BufferedInputStream;
import java.security.cert.CertificateException;
import org.bouncycastle.jcajce.provider.keystore.util.ParameterUtil;
import org.bouncycastle.jcajce.BCLoadStoreParameter;
import java.security.KeyStore;
import java.security.NoSuchProviderException;
import java.security.InvalidAlgorithmParameterException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import java.security.spec.InvalidKeySpecException;
import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
import org.bouncycastle.asn1.cryptopro.GOST28147Parameters;
import org.bouncycastle.asn1.ASN1Sequence;
import javax.crypto.spec.IvParameterSpec;
import org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
import org.bouncycastle.asn1.pkcs.PBES2Parameters;
import org.bouncycastle.util.Arrays;
import java.security.AlgorithmParameters;
import org.bouncycastle.asn1.pkcs.PBKDF2Params;
import org.bouncycastle.asn1.pkcs.EncryptionScheme;
import javax.crypto.SecretKeyFactory;
import java.security.spec.KeySpec;
import org.bouncycastle.util.BigIntegers;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.Cipher;
import java.security.InvalidKeyException;
import org.bouncycastle.util.Exceptions;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.jcajce.PKCS12Key;
import javax.crypto.spec.PBEParameterSpec;
import org.bouncycastle.asn1.pkcs.PKCS12PBEParams;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.security.Principal;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.x509.Extension;
import java.security.cert.X509Certificate;
import java.util.Vector;
import java.security.KeyStoreException;
import java.security.Key;
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.io.IOException;
import java.io.InputStream;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.util.DigestFactory;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import java.security.PublicKey;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import java.security.cert.CertificateFactory;
import java.security.SecureRandom;
import java.util.Hashtable;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.interfaces.BCKeyStore;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import java.security.KeyStoreSpi;

public class PKCS12KeyStoreSpi extends KeyStoreSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore
{
    static final String PKCS12_MAX_IT_COUNT_PROPERTY = "org.bouncycastle.pkcs12.max_it_count";
    private final JcaJceHelper helper;
    private static final int SALT_SIZE = 20;
    private static final int MIN_ITERATIONS = 51200;
    private static final DefaultSecretKeyProvider keySizeProvider;
    private IgnoresCaseHashtable keys;
    private IgnoresCaseHashtable localIds;
    private IgnoresCaseHashtable certs;
    private Hashtable chainCerts;
    private Hashtable keyCerts;
    static final int NULL = 0;
    static final int CERTIFICATE = 1;
    static final int KEY = 2;
    static final int SECRET = 3;
    static final int SEALED = 4;
    static final int KEY_PRIVATE = 0;
    static final int KEY_PUBLIC = 1;
    static final int KEY_SECRET = 2;
    protected SecureRandom random;
    private CertificateFactory certFact;
    private ASN1ObjectIdentifier keyAlgorithm;
    private ASN1ObjectIdentifier certAlgorithm;
    private AlgorithmIdentifier macAlgorithm;
    private int itCount;
    private int saltLength;
    
    private static boolean isPBKDF2(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        return asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes256_CBC) || asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes256_GCM) || asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes128_CBC) || asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes128_GCM);
    }
    
    private static int getKeyLength(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        if (asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes256_CBC) || asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes256_GCM)) {
            return 32;
        }
        return 16;
    }
    
    public PKCS12KeyStoreSpi(final JcaJceHelper jcaJceHelper, final ASN1ObjectIdentifier keyAlgorithm, final ASN1ObjectIdentifier certAlgorithm) {
        this.helper = new BCJcaJceHelper();
        this.keys = new IgnoresCaseHashtable();
        this.localIds = new IgnoresCaseHashtable();
        this.certs = new IgnoresCaseHashtable();
        this.chainCerts = new Hashtable();
        this.keyCerts = new Hashtable();
        this.random = CryptoServicesRegistrar.getSecureRandom();
        this.macAlgorithm = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
        this.itCount = 102400;
        this.saltLength = 20;
        this.keyAlgorithm = keyAlgorithm;
        this.certAlgorithm = certAlgorithm;
        try {
            this.certFact = jcaJceHelper.createCertificateFactory("X.509");
        }
        catch (final Exception ex) {
            throw new IllegalArgumentException("can't create cert factory - " + ex.toString());
        }
    }
    
    private SubjectKeyIdentifier createSubjectKeyId(final PublicKey publicKey) {
        try {
            return new SubjectKeyIdentifier(getDigest(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())));
        }
        catch (final Exception ex) {
            throw new RuntimeException("error creating key");
        }
    }
    
    private static byte[] getDigest(final SubjectPublicKeyInfo subjectPublicKeyInfo) {
        final Digest sha1 = DigestFactory.createSHA1();
        final byte[] array = new byte[sha1.getDigestSize()];
        final byte[] bytes = subjectPublicKeyInfo.getPublicKeyData().getBytes();
        sha1.update(bytes, 0, bytes.length);
        sha1.doFinal(array, 0);
        return array;
    }
    
    @Override
    public void setRandom(final SecureRandom random) {
        this.random = random;
    }
    
    @Override
    public boolean engineProbe(final InputStream inputStream) throws IOException {
        return false;
    }
    
    @Override
    public Enumeration engineAliases() {
        final Hashtable hashtable = new Hashtable();
        final Enumeration keys = this.certs.keys();
        while (keys.hasMoreElements()) {
            hashtable.put(keys.nextElement(), "cert");
        }
        final Enumeration keys2 = this.keys.keys();
        while (keys2.hasMoreElements()) {
            final String s = keys2.nextElement();
            if (hashtable.get(s) == null) {
                hashtable.put(s, "key");
            }
        }
        return hashtable.keys();
    }
    
    @Override
    public boolean engineContainsAlias(final String s) {
        return this.certs.get(s) != null || this.keys.get(s) != null;
    }
    
    @Override
    public void engineDeleteEntry(final String s) throws KeyStoreException {
        final Certificate certificate = (Certificate)this.certs.remove(s);
        if (certificate != null) {
            this.chainCerts.remove(new CertId(certificate.getPublicKey()));
        }
        if (this.keys.remove(s) != null) {
            final String key = (String)this.localIds.remove(s);
            if (key != null) {
                final Certificate certificate2 = this.keyCerts.remove(key);
                if (certificate2 != null) {
                    this.chainCerts.remove(new CertId(certificate2.getPublicKey()));
                }
            }
        }
    }
    
    @Override
    public Certificate engineGetCertificate(final String key) {
        if (key == null) {
            throw new IllegalArgumentException("null alias passed to getCertificate.");
        }
        Certificate certificate = (Certificate)this.certs.get(key);
        if (certificate == null) {
            final String key2 = (String)this.localIds.get(key);
            if (key2 != null) {
                certificate = (Certificate)this.keyCerts.get(key2);
            }
            else {
                certificate = this.keyCerts.get(key);
            }
        }
        return certificate;
    }
    
    @Override
    public String engineGetCertificateAlias(final Certificate certificate) {
        final Enumeration elements = this.certs.elements();
        final Enumeration keys = this.certs.keys();
        while (elements.hasMoreElements()) {
            final Certificate certificate2 = elements.nextElement();
            final String s = keys.nextElement();
            if (certificate2.equals(certificate)) {
                return s;
            }
        }
        final Enumeration elements2 = this.keyCerts.elements();
        final Enumeration keys2 = this.keyCerts.keys();
        while (elements2.hasMoreElements()) {
            final Certificate certificate3 = (Certificate)elements2.nextElement();
            final String s2 = (String)keys2.nextElement();
            if (certificate3.equals(certificate)) {
                return s2;
            }
        }
        return null;
    }
    
    @Override
    public Certificate[] engineGetCertificateChain(final String s) {
        if (s == null) {
            throw new IllegalArgumentException("null alias passed to getCertificateChain.");
        }
        if (!this.engineIsKeyEntry(s)) {
            return null;
        }
        Certificate engineGetCertificate = this.engineGetCertificate(s);
        if (engineGetCertificate != null) {
            final Vector vector = new Vector();
            while (engineGetCertificate != null) {
                final X509Certificate x509Certificate = (X509Certificate)engineGetCertificate;
                Certificate certificate = null;
                final byte[] extensionValue = x509Certificate.getExtensionValue(Extension.authorityKeyIdentifier.getId());
                if (extensionValue != null) {
                    final byte[] keyIdentifierOctets = AuthorityKeyIdentifier.getInstance(ASN1OctetString.getInstance(extensionValue).getOctets()).getKeyIdentifierOctets();
                    if (null != keyIdentifierOctets) {
                        certificate = (Certificate)this.chainCerts.get(new CertId(keyIdentifierOctets));
                    }
                }
                if (certificate == null) {
                    final Principal issuerDN = x509Certificate.getIssuerDN();
                    if (!issuerDN.equals(x509Certificate.getSubjectDN())) {
                        final Enumeration keys = this.chainCerts.keys();
                        while (keys.hasMoreElements()) {
                            final X509Certificate x509Certificate2 = this.chainCerts.get(keys.nextElement());
                            if (x509Certificate2.getSubjectDN().equals(issuerDN)) {
                                try {
                                    x509Certificate.verify(x509Certificate2.getPublicKey());
                                    certificate = x509Certificate2;
                                    break;
                                }
                                catch (final Exception ex) {}
                            }
                        }
                    }
                }
                if (vector.contains(engineGetCertificate)) {
                    engineGetCertificate = null;
                }
                else {
                    vector.addElement(engineGetCertificate);
                    if (certificate != engineGetCertificate) {
                        engineGetCertificate = certificate;
                    }
                    else {
                        engineGetCertificate = null;
                    }
                }
            }
            final Certificate[] array = new Certificate[vector.size()];
            for (int i = 0; i != array.length; ++i) {
                array[i] = (Certificate)vector.elementAt(i);
            }
            return array;
        }
        return null;
    }
    
    @Override
    public Date engineGetCreationDate(final String s) {
        if (s == null) {
            throw new NullPointerException("alias == null");
        }
        if (this.keys.get(s) == null && this.certs.get(s) == null) {
            return null;
        }
        return new Date();
    }
    
    @Override
    public Key engineGetKey(final String s, final char[] array) throws NoSuchAlgorithmException, UnrecoverableKeyException {
        if (s == null) {
            throw new IllegalArgumentException("null alias passed to getKey.");
        }
        return (Key)this.keys.get(s);
    }
    
    @Override
    public boolean engineIsCertificateEntry(final String s) {
        return this.certs.get(s) != null && this.keys.get(s) == null;
    }
    
    @Override
    public boolean engineIsKeyEntry(final String s) {
        return this.keys.get(s) != null;
    }
    
    @Override
    public void engineSetCertificateEntry(final String str, final Certificate value) throws KeyStoreException {
        if (this.keys.get(str) != null) {
            throw new KeyStoreException("There is a key entry with the name " + str + ".");
        }
        this.certs.put(str, value);
        this.chainCerts.put(new CertId(value.getPublicKey()), value);
    }
    
    @Override
    public void engineSetKeyEntry(final String s, final byte[] array, final Certificate[] array2) throws KeyStoreException {
        throw new RuntimeException("operation not supported");
    }
    
    @Override
    public void engineSetKeyEntry(final String s, final Key key, final char[] array, final Certificate[] array2) throws KeyStoreException {
        if (!(key instanceof PrivateKey)) {
            throw new KeyStoreException("PKCS12 does not support non-PrivateKeys");
        }
        if (key instanceof PrivateKey && array2 == null) {
            throw new KeyStoreException("no certificate chain for private key");
        }
        if (this.keys.get(s) != null) {
            this.engineDeleteEntry(s);
        }
        this.keys.put(s, key);
        if (array2 != null) {
            this.certs.put(s, array2[0]);
            for (int i = 0; i != array2.length; ++i) {
                this.chainCerts.put(new CertId(array2[i].getPublicKey()), array2[i]);
            }
        }
    }
    
    @Override
    public int engineSize() {
        final Hashtable hashtable = new Hashtable();
        final Enumeration keys = this.certs.keys();
        while (keys.hasMoreElements()) {
            hashtable.put(keys.nextElement(), "cert");
        }
        final Enumeration keys2 = this.keys.keys();
        while (keys2.hasMoreElements()) {
            final String s = keys2.nextElement();
            if (hashtable.get(s) == null) {
                hashtable.put(s, "key");
            }
        }
        return hashtable.size();
    }
    
    protected PrivateKey unwrapKey(final AlgorithmIdentifier algorithmIdentifier, final byte[] array, final char[] array2, final boolean b) throws IOException {
        final ASN1ObjectIdentifier algorithm = algorithmIdentifier.getAlgorithm();
        try {
            if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) {
                final PKCS12PBEParams instance = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters());
                final PBEParameterSpec params = new PBEParameterSpec(instance.getIV(), this.validateIterationCount(instance.getIterations()));
                final Cipher cipher = this.helper.createCipher(algorithm.getId());
                cipher.init(4, new PKCS12Key(array2, b), params);
                return (PrivateKey)cipher.unwrap(array, "", 2);
            }
            if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2)) {
                return (PrivateKey)this.createCipher(4, array2, algorithmIdentifier).unwrap(array, "", 2);
            }
        }
        catch (final InvalidKeyException ex) {
            throw Exceptions.ioException("exception unwrapping private key:" + ex.getMessage(), new UnrecoverableKeyException(ex.toString()));
        }
        catch (final Exception ex2) {
            throw Exceptions.ioException("exception unwrapping private key: " + ex2.getMessage(), ex2);
        }
        throw new IOException("exception unwrapping private key - cannot recognise: " + algorithm);
    }
    
    protected byte[] wrapKey(final String s, final Key key, final PKCS12PBEParams pkcs12PBEParams, final char[] password) throws IOException {
        final PBEKeySpec keySpec = new PBEKeySpec(password);
        byte[] wrap;
        try {
            final SecretKeyFactory secretKeyFactory = this.helper.createSecretKeyFactory(s);
            final PBEParameterSpec params = new PBEParameterSpec(pkcs12PBEParams.getIV(), BigIntegers.intValueExact(pkcs12PBEParams.getIterations()));
            final Cipher cipher = this.helper.createCipher(s);
            cipher.init(3, secretKeyFactory.generateSecret(keySpec), params);
            wrap = cipher.wrap(key);
        }
        catch (final Exception ex) {
            throw new IOException("exception encrypting data - " + ex.toString());
        }
        return wrap;
    }
    
    protected byte[] wrapKey(final EncryptionScheme encryptionScheme, final Key key, final PBKDF2Params pbkdf2Params, final char[] password) throws IOException {
        final PBEKeySpec keySpec = new PBEKeySpec(password, pbkdf2Params.getSalt(), BigIntegers.intValueExact(pbkdf2Params.getIterationCount()), BigIntegers.intValueExact(pbkdf2Params.getKeyLength()) * 8);
        byte[] wrap;
        try {
            final SecretKeyFactory secretKeyFactory = this.helper.createSecretKeyFactory("PBKDF2withHMacSHA256");
            final Cipher cipher = this.helper.createCipher(encryptionScheme.getAlgorithm().getId());
            final AlgorithmParameters instance = AlgorithmParameters.getInstance(encryptionScheme.getAlgorithm().getId());
            instance.init(encryptionScheme.getParameters().toASN1Primitive().getEncoded());
            cipher.init(3, secretKeyFactory.generateSecret(keySpec), instance);
            wrap = cipher.wrap(key);
        }
        catch (final Exception ex) {
            throw new IOException("exception encrypting data - " + ex.toString());
        }
        return wrap;
    }
    
    protected byte[] cryptData(final boolean b, final AlgorithmIdentifier algorithmIdentifier, final char[] array, final boolean b2, final byte[] array2) throws IOException {
        final ASN1ObjectIdentifier algorithm = algorithmIdentifier.getAlgorithm();
        final int opmode = b ? 1 : 2;
        if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds)) {
            final PKCS12PBEParams instance = PKCS12PBEParams.getInstance(algorithmIdentifier.getParameters());
            final PKCS12Key key = new PKCS12Key(array, b2);
            try {
                final PBEParameterSpec params = new PBEParameterSpec(instance.getIV(), BigIntegers.intValueExact(instance.getIterations()));
                final Cipher cipher = this.helper.createCipher(algorithm.getId());
                cipher.init(opmode, key, params);
                return cipher.doFinal(array2);
            }
            catch (final Exception ex) {
                throw new IOException("exception decrypting data - " + ex.toString());
            }
            finally {
                Arrays.clear(key.getPassword());
            }
        }
        if (algorithm.equals(PKCSObjectIdentifiers.id_PBES2)) {
            try {
                return this.createCipher(opmode, array, algorithmIdentifier).doFinal(array2);
            }
            catch (final Exception ex2) {
                throw new IOException("exception decrypting data - " + ex2.toString());
            }
        }
        throw new IOException("unknown PBE algorithm: " + algorithm);
    }
    
    private Cipher createCipher(final int opmode, final char[] password, final AlgorithmIdentifier algorithmIdentifier) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException {
        final PBES2Parameters instance = PBES2Parameters.getInstance(algorithmIdentifier.getParameters());
        final PBKDF2Params instance2 = PBKDF2Params.getInstance(instance.getKeyDerivationFunc().getParameters());
        final AlgorithmIdentifier instance3 = AlgorithmIdentifier.getInstance(instance.getEncryptionScheme());
        final SecretKeyFactory secretKeyFactory = this.helper.createSecretKeyFactory(instance.getKeyDerivationFunc().getAlgorithm().getId());
        SecretKey key;
        if (instance2.isDefaultPrf()) {
            key = secretKeyFactory.generateSecret(new PBEKeySpec(password, instance2.getSalt(), this.validateIterationCount(instance2.getIterationCount()), PKCS12KeyStoreSpi.keySizeProvider.getKeySize(instance3)));
        }
        else {
            key = secretKeyFactory.generateSecret(new PBKDF2KeySpec(password, instance2.getSalt(), this.validateIterationCount(instance2.getIterationCount()), PKCS12KeyStoreSpi.keySizeProvider.getKeySize(instance3), instance2.getPrf()));
        }
        final Cipher cipher = this.helper.createCipher(instance.getEncryptionScheme().getAlgorithm().getId());
        final ASN1Encodable parameters = instance.getEncryptionScheme().getParameters();
        if (parameters instanceof ASN1OctetString) {
            cipher.init(opmode, key, new IvParameterSpec(ASN1OctetString.getInstance(parameters).getOctets()));
        }
        else {
            final ASN1Sequence instance4 = ASN1Sequence.getInstance(parameters);
            if (instance4.getObjectAt(1) instanceof ASN1ObjectIdentifier) {
                final GOST28147Parameters instance5 = GOST28147Parameters.getInstance(parameters);
                cipher.init(opmode, key, new GOST28147ParameterSpec(instance5.getEncryptionParamSet(), instance5.getIV()));
            }
            else {
                final AlgorithmParameters instance6 = AlgorithmParameters.getInstance(instance3.getAlgorithm().getId(), "BC");
                try {
                    instance6.init(instance4.getEncoded());
                }
                catch (final IOException ex) {
                    throw new InvalidKeySpecException(ex.getMessage());
                }
                cipher.init(opmode, key, instance6);
            }
        }
        return cipher;
    }
    
    @Override
    public void engineLoad(final KeyStore.LoadStoreParameter loadStoreParameter) throws IOException, NoSuchAlgorithmException, CertificateException {
        if (loadStoreParameter == null) {
            this.engineLoad(null, (char[])null);
        }
        else {
            if (!(loadStoreParameter instanceof BCLoadStoreParameter)) {
                throw new IllegalArgumentException("no support for 'param' of type " + loadStoreParameter.getClass().getName());
            }
            this.engineLoad(((BCLoadStoreParameter)loadStoreParameter).getInputStream(), ParameterUtil.extractPassword(loadStoreParameter));
        }
    }
    
    @Override
    public void engineLoad(final InputStream in, final char[] array) throws IOException {
        if (in == null) {
            return;
        }
        boolean b = true;
        boolean b2 = true;
        final BufferedInputStream bufferedInputStream = new BufferedInputStream(in);
        bufferedInputStream.mark(10);
        final int read = bufferedInputStream.read();
        if (read < 0) {
            throw new EOFException("no data in keystore stream");
        }
        if (read != 48) {
            throw new IOException("stream does not represent a PKCS12 key store");
        }
        bufferedInputStream.reset();
        final ASN1InputStream asn1InputStream = new ASN1InputStream(bufferedInputStream);
        Pfx instance;
        try {
            instance = Pfx.getInstance(asn1InputStream.readObject());
        }
        catch (final Exception ex) {
            throw new IOException(ex.getMessage());
        }
        final ContentInfo authSafe = instance.getAuthSafe();
        final Vector vector = new Vector();
        boolean b3 = false;
        boolean b4 = false;
        if (instance.getMacData() != null) {
            if (array == null) {
                throw new NullPointerException("no password supplied when one expected");
            }
            b = false;
            final MacData macData = instance.getMacData();
            final DigestInfo mac = macData.getMac();
            this.macAlgorithm = mac.getAlgorithmId();
            final byte[] salt = macData.getSalt();
            this.itCount = this.validateIterationCount(macData.getIterationCount());
            this.saltLength = salt.length;
            final byte[] octets = ((ASN1OctetString)authSafe.getContent()).getOctets();
            try {
                final byte[] calculatePbeMac = this.calculatePbeMac(this.macAlgorithm.getAlgorithm(), salt, this.itCount, array, false, octets);
                final byte[] digest = mac.getDigest();
                if (!Arrays.constantTimeAreEqual(calculatePbeMac, digest)) {
                    if (array.length > 0) {
                        throw Exceptions.ioException("PKCS12 key store mac invalid - wrong password or corrupted file", new UnrecoverableKeyException("PKCS12 key store mac invalid"));
                    }
                    if (!Arrays.constantTimeAreEqual(this.calculatePbeMac(this.macAlgorithm.getAlgorithm(), salt, this.itCount, array, true, octets), digest)) {
                        throw Exceptions.ioException("PKCS12 key store mac invalid - wrong password or corrupted file", new UnrecoverableKeyException("PKCS12 key store mac invalid"));
                    }
                    b4 = true;
                }
            }
            catch (final IOException ex2) {
                throw ex2;
            }
            catch (final Exception ex3) {
                throw new IOException("error constructing MAC: " + ex3.toString());
            }
        }
        this.keys = new IgnoresCaseHashtable();
        this.localIds = new IgnoresCaseHashtable();
        if (authSafe.getContentType().equals(PKCS12KeyStoreSpi.data)) {
            final ContentInfo[] contentInfo = AuthenticatedSafe.getInstance(ASN1OctetString.getInstance(authSafe.getContent()).getOctets()).getContentInfo();
            for (int i = 0; i != contentInfo.length; ++i) {
                if (contentInfo[i].getContentType().equals(PKCS12KeyStoreSpi.data)) {
                    final ASN1Sequence instance2 = ASN1Sequence.getInstance(ASN1OctetString.getInstance(contentInfo[i].getContent()).getOctets());
                    for (int j = 0; j != instance2.size(); ++j) {
                        final SafeBag instance3 = SafeBag.getInstance(instance2.getObjectAt(j));
                        if (instance3.getBagId().equals(PKCS12KeyStoreSpi.pkcs8ShroudedKeyBag)) {
                            b3 = this.processShroudedKeyBag(instance3, array, b4);
                            b2 = false;
                        }
                        else if (instance3.getBagId().equals(PKCS12KeyStoreSpi.certBag)) {
                            vector.addElement(instance3);
                        }
                        else if (instance3.getBagId().equals(PKCS12KeyStoreSpi.keyBag)) {
                            this.processKeyBag(instance3);
                        }
                        else {
                            System.out.println("extra in data " + instance3.getBagId());
                            System.out.println(ASN1Dump.dumpAsString(instance3));
                        }
                    }
                }
                else if (contentInfo[i].getContentType().equals(PKCS12KeyStoreSpi.encryptedData)) {
                    final EncryptedData instance4 = EncryptedData.getInstance(contentInfo[i].getContent());
                    final ASN1Sequence instance5 = ASN1Sequence.getInstance(this.cryptData(false, instance4.getEncryptionAlgorithm(), array, b4, instance4.getContent().getOctets()));
                    b2 = false;
                    for (int k = 0; k != instance5.size(); ++k) {
                        final SafeBag instance6 = SafeBag.getInstance(instance5.getObjectAt(k));
                        if (instance6.getBagId().equals(PKCS12KeyStoreSpi.certBag)) {
                            vector.addElement(instance6);
                        }
                        else if (instance6.getBagId().equals(PKCS12KeyStoreSpi.pkcs8ShroudedKeyBag)) {
                            b3 = this.processShroudedKeyBag(instance6, array, b4);
                        }
                        else if (instance6.getBagId().equals(PKCS12KeyStoreSpi.keyBag)) {
                            this.processKeyBag(instance6);
                        }
                        else {
                            System.out.println("extra in encryptedData " + instance6.getBagId());
                            System.out.println(ASN1Dump.dumpAsString(instance6));
                        }
                    }
                }
                else {
                    System.out.println("extra " + contentInfo[i].getContentType().getId());
                    System.out.println("extra " + ASN1Dump.dumpAsString(contentInfo[i].getContent()));
                }
            }
        }
        this.certs = new IgnoresCaseHashtable();
        this.chainCerts = new Hashtable();
        this.keyCerts = new Hashtable();
        for (int l = 0; l != vector.size(); ++l) {
            final SafeBag safeBag = vector.elementAt(l);
            final CertBag instance7 = CertBag.getInstance(safeBag.getBagValue());
            if (!instance7.getCertId().equals(PKCS12KeyStoreSpi.x509Certificate)) {
                throw new RuntimeException("Unsupported certificate type: " + instance7.getCertId());
            }
            Certificate generateCertificate;
            try {
                generateCertificate = this.certFact.generateCertificate(new ByteArrayInputStream(((ASN1OctetString)instance7.getCertValue()).getOctets()));
            }
            catch (final Exception ex4) {
                throw new RuntimeException(ex4.toString());
            }
            ASN1OctetString asn1OctetString = null;
            String string = null;
            if (safeBag.getBagAttributes() != null) {
                final Enumeration objects = safeBag.getBagAttributes().getObjects();
                while (objects.hasMoreElements()) {
                    final ASN1Sequence instance8 = ASN1Sequence.getInstance(objects.nextElement());
                    final ASN1ObjectIdentifier instance9 = ASN1ObjectIdentifier.getInstance(instance8.getObjectAt(0));
                    final ASN1Set instance10 = ASN1Set.getInstance(instance8.getObjectAt(1));
                    if (instance10.size() > 0) {
                        final ASN1Primitive asn1Primitive = (ASN1Primitive)instance10.getObjectAt(0);
                        if (generateCertificate instanceof PKCS12BagAttributeCarrier) {
                            final PKCS12BagAttributeCarrier pkcs12BagAttributeCarrier = (PKCS12BagAttributeCarrier)generateCertificate;
                            final ASN1Encodable bagAttribute = pkcs12BagAttributeCarrier.getBagAttribute(instance9);
                            if (bagAttribute != null) {
                                if (instance9.equals(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId)) {
                                    final String hexString = Hex.toHexString(((ASN1OctetString)asn1Primitive).getOctets());
                                    if (!this.keys.keys.containsKey(hexString) && !this.localIds.keys.containsKey(hexString)) {
                                        continue;
                                    }
                                }
                                if (!bagAttribute.toASN1Primitive().equals(asn1Primitive)) {
                                    throw new IOException("attempt to add existing attribute with different value");
                                }
                            }
                            else if (instance10.size() > 1) {
                                pkcs12BagAttributeCarrier.setBagAttribute(instance9, instance10);
                            }
                            else {
                                pkcs12BagAttributeCarrier.setBagAttribute(instance9, asn1Primitive);
                            }
                        }
                        if (instance9.equals(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName)) {
                            string = ((ASN1BMPString)asn1Primitive).getString();
                        }
                        else {
                            if (!instance9.equals(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId)) {
                                continue;
                            }
                            asn1OctetString = (ASN1OctetString)asn1Primitive;
                        }
                    }
                }
            }
            this.chainCerts.put(new CertId(generateCertificate.getPublicKey()), generateCertificate);
            if (b3) {
                if (this.keyCerts.isEmpty()) {
                    final String key = new String(Hex.encode(this.createSubjectKeyId(generateCertificate.getPublicKey()).getKeyIdentifier()));
                    this.keyCerts.put(key, generateCertificate);
                    this.keys.put(key, this.keys.remove("unmarked"));
                }
            }
            else {
                if (asn1OctetString != null) {
                    this.keyCerts.put(new String(Hex.encode(asn1OctetString.getOctets())), generateCertificate);
                }
                if (string != null) {
                    this.certs.put(string, generateCertificate);
                }
            }
        }
        if (b && b2 && array != null && array.length != 0 && !Properties.isOverrideSet("org.bouncycastle.pkcs12.ignore_useless_passwd")) {
            throw new IOException("password supplied for keystore that does not require one");
        }
    }
    
    private boolean processShroudedKeyBag(final SafeBag safeBag, final char[] array, final boolean b) throws IOException {
        final EncryptedPrivateKeyInfo instance = EncryptedPrivateKeyInfo.getInstance(safeBag.getBagValue());
        final PrivateKey unwrapKey = this.unwrapKey(instance.getEncryptionAlgorithm(), instance.getEncryptedData(), array, b);
        String string = null;
        ASN1OctetString asn1OctetString = null;
        if (safeBag.getBagAttributes() != null) {
            final Enumeration objects = safeBag.getBagAttributes().getObjects();
            while (objects.hasMoreElements()) {
                final ASN1Sequence asn1Sequence = objects.nextElement();
                final ASN1ObjectIdentifier asn1ObjectIdentifier = (ASN1ObjectIdentifier)asn1Sequence.getObjectAt(0);
                final ASN1Set set = (ASN1Set)asn1Sequence.getObjectAt(1);
                ASN1Primitive asn1Primitive = null;
                if (set.size() > 0) {
                    asn1Primitive = (ASN1Primitive)set.getObjectAt(0);
                    if (unwrapKey instanceof PKCS12BagAttributeCarrier) {
                        final PKCS12BagAttributeCarrier pkcs12BagAttributeCarrier = (PKCS12BagAttributeCarrier)unwrapKey;
                        final ASN1Encodable bagAttribute = pkcs12BagAttributeCarrier.getBagAttribute(asn1ObjectIdentifier);
                        if (bagAttribute != null) {
                            if (!bagAttribute.toASN1Primitive().equals(asn1Primitive)) {
                                throw new IOException("attempt to add existing attribute with different value");
                            }
                        }
                        else {
                            pkcs12BagAttributeCarrier.setBagAttribute(asn1ObjectIdentifier, asn1Primitive);
                        }
                    }
                }
                if (asn1ObjectIdentifier.equals(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName)) {
                    string = ((ASN1BMPString)asn1Primitive).getString();
                    this.keys.put(string, unwrapKey);
                }
                else {
                    if (!asn1ObjectIdentifier.equals(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId)) {
                        continue;
                    }
                    asn1OctetString = (ASN1OctetString)asn1Primitive;
                }
            }
        }
        if (asn1OctetString != null) {
            final String s = new String(Hex.encode(asn1OctetString.getOctets()));
            if (string == null) {
                this.keys.put(s, unwrapKey);
            }
            else {
                this.localIds.put(string, s);
            }
            return false;
        }
        this.keys.put("unmarked", unwrapKey);
        return true;
    }
    
    private void processKeyBag(final SafeBag safeBag) throws IOException {
        final PrivateKey privateKey = BouncyCastleProvider.getPrivateKey(PrivateKeyInfo.getInstance(safeBag.getBagValue()));
        String string = null;
        ASN1OctetString asn1OctetString = null;
        if (privateKey instanceof PKCS12BagAttributeCarrier) {
            final PKCS12BagAttributeCarrier pkcs12BagAttributeCarrier = (PKCS12BagAttributeCarrier)privateKey;
            final Enumeration objects = safeBag.getBagAttributes().getObjects();
            while (objects.hasMoreElements()) {
                final ASN1Sequence instance = ASN1Sequence.getInstance(objects.nextElement());
                final ASN1ObjectIdentifier instance2 = ASN1ObjectIdentifier.getInstance(instance.getObjectAt(0));
                final ASN1Set instance3 = ASN1Set.getInstance(instance.getObjectAt(1));
                if (instance3.size() > 0) {
                    final ASN1Primitive asn1Primitive = (ASN1Primitive)instance3.getObjectAt(0);
                    final ASN1Encodable bagAttribute = pkcs12BagAttributeCarrier.getBagAttribute(instance2);
                    if (bagAttribute != null) {
                        if (!bagAttribute.toASN1Primitive().equals(asn1Primitive)) {
                            throw new IOException("attempt to add existing attribute with different value");
                        }
                    }
                    else {
                        pkcs12BagAttributeCarrier.setBagAttribute(instance2, asn1Primitive);
                    }
                    if (instance2.equals(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName)) {
                        string = ((ASN1BMPString)asn1Primitive).getString();
                        this.keys.put(string, privateKey);
                    }
                    else {
                        if (!instance2.equals(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId)) {
                            continue;
                        }
                        asn1OctetString = (ASN1OctetString)asn1Primitive;
                    }
                }
            }
        }
        final String s = new String(Hex.encode(asn1OctetString.getOctets()));
        if (string == null) {
            this.keys.put(s, privateKey);
        }
        else {
            this.localIds.put(string, s);
        }
    }
    
    private int validateIterationCount(final BigInteger bigInteger) {
        final int intValueExact = BigIntegers.intValueExact(bigInteger);
        if (intValueExact < 0) {
            throw new IllegalStateException("negative iteration count found");
        }
        final BigInteger bigInteger2 = Properties.asBigInteger("org.bouncycastle.pkcs12.max_it_count");
        if (bigInteger2 != null && BigIntegers.intValueExact(bigInteger2) < intValueExact) {
            throw new IllegalStateException("iteration count " + intValueExact + " greater than " + BigIntegers.intValueExact(bigInteger2));
        }
        return intValueExact;
    }
    
    private ASN1Primitive getAlgParams(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        if (asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes128_CBC) || asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes256_CBC)) {
            final byte[] bytes = new byte[16];
            this.random.nextBytes(bytes);
            return new DEROctetString(bytes);
        }
        if (asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes128_GCM) || asn1ObjectIdentifier.equals(NISTObjectIdentifiers.id_aes256_GCM)) {
            final byte[] bytes2 = new byte[12];
            this.random.nextBytes(bytes2);
            return new GCMParameters(bytes2, 16).toASN1Primitive();
        }
        throw new IllegalStateException("unknown encryption OID in getAlgParams()");
    }
    
    @Override
    public void engineStore(final KeyStore.LoadStoreParameter loadStoreParameter) throws IOException, NoSuchAlgorithmException, CertificateException {
        if (loadStoreParameter == null) {
            throw new IllegalArgumentException("'param' arg cannot be null");
        }
        if (!(loadStoreParameter instanceof PKCS12StoreParameter) && !(loadStoreParameter instanceof JDKPKCS12StoreParameter)) {
            throw new IllegalArgumentException("No support for 'param' of type " + loadStoreParameter.getClass().getName());
        }
        PKCS12StoreParameter pkcs12StoreParameter;
        if (loadStoreParameter instanceof PKCS12StoreParameter) {
            pkcs12StoreParameter = (PKCS12StoreParameter)loadStoreParameter;
        }
        else {
            pkcs12StoreParameter = new PKCS12StoreParameter(((JDKPKCS12StoreParameter)loadStoreParameter).getOutputStream(), loadStoreParameter.getProtectionParameter(), ((JDKPKCS12StoreParameter)loadStoreParameter).isUseDEREncoding(), ((JDKPKCS12StoreParameter)loadStoreParameter).isOverwriteFriendlyName());
        }
        final KeyStore.ProtectionParameter protectionParameter = loadStoreParameter.getProtectionParameter();
        char[] password;
        if (protectionParameter == null) {
            password = null;
        }
        else {
            if (!(protectionParameter instanceof KeyStore.PasswordProtection)) {
                throw new IllegalArgumentException("No support for protection parameter of type " + ((KeyStore.PasswordProtection)protectionParameter).getClass().getName());
            }
            password = ((KeyStore.PasswordProtection)protectionParameter).getPassword();
        }
        this.doStore(pkcs12StoreParameter.getOutputStream(), password, pkcs12StoreParameter.isForDEREncoding(), pkcs12StoreParameter.isOverwriteFriendlyName());
    }
    
    @Override
    public void engineStore(final OutputStream outputStream, final char[] array) throws IOException {
        this.doStore(outputStream, array, false, true);
    }
    
    private void syncFriendlyName() {
        final Enumeration keys = this.keys.keys();
        while (keys.hasMoreElements()) {
            final String s = keys.nextElement();
            final PrivateKey privateKey = (PrivateKey)this.keys.get(s);
            if (privateKey instanceof PKCS12BagAttributeCarrier) {
                final ASN1Encodable bagAttribute = ((PKCS12BagAttributeCarrier)privateKey).getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                if (bagAttribute == null || s.equals(bagAttribute.toString())) {
                    continue;
                }
                this.keys.put(bagAttribute.toString(), privateKey);
                this.keys.remove(s);
            }
        }
        final Enumeration keys2 = this.certs.keys();
        while (keys2.hasMoreElements()) {
            final String s2 = keys2.nextElement();
            final Certificate certificate = (Certificate)this.certs.get(s2);
            if (certificate instanceof PKCS12BagAttributeCarrier) {
                final ASN1Encodable bagAttribute2 = ((PKCS12BagAttributeCarrier)certificate).getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                if (bagAttribute2 == null || s2.equals(bagAttribute2.toString())) {
                    continue;
                }
                this.certs.put(bagAttribute2.toString(), certificate);
                this.certs.remove(s2);
            }
        }
        final Enumeration keys3 = this.keyCerts.keys();
        while (keys3.hasMoreElements()) {
            final String s3 = (String)keys3.nextElement();
            final Certificate value = this.keyCerts.get(s3);
            if (value instanceof PKCS12BagAttributeCarrier) {
                final ASN1Encodable bagAttribute3 = ((PKCS12BagAttributeCarrier)value).getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                if (bagAttribute3 == null || s3.equals(bagAttribute3.toString())) {
                    continue;
                }
                this.keyCerts.put(bagAttribute3.toString(), value);
                this.keyCerts.remove(s3);
            }
        }
    }
    
    private void doStore(final OutputStream outputStream, final char[] array, final boolean b, final boolean b2) throws IOException {
        if (!b2) {
            this.syncFriendlyName();
        }
        if (this.keys.size() == 0) {
            if (array == null) {
                final Enumeration keys = this.certs.keys();
                final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector();
                while (keys.hasMoreElements()) {
                    try {
                        final String s = keys.nextElement();
                        asn1EncodableVector.add(this.createSafeBag(s, (Certificate)this.certs.get(s), b2));
                        continue;
                    }
                    catch (final CertificateEncodingException ex) {
                        throw new IOException("Error encoding certificate: " + ex.toString());
                    }
                    break;
                }
                if (b) {
                    new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(asn1EncodableVector).getEncoded()))).getEncoded())), null).encodeTo(outputStream, "DER");
                }
                else {
                    new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(asn1EncodableVector).getEncoded()))).getEncoded())), null).encodeTo(outputStream, "BER");
                }
                return;
            }
        }
        else if (array == null) {
            throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
        }
        final ASN1EncodableVector asn1EncodableVector2 = new ASN1EncodableVector();
        final Enumeration keys2 = this.keys.keys();
        while (keys2.hasMoreElements()) {
            final byte[] bytes = new byte[20];
            this.random.nextBytes(bytes);
            final String anObject = keys2.nextElement();
            final PrivateKey privateKey = (PrivateKey)this.keys.get(anObject);
            AlgorithmIdentifier algorithmIdentifier;
            byte[] array2;
            if (isPBKDF2(this.keyAlgorithm)) {
                final PBKDF2Params pbkdf2Params = new PBKDF2Params(bytes, 51200, getKeyLength(this.keyAlgorithm), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE));
                final EncryptionScheme encryptionScheme = new EncryptionScheme(this.keyAlgorithm, this.getAlgParams(this.keyAlgorithm));
                algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBES2, new PBES2Parameters(new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, pbkdf2Params), encryptionScheme));
                array2 = this.wrapKey(encryptionScheme, privateKey, pbkdf2Params, array);
            }
            else {
                final PKCS12PBEParams pkcs12PBEParams = new PKCS12PBEParams(bytes, 51200);
                array2 = this.wrapKey(this.keyAlgorithm.getId(), privateKey, pkcs12PBEParams, array);
                algorithmIdentifier = new AlgorithmIdentifier(this.keyAlgorithm, pkcs12PBEParams.toASN1Primitive());
            }
            final EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(algorithmIdentifier, array2);
            boolean b3 = false;
            final ASN1EncodableVector asn1EncodableVector3 = new ASN1EncodableVector();
            if (privateKey instanceof PKCS12BagAttributeCarrier) {
                final PKCS12BagAttributeCarrier pkcs12BagAttributeCarrier = (PKCS12BagAttributeCarrier)privateKey;
                final ASN1BMPString asn1BMPString = (ASN1BMPString)pkcs12BagAttributeCarrier.getBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName);
                if (b2 && (asn1BMPString == null || !asn1BMPString.getString().equals(anObject))) {
                    pkcs12BagAttributeCarrier.setBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName, new DERBMPString(anObject));
                }
                if (pkcs12BagAttributeCarrier.getBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId) == null) {
                    pkcs12BagAttributeCarrier.setBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId, this.createSubjectKeyId(this.engineGetCertificate(anObject).getPublicKey()));
                }
                final Enumeration bagAttributeKeys = pkcs12BagAttributeCarrier.getBagAttributeKeys();
                while (bagAttributeKeys.hasMoreElements()) {
                    final ASN1ObjectIdentifier asn1ObjectIdentifier = bagAttributeKeys.nextElement();
                    final ASN1EncodableVector asn1EncodableVector4 = new ASN1EncodableVector();
                    asn1EncodableVector4.add(asn1ObjectIdentifier);
                    asn1EncodableVector4.add(new DERSet(pkcs12BagAttributeCarrier.getBagAttribute(asn1ObjectIdentifier)));
                    b3 = true;
                    asn1EncodableVector3.add(new DERSequence(asn1EncodableVector4));
                }
            }
            if (!b3) {
                final ASN1EncodableVector asn1EncodableVector5 = new ASN1EncodableVector();
                final Certificate engineGetCertificate = this.engineGetCertificate(anObject);
                asn1EncodableVector5.add(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId);
                asn1EncodableVector5.add(new DERSet(this.createSubjectKeyId(engineGetCertificate.getPublicKey())));
                asn1EncodableVector3.add(new DERSequence(asn1EncodableVector5));
                final ASN1EncodableVector asn1EncodableVector6 = new ASN1EncodableVector();
                asn1EncodableVector6.add(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName);
                asn1EncodableVector6.add(new DERSet(new DERBMPString(anObject)));
                asn1EncodableVector3.add(new DERSequence(asn1EncodableVector6));
            }
            asn1EncodableVector2.add(new SafeBag(PKCS12KeyStoreSpi.pkcs8ShroudedKeyBag, encryptedPrivateKeyInfo.toASN1Primitive(), new DERSet(asn1EncodableVector3)));
        }
        final BEROctetString berOctetString = new BEROctetString(new DERSequence(asn1EncodableVector2).getEncoded("DER"));
        final byte[] bytes2 = new byte[20];
        this.random.nextBytes(bytes2);
        final ASN1EncodableVector asn1EncodableVector7 = new ASN1EncodableVector();
        AlgorithmIdentifier algorithmIdentifier2;
        if (isPBKDF2(this.certAlgorithm)) {
            algorithmIdentifier2 = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBES2, new PBES2Parameters(new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(bytes2, 51200, getKeyLength(this.certAlgorithm), new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE))), new EncryptionScheme(this.certAlgorithm, this.getAlgParams(this.certAlgorithm))));
        }
        else {
            algorithmIdentifier2 = new AlgorithmIdentifier(this.certAlgorithm, new PKCS12PBEParams(bytes2, 51200).toASN1Primitive());
        }
        final Hashtable<Certificate, Certificate> hashtable = new Hashtable<Certificate, Certificate>();
        final Enumeration keys3 = this.keys.keys();
        while (keys3.hasMoreElements()) {
            try {
                final String anObject2 = keys3.nextElement();
                final Certificate engineGetCertificate2 = this.engineGetCertificate(anObject2);
                boolean b4 = false;
                final CertBag certBag = new CertBag(PKCS12KeyStoreSpi.x509Certificate, new DEROctetString(engineGetCertificate2.getEncoded()));
                final ASN1EncodableVector asn1EncodableVector8 = new ASN1EncodableVector();
                if (engineGetCertificate2 instanceof PKCS12BagAttributeCarrier) {
                    final PKCS12BagAttributeCarrier pkcs12BagAttributeCarrier2 = (PKCS12BagAttributeCarrier)engineGetCertificate2;
                    final ASN1BMPString asn1BMPString2 = (ASN1BMPString)pkcs12BagAttributeCarrier2.getBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName);
                    if (b2 && (asn1BMPString2 == null || !asn1BMPString2.getString().equals(anObject2))) {
                        pkcs12BagAttributeCarrier2.setBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName, new DERBMPString(anObject2));
                    }
                    if (pkcs12BagAttributeCarrier2.getBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId) == null) {
                        pkcs12BagAttributeCarrier2.setBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId, this.createSubjectKeyId(engineGetCertificate2.getPublicKey()));
                    }
                    final Enumeration bagAttributeKeys2 = pkcs12BagAttributeCarrier2.getBagAttributeKeys();
                    while (bagAttributeKeys2.hasMoreElements()) {
                        final ASN1ObjectIdentifier asn1ObjectIdentifier2 = bagAttributeKeys2.nextElement();
                        final ASN1EncodableVector asn1EncodableVector9 = new ASN1EncodableVector();
                        asn1EncodableVector9.add(asn1ObjectIdentifier2);
                        asn1EncodableVector9.add(new DERSet(pkcs12BagAttributeCarrier2.getBagAttribute(asn1ObjectIdentifier2)));
                        asn1EncodableVector8.add(new DERSequence(asn1EncodableVector9));
                        b4 = true;
                    }
                }
                if (!b4) {
                    final ASN1EncodableVector asn1EncodableVector10 = new ASN1EncodableVector();
                    asn1EncodableVector10.add(PKCS12KeyStoreSpi.pkcs_9_at_localKeyId);
                    asn1EncodableVector10.add(new DERSet(this.createSubjectKeyId(engineGetCertificate2.getPublicKey())));
                    asn1EncodableVector8.add(new DERSequence(asn1EncodableVector10));
                    final ASN1EncodableVector asn1EncodableVector11 = new ASN1EncodableVector();
                    asn1EncodableVector11.add(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName);
                    asn1EncodableVector11.add(new DERSet(new DERBMPString(anObject2)));
                    asn1EncodableVector8.add(new DERSequence(asn1EncodableVector11));
                }
                asn1EncodableVector7.add(new SafeBag(PKCS12KeyStoreSpi.certBag, certBag.toASN1Primitive(), new DERSet(asn1EncodableVector8)));
                hashtable.put(engineGetCertificate2, engineGetCertificate2);
                continue;
            }
            catch (final CertificateEncodingException ex2) {
                throw new IOException("Error encoding certificate: " + ex2.toString());
            }
            break;
        }
        final Enumeration keys4 = this.certs.keys();
        while (keys4.hasMoreElements()) {
            try {
                final String s2 = keys4.nextElement();
                final Certificate certificate = (Certificate)this.certs.get(s2);
                if (this.keys.get(s2) != null) {
                    continue;
                }
                asn1EncodableVector7.add(this.createSafeBag(s2, certificate, b2));
                hashtable.put(certificate, certificate);
                continue;
            }
            catch (final CertificateEncodingException ex3) {
                throw new IOException("Error encoding certificate: " + ex3.toString());
            }
            break;
        }
        final Set usedCertificateSet = this.getUsedCertificateSet();
        final Enumeration keys5 = this.chainCerts.keys();
        while (keys5.hasMoreElements()) {
            try {
                final Certificate key = this.chainCerts.get(keys5.nextElement());
                if (!usedCertificateSet.contains(key)) {
                    continue;
                }
                if (hashtable.get(key) != null) {
                    continue;
                }
                final CertBag certBag2 = new CertBag(PKCS12KeyStoreSpi.x509Certificate, new DEROctetString(key.getEncoded()));
                final ASN1EncodableVector asn1EncodableVector12 = new ASN1EncodableVector();
                if (key instanceof PKCS12BagAttributeCarrier) {
                    final PKCS12BagAttributeCarrier pkcs12BagAttributeCarrier3 = (PKCS12BagAttributeCarrier)key;
                    final Enumeration bagAttributeKeys3 = pkcs12BagAttributeCarrier3.getBagAttributeKeys();
                    while (bagAttributeKeys3.hasMoreElements()) {
                        final ASN1ObjectIdentifier asn1ObjectIdentifier3 = bagAttributeKeys3.nextElement();
                        if (asn1ObjectIdentifier3.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) {
                            continue;
                        }
                        final ASN1EncodableVector asn1EncodableVector13 = new ASN1EncodableVector();
                        asn1EncodableVector13.add(asn1ObjectIdentifier3);
                        asn1EncodableVector13.add(new DERSet(pkcs12BagAttributeCarrier3.getBagAttribute(asn1ObjectIdentifier3)));
                        asn1EncodableVector12.add(new DERSequence(asn1EncodableVector13));
                    }
                }
                asn1EncodableVector7.add(new SafeBag(PKCS12KeyStoreSpi.certBag, certBag2.toASN1Primitive(), new DERSet(asn1EncodableVector12)));
                continue;
            }
            catch (final CertificateEncodingException ex4) {
                throw new IOException("Error encoding certificate: " + ex4.toString());
            }
            break;
        }
        final ContentInfo contentInfo = new ContentInfo(PKCS12KeyStoreSpi.data, new BEROctetString(new AuthenticatedSafe(new ContentInfo[] { new ContentInfo(PKCS12KeyStoreSpi.data, berOctetString), new ContentInfo(PKCS12KeyStoreSpi.encryptedData, new EncryptedData(PKCS12KeyStoreSpi.data, algorithmIdentifier2, new BEROctetString(this.cryptData(true, algorithmIdentifier2, array, false, new DERSequence(asn1EncodableVector7).getEncoded("DER")))).toASN1Primitive()) }).getEncoded(b ? "DER" : "BER")));
        final byte[] bytes3 = new byte[this.saltLength];
        this.random.nextBytes(bytes3);
        final byte[] octets = ((ASN1OctetString)contentInfo.getContent()).getOctets();
        MacData macData;
        if (this.keyAlgorithm.equals(NISTObjectIdentifiers.id_aes256_GCM)) {
            macData = null;
        }
        else {
            try {
                macData = new MacData(new DigestInfo(this.macAlgorithm, this.calculatePbeMac(this.macAlgorithm.getAlgorithm(), bytes3, this.itCount, array, false, octets)), bytes3, this.itCount);
            }
            catch (final Exception ex5) {
                throw new IOException("error constructing MAC: " + ex5.toString());
            }
        }
        new Pfx(contentInfo, macData).encodeTo(outputStream, b ? "DER" : "BER");
    }
    
    private SafeBag createSafeBag(final String anObject, final Certificate certificate, final boolean b) throws CertificateEncodingException {
        final CertBag certBag = new CertBag(PKCS12KeyStoreSpi.x509Certificate, new DEROctetString(certificate.getEncoded()));
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector();
        boolean b2 = false;
        if (certificate instanceof PKCS12BagAttributeCarrier) {
            final PKCS12BagAttributeCarrier pkcs12BagAttributeCarrier = (PKCS12BagAttributeCarrier)certificate;
            final ASN1BMPString asn1BMPString = (ASN1BMPString)pkcs12BagAttributeCarrier.getBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName);
            if (b && (asn1BMPString == null || !asn1BMPString.getString().equals(anObject)) && anObject != null) {
                pkcs12BagAttributeCarrier.setBagAttribute(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName, new DERBMPString(anObject));
            }
            final Enumeration bagAttributeKeys = pkcs12BagAttributeCarrier.getBagAttributeKeys();
            while (bagAttributeKeys.hasMoreElements()) {
                final ASN1ObjectIdentifier asn1ObjectIdentifier = bagAttributeKeys.nextElement();
                if (asn1ObjectIdentifier.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) {
                    continue;
                }
                if (asn1ObjectIdentifier.equals(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage)) {
                    continue;
                }
                final ASN1EncodableVector asn1EncodableVector2 = new ASN1EncodableVector();
                asn1EncodableVector2.add(asn1ObjectIdentifier);
                asn1EncodableVector2.add(new DERSet(pkcs12BagAttributeCarrier.getBagAttribute(asn1ObjectIdentifier)));
                asn1EncodableVector.add(new DERSequence(asn1EncodableVector2));
                b2 = true;
            }
        }
        if (!b2) {
            final ASN1EncodableVector asn1EncodableVector3 = new ASN1EncodableVector();
            asn1EncodableVector3.add(PKCS12KeyStoreSpi.pkcs_9_at_friendlyName);
            asn1EncodableVector3.add(new DERSet(new DERBMPString(anObject)));
            asn1EncodableVector.add(new DERSequence(asn1EncodableVector3));
        }
        if (certificate instanceof X509Certificate) {
            final ASN1OctetString extensionValue = Extensions.getExtensionValue(TBSCertificate.getInstance(((X509Certificate)certificate).getTBSCertificate()).getExtensions(), Extension.extendedKeyUsage);
            DERSet set;
            if (extensionValue != null) {
                set = new DERSet(ExtendedKeyUsage.getInstance(extensionValue.getOctets()).getUsages());
            }
            else {
                set = new DERSet(KeyPurposeId.anyExtendedKeyUsage);
            }
            asn1EncodableVector.add(new DERSequence(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage, set));
        }
        return new SafeBag(PKCS12KeyStoreSpi.certBag, certBag.toASN1Primitive(), new DERSet(asn1EncodableVector));
    }
    
    private Set getUsedCertificateSet() {
        final HashSet set = new HashSet();
        final Enumeration keys = this.keys.keys();
        while (keys.hasMoreElements()) {
            final Certificate[] engineGetCertificateChain = this.engineGetCertificateChain(keys.nextElement());
            for (int i = 0; i != engineGetCertificateChain.length; ++i) {
                set.add(engineGetCertificateChain[i]);
            }
        }
        final Enumeration keys2 = this.certs.keys();
        while (keys2.hasMoreElements()) {
            set.add(this.engineGetCertificate((String)keys2.nextElement()));
        }
        return set;
    }
    
    private byte[] calculatePbeMac(final ASN1ObjectIdentifier asn1ObjectIdentifier, final byte[] salt, final int iterationCount, final char[] array, final boolean b, final byte[] input) throws Exception {
        if (PKCSObjectIdentifiers.id_PBMAC1.equals(asn1ObjectIdentifier)) {
            final PBMAC1Params instance = PBMAC1Params.getInstance(this.macAlgorithm.getParameters());
            if (instance == null) {
                throw new IOException("If the DigestAlgorithmIdentifier is id-PBMAC1, then the parameters field must contain valid PBMAC1-params parameters.");
            }
            if (PKCSObjectIdentifiers.id_PBKDF2.equals(instance.getKeyDerivationFunc().getAlgorithm())) {
                final PBKDF2Params instance2 = PBKDF2Params.getInstance(instance.getKeyDerivationFunc().getParameters());
                if (instance2.getKeyLength() == null) {
                    throw new IOException("Key length must be present when using PBMAC1.");
                }
                final HMac hMac = new HMac(getPrf(instance.getMessageAuthScheme().getAlgorithm()));
                final PKCS5S2ParametersGenerator pkcs5S2ParametersGenerator = new PKCS5S2ParametersGenerator(getPrf(instance2.getPrf().getAlgorithm()));
                pkcs5S2ParametersGenerator.init(Strings.toUTF8ByteArray(array), instance2.getSalt(), BigIntegers.intValueExact(instance2.getIterationCount()));
                final CipherParameters generateDerivedParameters = pkcs5S2ParametersGenerator.generateDerivedParameters(BigIntegers.intValueExact(instance2.getKeyLength()) * 8);
                Arrays.clear(pkcs5S2ParametersGenerator.getPassword());
                hMac.init(generateDerivedParameters);
                hMac.update(input, 0, input.length);
                final byte[] array2 = new byte[hMac.getMacSize()];
                hMac.doFinal(array2, 0);
                return array2;
            }
        }
        final PBEParameterSpec params = new PBEParameterSpec(salt, iterationCount);
        final PKCS12Key key = new PKCS12Key(array, b);
        try {
            final Mac mac = this.helper.createMac(asn1ObjectIdentifier.getId());
            mac.init(key, params);
            mac.update(input);
            return mac.doFinal();
        }
        finally {
            Arrays.clear(key.getPassword());
        }
    }
    
    private static Digest getPrf(final ASN1ObjectIdentifier obj) {
        if (PKCSObjectIdentifiers.id_hmacWithSHA256.equals(obj)) {
            return new SHA256Digest();
        }
        if (PKCSObjectIdentifiers.id_hmacWithSHA512.equals(obj)) {
            return new SHA512Digest();
        }
        throw new IllegalArgumentException("unknown prf id " + obj);
    }
    
    static {
        keySizeProvider = new DefaultSecretKeyProvider();
    }
    
    public static class BCPKCS12KeyStore extends AdaptingKeyStoreSpi
    {
        public BCPKCS12KeyStore() {
            super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC));
        }
    }
    
    public static class BCPKCS12KeyStore3DES extends AdaptingKeyStoreSpi
    {
        public BCPKCS12KeyStore3DES() {
            super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC));
        }
    }
    
    public static class BCPKCS12KeyStoreAES256 extends AdaptingKeyStoreSpi
    {
        public BCPKCS12KeyStoreAES256() {
            super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_CBC, NISTObjectIdentifiers.id_aes128_CBC));
        }
    }
    
    public static class BCPKCS12KeyStoreAES256GCM extends AdaptingKeyStoreSpi
    {
        public BCPKCS12KeyStoreAES256GCM() {
            super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_GCM, NISTObjectIdentifiers.id_aes128_GCM));
        }
    }
    
    private class CertId
    {
        byte[] id;
        
        CertId(final PublicKey publicKey) {
            this.id = PKCS12KeyStoreSpi.this.createSubjectKeyId(publicKey).getKeyIdentifier();
        }
        
        CertId(final byte[] id) {
            this.id = id;
        }
        
        @Override
        public int hashCode() {
            return Arrays.hashCode(this.id);
        }
        
        @Override
        public boolean equals(final Object o) {
            return o == this || (o instanceof CertId && Arrays.areEqual(this.id, ((CertId)o).id));
        }
    }
    
    public static class DefPKCS12KeyStore extends AdaptingKeyStoreSpi
    {
        public DefPKCS12KeyStore() {
            super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC));
        }
    }
    
    public static class DefPKCS12KeyStore3DES extends AdaptingKeyStoreSpi
    {
        public DefPKCS12KeyStore3DES() {
            super(new DefaultJcaJceHelper(), new PKCS12KeyStoreSpi(new DefaultJcaJceHelper(), PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC));
        }
    }
    
    public static class DefPKCS12KeyStoreAES256 extends AdaptingKeyStoreSpi
    {
        public DefPKCS12KeyStoreAES256() {
            super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_CBC, NISTObjectIdentifiers.id_aes128_CBC));
        }
    }
    
    public static class DefPKCS12KeyStoreAES256GCM extends AdaptingKeyStoreSpi
    {
        public DefPKCS12KeyStoreAES256GCM() {
            super(new BCJcaJceHelper(), new PKCS12KeyStoreSpi(new BCJcaJceHelper(), NISTObjectIdentifiers.id_aes256_GCM, NISTObjectIdentifiers.id_aes128_GCM));
        }
    }
    
    private static class DefaultSecretKeyProvider
    {
        private final Map KEY_SIZES;
        
        DefaultSecretKeyProvider() {
            final HashMap m = new HashMap();
            m.put(new ASN1ObjectIdentifier("1.2.840.113533.7.66.10"), Integers.valueOf(128));
            m.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
            m.put(NISTObjectIdentifiers.id_aes128_CBC, Integers.valueOf(128));
            m.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192));
            m.put(NISTObjectIdentifiers.id_aes256_CBC, Integers.valueOf(256));
            m.put(NISTObjectIdentifiers.id_aes128_GCM, Integers.valueOf(128));
            m.put(NISTObjectIdentifiers.id_aes256_GCM, Integers.valueOf(256));
            m.put(NTTObjectIdentifiers.id_camellia128_cbc, Integers.valueOf(128));
            m.put(NTTObjectIdentifiers.id_camellia192_cbc, Integers.valueOf(192));
            m.put(NTTObjectIdentifiers.id_camellia256_cbc, Integers.valueOf(256));
            m.put(CryptoProObjectIdentifiers.gostR28147_gcfb, Integers.valueOf(256));
            this.KEY_SIZES = Collections.unmodifiableMap((Map<?, ?>)m);
        }
        
        public int getKeySize(final AlgorithmIdentifier algorithmIdentifier) {
            final Integer n = this.KEY_SIZES.get(algorithmIdentifier.getAlgorithm());
            if (n != null) {
                return n;
            }
            return -1;
        }
    }
    
    private static class IgnoresCaseHashtable
    {
        private Hashtable orig;
        private Hashtable keys;
        
        private IgnoresCaseHashtable() {
            this.orig = new Hashtable();
            this.keys = new Hashtable();
        }
        
        public void put(final String s, final Object value) {
            final String s2 = (s == null) ? null : Strings.toLowerCase(s);
            final String key = this.keys.get(s2);
            if (key != null) {
                this.orig.remove(key);
            }
            this.keys.put(s2, s);
            this.orig.put(s, value);
        }
        
        public Enumeration keys() {
            return new Hashtable(this.orig).keys();
        }
        
        public Object remove(final String s) {
            final String key = this.keys.remove((s == null) ? null : Strings.toLowerCase(s));
            if (key == null) {
                return null;
            }
            return this.orig.remove(key);
        }
        
        public Object get(final String s) {
            final String key = this.keys.get((s == null) ? null : Strings.toLowerCase(s));
            if (key == null) {
                return null;
            }
            return this.orig.get(key);
        }
        
        public Enumeration elements() {
            return this.orig.elements();
        }
        
        public int size() {
            return this.orig.size();
        }
    }
}
