package org.bouncycastle.cms;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.cert.CRLException;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERObjectIdentifier;
// BEGIN android-removed
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// END android-removed
import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.x509.NoSuchStoreException;
import org.bouncycastle.x509.X509CollectionStoreParameters;
import org.bouncycastle.x509.X509Store;
import org.bouncycastle.x509.X509V2AttributeCertificate;

class CMSSignedHelper
{
    static final CMSSignedHelper INSTANCE = new CMSSignedHelper();

    private static final Map     encryptionAlgs = new HashMap();
    private static final Map     digestAlgs = new HashMap();
    private static final Map     digestAliases = new HashMap();

    private static void addEntries(DERObjectIdentifier alias, String digest, String encryption)
    {
        digestAlgs.put(alias.getId(), digest);
        encryptionAlgs.put(alias.getId(), encryption);
    }

    static
    {
        // BEGIN android-removed
        // addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA");
        // END android-removed
        addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA");
        addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA");
        addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA");
        addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA");
        // BEGIN android-removed
        // addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA");
        // addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA");
        // END android-removed
        addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA");
        addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA");
        // BEGIN android-removed
        // addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA");
        // addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA");
        // END android-removed
        addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA");
        addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA");
        // BEGIN android-removed
        // addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA");
        // END android-removed
        addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA");
        addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA");
        addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA");
        addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA");
        // BEGIN android-removed
        // addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA");
        // END android-removed
        addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA");
        addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA");
        addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA");
        addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA");
        addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA");
        // BEGIN android-removed
        // addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA");
        // END android-removed
        addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA");
        addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA");
        addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA");
        addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA");
        addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA");
        addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1");
        addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1");

        encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA");
        encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA");
        encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA");
        encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(), "RSA");
        // BEGIN android-removed
        // encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, "RSAandMGF1");
        // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94.getId(), "GOST3410");
        // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001.getId(), "ECGOST3410");
        // encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410");
        // encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410");
        // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001.getId(), "ECGOST3410");
        // encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94.getId(), "GOST3410");
        //
        // digestAlgs.put(PKCSObjectIdentifiers.md2.getId(), "MD2");
        // digestAlgs.put(PKCSObjectIdentifiers.md4.getId(), "MD4");
        // END android-removed
        digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5");
        digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1");
        // BEGIN android-removed
        // digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224");
        // END android-removed
        digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256");
        digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384");
        digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512");
        // BEGIN android-removed
        // digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128");
        // digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160");
        // digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256");
        // digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(),  "GOST3411");
        // digestAlgs.put("1.3.6.1.4.1.5849.1.2.1",  "GOST3411");
        // END android-removed

        digestAliases.put("SHA1", new String[] { "SHA-1" });
        // BEGIN android-removed
        // digestAliases.put("SHA224", new String[] { "SHA-224" });
        // END android-removed
        digestAliases.put("SHA256", new String[] { "SHA-256" });
        digestAliases.put("SHA384", new String[] { "SHA-384" });
        digestAliases.put("SHA512", new String[] { "SHA-512" });
    }
    
    /**
     * Return the digest algorithm using one of the standard JCA string
     * representations rather than the algorithm identifier (if possible).
     */
    String getDigestAlgName(
        String digestAlgOID)
    {
        String algName = (String)digestAlgs.get(digestAlgOID);

        if (algName != null)
        {
            return algName;
        }

        return digestAlgOID;
    }

    /**
     * Return the digest encryption algorithm using one of the standard
     * JCA string representations rather the the algorithm identifier (if
     * possible).
     */
    String getEncryptionAlgName(
        String encryptionAlgOID)
    {
        String algName = (String)encryptionAlgs.get(encryptionAlgOID);

        if (algName != null)
        {
            return algName;
        }

        return encryptionAlgOID;
    }


    X509Store createAttributeStore(
        String type,
        Provider provider,
        ASN1Set certSet)
        throws NoSuchStoreException, CMSException
    {
        List certs = new ArrayList();

        if (certSet != null)
        {
            Enumeration e = certSet.getObjects();

            while (e.hasMoreElements())
            {
                try
                {
                    ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive();

                    if (obj instanceof ASN1TaggedObject)
                    {
                        ASN1TaggedObject tagged = (ASN1TaggedObject)obj;

                        if (tagged.getTagNo() == 2)
                        {
                            certs.add(new X509V2AttributeCertificate(ASN1Sequence.getInstance(tagged, false).getEncoded()));
                        }
                    }
                }
                catch (IOException ex)
                {
                    throw new CMSException(
                            "can't re-encode attribute certificate!", ex);
                }
            }
        }

        try
        {
            return X509Store.getInstance(
                         "AttributeCertificate/" +type, new X509CollectionStoreParameters(certs), provider);
        }
        catch (IllegalArgumentException e)
        {
            throw new CMSException("can't setup the X509Store", e);
        }
    }

    X509Store createCertificateStore(
        String type,
        Provider provider,
        ASN1Set certSet)
        throws NoSuchStoreException, CMSException
    {
        List certs = new ArrayList();

        if (certSet != null)
        {
            addCertsFromSet(certs, certSet, provider);
        }

        try
        {
            return X509Store.getInstance(
                         "Certificate/" +type, new X509CollectionStoreParameters(certs), provider);
        }
        catch (IllegalArgumentException e)
        {
            throw new CMSException("can't setup the X509Store", e);
        }
    }

    X509Store createCRLsStore(
        String type,
        Provider provider,
        ASN1Set crlSet)
        throws NoSuchStoreException, CMSException
    {
        List crls = new ArrayList();

        if (crlSet != null)
        {
            addCRLsFromSet(crls, crlSet, provider);
        }

        try
        {
            return X509Store.getInstance(
                         "CRL/" +type, new X509CollectionStoreParameters(crls), provider);
        }
        catch (IllegalArgumentException e)
        {
            throw new CMSException("can't setup the X509Store", e);
        }
    }

    CertStore createCertStore(
        String type,
        Provider provider,
        ASN1Set certSet,
        ASN1Set crlSet)
        throws CMSException, NoSuchAlgorithmException
    {
        List certsAndcrls = new ArrayList();

        //
        // load the certificates and revocation lists if we have any
        //

        if (certSet != null)
        {
            addCertsFromSet(certsAndcrls, certSet, provider);
        }

        if (crlSet != null)
        {
            addCRLsFromSet(certsAndcrls, crlSet, provider);
        }

        try
        {
            if (provider != null)
            {
                return CertStore.getInstance(type, new CollectionCertStoreParameters(certsAndcrls), provider);
            }
            else
            {
                return CertStore.getInstance(type, new CollectionCertStoreParameters(certsAndcrls));
            }
        }
        catch (InvalidAlgorithmParameterException e)
        {
            throw new CMSException("can't setup the CertStore", e);
        }
    }

    private void addCertsFromSet(List certs, ASN1Set certSet, Provider provider)
        throws CMSException
    {
        CertificateFactory cf;

        try
        {
            if (provider != null)
            {
                cf = CertificateFactory.getInstance("X.509", provider);
            }
            else
            {
                cf = CertificateFactory.getInstance("X.509");
            }
        }
        catch (CertificateException ex)
        {
            throw new CMSException("can't get certificate factory.", ex);
        }
        Enumeration e = certSet.getObjects();

        while (e.hasMoreElements())
        {
            try
            {
                ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive();

                if (obj instanceof ASN1Sequence)
                {
                    certs.add(cf.generateCertificate(
                        new ByteArrayInputStream(obj.getEncoded())));
                }
            }
            catch (IOException ex)
            {
                throw new CMSException(
                        "can't re-encode certificate!", ex);
            }
            catch (CertificateException ex)
            {
                throw new CMSException(
                        "can't re-encode certificate!", ex);
            }
        }
    }

    private void addCRLsFromSet(List crls, ASN1Set certSet, Provider provider)
        throws CMSException
    {
        CertificateFactory cf;

        try
        {
            if (provider != null)
            {
                cf = CertificateFactory.getInstance("X.509", provider);
            }
            else
            {
                cf = CertificateFactory.getInstance("X.509");
            }
        }
        catch (CertificateException ex)
        {
            throw new CMSException("can't get certificate factory.", ex);
        }
        Enumeration e = certSet.getObjects();

        while (e.hasMoreElements())
        {
            try
            {
                ASN1Primitive obj = ((ASN1Encodable)e.nextElement()).toASN1Primitive();

                crls.add(cf.generateCRL(
                    new ByteArrayInputStream(obj.getEncoded())));
            }
            catch (IOException ex)
            {
                throw new CMSException("can't re-encode CRL!", ex);
            }
            catch (CRLException ex)
            {
                throw new CMSException("can't re-encode CRL!", ex);
            }
        }
    }

    AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId)
    {
        if (algId.getParameters() == null)
        {
            return new AlgorithmIdentifier(algId.getObjectId(), DERNull.INSTANCE);
        }

        return algId;
    }

    void setSigningEncryptionAlgorithmMapping(DERObjectIdentifier oid, String algorithmName)
    {
        encryptionAlgs.put(oid.getId(), algorithmName);
    }

    void setSigningDigestAlgorithmMapping(DERObjectIdentifier oid, String algorithmName)
    {
        digestAlgs.put(oid.getId(), algorithmName);
    }
}
