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

package org.bouncycastle.operator.jcajce;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Integers;
import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import java.util.HashMap;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.PublicKey;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import java.security.cert.CertificateException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.security.cert.X509Certificate;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.jcajce.util.AlgorithmParametersUtils;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.PSSParameterSpec;
import org.bouncycastle.asn1.ASN1Sequence;
import java.security.Signature;
import org.bouncycastle.jcajce.util.MessageDigestUtils;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import java.security.MessageDigest;
import java.io.IOException;
import java.security.NoSuchProviderException;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import java.security.AlgorithmParameters;
import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import javax.crypto.KeyAgreement;
import org.bouncycastle.operator.OperatorCreationException;
import javax.crypto.Cipher;
import java.security.GeneralSecurityException;
import org.bouncycastle.cms.CMSException;
import java.security.NoSuchAlgorithmException;
import java.security.KeyPairGenerator;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.operator.DefaultSignatureNameFinder;
import java.util.Map;

class OperatorHelper
{
    private static final Map oids;
    private static final Map asymmetricWrapperAlgNames;
    private static final Map symmetricWrapperAlgNames;
    private static final Map symmetricKeyAlgNames;
    private static final Map symmetricWrapperKeySizes;
    private static final Map oaepParamsMap;
    private static DefaultSignatureNameFinder sigFinder;
    private JcaJceHelper helper;
    
    OperatorHelper(final JcaJceHelper helper) {
        this.helper = helper;
    }
    
    String getWrappingAlgorithmName(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        return OperatorHelper.symmetricWrapperAlgNames.get(asn1ObjectIdentifier);
    }
    
    int getKeySizeInBits(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        return OperatorHelper.symmetricWrapperKeySizes.get(asn1ObjectIdentifier);
    }
    
    KeyPairGenerator createKeyPairGenerator(final ASN1ObjectIdentifier asn1ObjectIdentifier) throws CMSException {
        try {
            final String s = null;
            if (s != null) {
                try {
                    return this.helper.createKeyPairGenerator(s);
                }
                catch (final NoSuchAlgorithmException ex) {}
            }
            return this.helper.createKeyPairGenerator(asn1ObjectIdentifier.getId());
        }
        catch (final GeneralSecurityException ex2) {
            throw new CMSException("cannot create key agreement: " + ex2.getMessage(), ex2);
        }
    }
    
    Cipher createCipher(final ASN1ObjectIdentifier asn1ObjectIdentifier) throws OperatorCreationException {
        try {
            return this.helper.createCipher(asn1ObjectIdentifier.getId());
        }
        catch (final GeneralSecurityException ex) {
            throw new OperatorCreationException("cannot create cipher: " + ex.getMessage(), ex);
        }
    }
    
    KeyAgreement createKeyAgreement(final ASN1ObjectIdentifier asn1ObjectIdentifier) throws OperatorCreationException {
        try {
            final String s = null;
            if (s != null) {
                try {
                    return this.helper.createKeyAgreement(s);
                }
                catch (final NoSuchAlgorithmException ex) {}
            }
            return this.helper.createKeyAgreement(asn1ObjectIdentifier.getId());
        }
        catch (final GeneralSecurityException ex2) {
            throw new OperatorCreationException("cannot create key agreement: " + ex2.getMessage(), ex2);
        }
    }
    
    Cipher createAsymmetricWrapper(final AlgorithmIdentifier algorithmIdentifier, final Map map) throws OperatorCreationException {
        if (algorithmIdentifier == null) {
            throw new NullPointerException("'algorithmID' cannot be null");
        }
        final ASN1ObjectIdentifier algorithm = algorithmIdentifier.getAlgorithm();
        try {
            String cipherName = null;
            if (map != null && !map.isEmpty()) {
                cipherName = map.get(algorithm);
            }
            if (cipherName == null) {
                cipherName = OperatorHelper.asymmetricWrapperAlgNames.get(algorithm);
            }
            if (cipherName != null) {
                if (cipherName.indexOf("OAEPPadding") > 0) {
                    try {
                        final RSAESOAEPparams instance = RSAESOAEPparams.getInstance(algorithmIdentifier.getParameters());
                        if (instance != null) {
                            final OAEPParamsValue oaepParamsValue = OperatorHelper.oaepParamsMap.get(instance.getHashAlgorithm().getAlgorithm());
                            if (oaepParamsValue != null && oaepParamsValue.matches(instance.withDefaultPSource())) {
                                cipherName = oaepParamsValue.getCipherName();
                            }
                        }
                    }
                    catch (final Exception ex) {}
                }
                try {
                    return this.helper.createCipher(cipherName);
                }
                catch (final NoSuchAlgorithmException ex2) {
                    if (cipherName.equals("RSA/ECB/PKCS1Padding")) {
                        try {
                            return this.helper.createCipher("RSA/NONE/PKCS1Padding");
                        }
                        catch (final NoSuchAlgorithmException ex3) {
                            return this.helper.createCipher(algorithm.getId());
                        }
                    }
                    if (cipherName.indexOf("ECB/OAEPWith") > 0) {
                        final int index = cipherName.indexOf("ECB");
                        try {
                            return this.helper.createCipher(cipherName.substring(0, index) + "NONE" + cipherName.substring(index + 3));
                        }
                        catch (final NoSuchAlgorithmException ex4) {}
                    }
                }
            }
            return this.helper.createCipher(algorithm.getId());
        }
        catch (final GeneralSecurityException ex5) {
            throw new OperatorCreationException("cannot create cipher: " + ex5.getMessage(), ex5);
        }
    }
    
    Cipher createSymmetricWrapper(final ASN1ObjectIdentifier asn1ObjectIdentifier) throws OperatorCreationException {
        try {
            final String s = OperatorHelper.symmetricWrapperAlgNames.get(asn1ObjectIdentifier);
            if (s != null) {
                try {
                    return this.helper.createCipher(s);
                }
                catch (final NoSuchAlgorithmException ex) {}
            }
            return this.helper.createCipher(asn1ObjectIdentifier.getId());
        }
        catch (final GeneralSecurityException ex2) {
            throw new OperatorCreationException("cannot create cipher: " + ex2.getMessage(), ex2);
        }
    }
    
    AlgorithmParameters createAlgorithmParameters(final AlgorithmIdentifier algorithmIdentifier) throws OperatorCreationException {
        AlgorithmParameters algorithmParameters = null;
        if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) {
            return null;
        }
        if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSAES_OAEP)) {
            try {
                algorithmParameters = this.helper.createAlgorithmParameters("OAEP");
            }
            catch (final NoSuchAlgorithmException ex) {}
            catch (final NoSuchProviderException ex2) {
                throw new OperatorCreationException("cannot create algorithm parameters: " + ex2.getMessage(), ex2);
            }
        }
        if (algorithmParameters == null) {
            try {
                algorithmParameters = this.helper.createAlgorithmParameters(algorithmIdentifier.getAlgorithm().getId());
            }
            catch (final NoSuchAlgorithmException ex3) {
                return null;
            }
            catch (final NoSuchProviderException ex4) {
                throw new OperatorCreationException("cannot create algorithm parameters: " + ex4.getMessage(), ex4);
            }
        }
        try {
            algorithmParameters.init(algorithmIdentifier.getParameters().toASN1Primitive().getEncoded());
        }
        catch (final IOException ex5) {
            throw new OperatorCreationException("cannot initialise algorithm parameters: " + ex5.getMessage(), ex5);
        }
        return algorithmParameters;
    }
    
    MessageDigest createDigest(final AlgorithmIdentifier algorithmIdentifier) throws GeneralSecurityException {
        MessageDigest messageDigest;
        try {
            if (algorithmIdentifier.getAlgorithm().equals(NISTObjectIdentifiers.id_shake256_len)) {
                messageDigest = this.helper.createMessageDigest("SHAKE256-" + ASN1Integer.getInstance(algorithmIdentifier.getParameters()).getValue());
            }
            else if (algorithmIdentifier.getAlgorithm().equals(NISTObjectIdentifiers.id_shake128_len)) {
                messageDigest = this.helper.createMessageDigest("SHAKE128-" + ASN1Integer.getInstance(algorithmIdentifier.getParameters()).getValue());
            }
            else {
                messageDigest = this.helper.createMessageDigest(MessageDigestUtils.getDigestName(algorithmIdentifier.getAlgorithm()));
            }
        }
        catch (final NoSuchAlgorithmException ex) {
            if (OperatorHelper.oids.get(algorithmIdentifier.getAlgorithm()) == null) {
                throw ex;
            }
            messageDigest = this.helper.createMessageDigest(OperatorHelper.oids.get(algorithmIdentifier.getAlgorithm()));
        }
        return messageDigest;
    }
    
    Signature createSignature(final AlgorithmIdentifier algorithmIdentifier) throws GeneralSecurityException {
        final String signatureName = getSignatureName(algorithmIdentifier);
        Signature signature;
        try {
            signature = this.helper.createSignature(signatureName);
        }
        catch (final NoSuchAlgorithmException ex) {
            if (!signatureName.endsWith("WITHRSAANDMGF1")) {
                throw ex;
            }
            signature = this.helper.createSignature(signatureName.substring(0, signatureName.indexOf(87)) + "WITHRSASSA-PSS");
        }
        if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) {
            final ASN1Sequence instance = ASN1Sequence.getInstance(algorithmIdentifier.getParameters());
            if (this.notDefaultPSSParams(instance)) {
                try {
                    final AlgorithmParameters algorithmParameters = this.helper.createAlgorithmParameters("PSS");
                    algorithmParameters.init(instance.getEncoded());
                    signature.setParameter(algorithmParameters.getParameterSpec(PSSParameterSpec.class));
                }
                catch (final IOException ex2) {
                    throw new GeneralSecurityException("unable to process PSS parameters: " + ex2.getMessage());
                }
            }
        }
        return signature;
    }
    
    Signature createRawSignature(final AlgorithmIdentifier algorithmIdentifier) {
        Signature signature;
        try {
            final String signatureName = getSignatureName(algorithmIdentifier);
            final String string = "NONE" + signatureName.substring(signatureName.indexOf("WITH"));
            signature = this.helper.createSignature(string);
            if (algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) {
                final AlgorithmParameters algorithmParameters = this.helper.createAlgorithmParameters(string);
                AlgorithmParametersUtils.loadParameters(algorithmParameters, algorithmIdentifier.getParameters());
                signature.setParameter(algorithmParameters.getParameterSpec(PSSParameterSpec.class));
            }
        }
        catch (final Exception ex) {
            return null;
        }
        return signature;
    }
    
    private static String getSignatureName(final AlgorithmIdentifier algorithmIdentifier) {
        return OperatorHelper.sigFinder.getAlgorithmName(algorithmIdentifier);
    }
    
    static String getDigestName(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        final String digestName = MessageDigestUtils.getDigestName(asn1ObjectIdentifier);
        final int index = digestName.indexOf(45);
        if (index > 0 && !digestName.startsWith("SHA3")) {
            return digestName.substring(0, index) + digestName.substring(index + 1);
        }
        return digestName;
    }
    
    public X509Certificate convertCertificate(final X509CertificateHolder x509CertificateHolder) throws CertificateException {
        try {
            return (X509Certificate)this.helper.createCertificateFactory("X.509").generateCertificate(new ByteArrayInputStream(x509CertificateHolder.getEncoded()));
        }
        catch (final IOException ex) {
            throw new OpCertificateException("cannot get encoded form of certificate: " + ex.getMessage(), ex);
        }
        catch (final NoSuchProviderException ex2) {
            throw new OpCertificateException("cannot find factory provider: " + ex2.getMessage(), ex2);
        }
    }
    
    public PublicKey convertPublicKey(final SubjectPublicKeyInfo subjectPublicKeyInfo) throws OperatorCreationException {
        try {
            return this.helper.createKeyFactory(subjectPublicKeyInfo.getAlgorithm().getAlgorithm().getId()).generatePublic(new X509EncodedKeySpec(subjectPublicKeyInfo.getEncoded()));
        }
        catch (final IOException ex) {
            throw new OperatorCreationException("cannot get encoded form of key: " + ex.getMessage(), ex);
        }
        catch (final NoSuchAlgorithmException ex2) {
            throw new OperatorCreationException("cannot create key factory: " + ex2.getMessage(), ex2);
        }
        catch (final NoSuchProviderException ex3) {
            throw new OperatorCreationException("cannot find factory provider: " + ex3.getMessage(), ex3);
        }
        catch (final InvalidKeySpecException ex4) {
            throw new OperatorCreationException("cannot create key factory: " + ex4.getMessage(), ex4);
        }
    }
    
    String getKeyAlgorithmName(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        final String s = OperatorHelper.symmetricKeyAlgNames.get(asn1ObjectIdentifier);
        if (s != null) {
            return s;
        }
        return asn1ObjectIdentifier.getId();
    }
    
    private boolean notDefaultPSSParams(final ASN1Sequence asn1Sequence) throws GeneralSecurityException {
        if (asn1Sequence == null || asn1Sequence.size() == 0) {
            return false;
        }
        final RSASSAPSSparams instance = RSASSAPSSparams.getInstance(asn1Sequence);
        return !instance.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1) || !instance.getHashAlgorithm().equals(AlgorithmIdentifier.getInstance(instance.getMaskGenAlgorithm().getParameters())) || instance.getSaltLength().intValue() != this.createDigest(instance.getHashAlgorithm()).getDigestLength();
    }
    
    static {
        oids = new HashMap();
        asymmetricWrapperAlgNames = new HashMap();
        symmetricWrapperAlgNames = new HashMap();
        symmetricKeyAlgNames = new HashMap();
        symmetricWrapperKeySizes = new HashMap();
        oaepParamsMap = new HashMap();
        OperatorHelper.sigFinder = new DefaultSignatureNameFinder();
        OperatorHelper.oids.put(OIWObjectIdentifiers.idSHA1, "SHA1");
        OperatorHelper.oids.put(NISTObjectIdentifiers.id_sha224, "SHA224");
        OperatorHelper.oids.put(NISTObjectIdentifiers.id_sha256, "SHA256");
        OperatorHelper.oids.put(NISTObjectIdentifiers.id_sha384, "SHA384");
        OperatorHelper.oids.put(NISTObjectIdentifiers.id_sha512, "SHA512");
        OperatorHelper.oids.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
        OperatorHelper.oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
        OperatorHelper.oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
        OperatorHelper.asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
        OperatorHelper.asymmetricWrapperAlgNames.put(OIWObjectIdentifiers.elGamalAlgorithm, "Elgamal/ECB/PKCS1Padding");
        OperatorHelper.asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA/ECB/OAEPPadding");
        OperatorHelper.asymmetricWrapperAlgNames.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410");
        OperatorHelper.symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap");
        OperatorHelper.symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap");
        OperatorHelper.symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
        OperatorHelper.symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, Integers.valueOf(192));
        OperatorHelper.symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes128_wrap, Integers.valueOf(128));
        OperatorHelper.symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes192_wrap, Integers.valueOf(192));
        OperatorHelper.symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes256_wrap, Integers.valueOf(256));
        OperatorHelper.symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia128_wrap, Integers.valueOf(128));
        OperatorHelper.symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia192_wrap, Integers.valueOf(192));
        OperatorHelper.symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia256_wrap, Integers.valueOf(256));
        OperatorHelper.symmetricWrapperKeySizes.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, Integers.valueOf(128));
        OperatorHelper.symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
        OperatorHelper.symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES");
        OperatorHelper.symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES");
        OperatorHelper.symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES");
        OperatorHelper.symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES");
        OperatorHelper.symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
        OperatorHelper.symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2");
        OAEPParamsValue.add(OperatorHelper.oaepParamsMap, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", OIWObjectIdentifiers.idSHA1);
        OAEPParamsValue.add(OperatorHelper.oaepParamsMap, "RSA/ECB/OAEPWithSHA-224AndMGF1Padding", NISTObjectIdentifiers.id_sha224);
        OAEPParamsValue.add(OperatorHelper.oaepParamsMap, "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", NISTObjectIdentifiers.id_sha256);
        OAEPParamsValue.add(OperatorHelper.oaepParamsMap, "RSA/ECB/OAEPWithSHA-384AndMGF1Padding", NISTObjectIdentifiers.id_sha384);
        OAEPParamsValue.add(OperatorHelper.oaepParamsMap, "RSA/ECB/OAEPWithSHA-512AndMGF1Padding", NISTObjectIdentifiers.id_sha512);
    }
    
    private static class OAEPParamsValue
    {
        private String cipherName;
        private byte[] derEncoding;
        
        static void add(final Map map, final String s, final ASN1ObjectIdentifier asn1ObjectIdentifier) {
            try {
                map.put(asn1ObjectIdentifier, new OAEPParamsValue(s, getDEREncoding(createOAEPParams(asn1ObjectIdentifier))));
            }
            catch (final Exception cause) {
                throw new RuntimeException(cause);
            }
        }
        
        private OAEPParamsValue(final String cipherName, final byte[] derEncoding) {
            this.cipherName = cipherName;
            this.derEncoding = derEncoding;
        }
        
        String getCipherName() {
            return this.cipherName;
        }
        
        boolean matches(final RSAESOAEPparams rsaesoaePparams) throws IOException {
            return Arrays.areEqual(this.derEncoding, getDEREncoding(rsaesoaePparams));
        }
        
        private static RSAESOAEPparams createOAEPParams(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
            final AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(asn1ObjectIdentifier, DERNull.INSTANCE);
            return new RSAESOAEPparams(algorithmIdentifier, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, algorithmIdentifier), RSAESOAEPparams.DEFAULT_P_SOURCE_ALGORITHM);
        }
        
        private static byte[] getDEREncoding(final RSAESOAEPparams rsaesoaePparams) throws IOException {
            return rsaesoaePparams.getEncoded("DER");
        }
    }
    
    private static class OpCertificateException extends CertificateException
    {
        private Throwable cause;
        
        public OpCertificateException(final String msg, final Throwable cause) {
            super(msg);
            this.cause = cause;
        }
        
        @Override
        public Throwable getCause() {
            return this.cause;
        }
    }
}
