/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.wss4j.common.crypto;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertificateEncodingException;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.x500.X500Principal;

import org.apache.wss4j.common.ext.WSSecurityException;

/**
 * A Crypto implementation based on a simple array of X509Certificate(s). PrivateKeys are not
 * supported, so this cannot be used for signature creation, or decryption.
 */
public class CertificateStore extends CryptoBase {

    private static final org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(CertificateStore.class);

    private X509Certificate[] trustedCerts;

    /**
     * Constructor
     */
    public CertificateStore(X509Certificate[] trustedCerts) {
        this.trustedCerts = trustedCerts;
    }

    /**
     * Get an X509Certificate (chain) corresponding to the CryptoType argument. The supported
     * types are as follows:
     *
     * TYPE.ISSUER_SERIAL - A certificate (chain) is located by the issuer name and serial number
     * TYPE.THUMBPRINT_SHA1 - A certificate (chain) is located by the SHA1 of the (root) cert
     * TYPE.SKI_BYTES - A certificate (chain) is located by the SKI bytes of the (root) cert
     * TYPE.SUBJECT_DN - A certificate (chain) is located by the Subject DN of the (root) cert
     * Note that TYPE.ALIAS is not allowed, as it doesn't have any meaning with a CertificateStore
     */
    public X509Certificate[] getX509Certificates(CryptoType cryptoType) throws WSSecurityException {
        if (cryptoType == null) {
            return null;
        }
        CryptoType.TYPE type = cryptoType.getType();
        X509Certificate[] certs = null;
        switch (type) {
        case ISSUER_SERIAL:
            certs = getX509Certificates(cryptoType.getIssuer(), cryptoType.getSerial());
            break;
        case THUMBPRINT_SHA1:
            certs = getX509Certificates(cryptoType.getBytes());
            break;
        case SKI_BYTES:
            certs = getX509CertificatesSKI(cryptoType.getBytes());
            break;
        case SUBJECT_DN:
            certs = getX509CertificatesSubjectDN(cryptoType.getSubjectDN());
            break;
        case ALIAS:
            throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE, "generic.EmptyMessage",
                    new Object[] {"The alias CryptoType is not allowed for CertificateStore"}
            );
        case ENDPOINT:
            break;
        }
        return certs;
    }

    /**
     * Get the implementation-specific identifier corresponding to the cert parameter. In this
     * case, the identifier refers to the subject DN.
     * @param cert The X509Certificate for which to search for an identifier
     * @return the identifier corresponding to the cert parameter
     * @throws WSSecurityException
     */
    public String getX509Identifier(X509Certificate cert) throws WSSecurityException {
        return cert.getSubjectDN().toString();
    }

    /**
     * Gets the private key corresponding to the certificate. Not supported.
     *
     * @param certificate The X509Certificate corresponding to the private key
     * @param callbackHandler The callbackHandler needed to get the password
     * @return The private key
     */
    public PrivateKey getPrivateKey(
        X509Certificate certificate, CallbackHandler callbackHandler
    ) throws WSSecurityException {
        return null;
    }

    /**
     * Gets the private key corresponding to the given PublicKey.
     *
     * @param publicKey The PublicKey corresponding to the private key
     * @param callbackHandler The callbackHandler needed to get the password
     * @return The private key
     */
    public PrivateKey getPrivateKey(
        PublicKey publicKey,
        CallbackHandler callbackHandler
    ) throws WSSecurityException {
        return null;
    }

    /**
     * Gets the private key corresponding to the identifier. Not supported.
     *
     * @param identifier The implementation-specific identifier corresponding to the key
     * @param password The password needed to get the key
     * @return The private key
     */
    public PrivateKey getPrivateKey(
        String identifier,
        String password
    ) throws WSSecurityException {
        return null;
    }

    /**
     * Evaluate whether a given certificate chain should be trusted.
     *
     * @param certs Certificate chain to validate
     * @param enableRevocation whether to enable CRL verification or not
     * @param subjectCertConstraints A set of constraints on the Subject DN of the certificates
     * @throws WSSecurityException if the certificate chain is invalid
     */
    protected void verifyTrust(
        X509Certificate[] certs,
        boolean enableRevocation,
        Collection<Pattern> subjectCertConstraints
    ) throws WSSecurityException {
        //
        // FIRST step - Search the trusted certs for the transmitted certificate
        //
        if (certs.length == 1 && !enableRevocation) {
            String issuerString = certs[0].getIssuerX500Principal().getName();
            BigInteger issuerSerial = certs[0].getSerialNumber();

            CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ISSUER_SERIAL);
            cryptoType.setIssuerSerial(issuerString, issuerSerial);
            X509Certificate[] foundCerts = getX509Certificates(cryptoType);

            //
            // If a certificate has been found, the certificates must be compared
            // to ensure against phony DNs (compare encoded form including signature)
            //
            if (foundCerts != null && foundCerts[0] != null && foundCerts[0].equals(certs[0])) {
                LOG.debug(
                    "Direct trust for certificate with {}", certs[0].getSubjectX500Principal().getName()
                );
                return;
            }
        }


        //
        // SECOND step - Search for the issuer cert (chain) of the transmitted certificate in the
        // keystore or the truststore
        //
        String issuerString = certs[0].getIssuerX500Principal().getName();
        X509Certificate[] foundCerts = new X509Certificate[0];
        if (certs.length == 1) {
            CryptoType cryptoType = new CryptoType(CryptoType.TYPE.SUBJECT_DN);
            cryptoType.setSubjectDN(issuerString);
            foundCerts = getX509Certificates(cryptoType);

            // If the certs have not been found, the issuer is not in the keystore/truststore
            // As a direct result, do not trust the transmitted certificate
            if (foundCerts == null || foundCerts.length < 1) {
                String subjectString = certs[0].getSubjectX500Principal().getName();
                LOG.debug(
                    "No certs found in keystore for issuer {} of certificate for {}", issuerString, subjectString
                );
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE, "certpath",
                    new Object[] {"No trusted certs found"}
                );
            }
        }

        //
        // THIRD step
        // Check the certificate trust path for the issuer cert chain
        //
        LOG.debug(
            "Preparing to validate certificate path for issuer {}", issuerString
        );

        try {
            Set<TrustAnchor> set = new HashSet<>();
            if (trustedCerts != null) {
                for (X509Certificate cert : trustedCerts) {
                    TrustAnchor anchor =
                        new TrustAnchor(cert, null);
                    set.add(anchor);
                }
            }

            // Verify the trust path using the above settings
            String provider = getCryptoProvider();
            CertPathValidator validator = null;
            if (provider == null || provider.length() == 0) {
                validator = CertPathValidator.getInstance("PKIX");
            } else {
                validator = CertPathValidator.getInstance("PKIX", provider);
            }

            PKIXParameters param = new PKIXParameters(set);
            param.setRevocationEnabled(enableRevocation);

            if (foundCerts.length > 0) {
                //
                // Form a certificate chain from the transmitted certificate
                // and the certificate(s) of the issuer from the keystore/truststore
                //
                X509Certificate[] x509certs = new X509Certificate[foundCerts.length + 1];
                x509certs[0] = certs[0];
                System.arraycopy(foundCerts, 0, x509certs, 1, foundCerts.length);

                // Generate cert path
                List<X509Certificate> certList = Arrays.asList(x509certs);
                CertPath path = getCertificateFactory().generateCertPath(certList);

                validator.validate(path, param);
            } else {
                List<X509Certificate> certList = Arrays.asList(certs);
                CertPath path = getCertificateFactory().generateCertPath(certList);

                validator.validate(path, param);
            }
        } catch (java.security.NoSuchProviderException | NoSuchAlgorithmException
            | java.security.cert.CertificateException
            | java.security.InvalidAlgorithmParameterException
            | java.security.cert.CertPathValidatorException e) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE, e, "certpath",
                    new Object[] {e.getMessage()}
                );
        }

        // Finally check Cert Constraints
        if (!matchesSubjectDnPattern(certs[0], subjectCertConstraints)) {
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
        }
    }

    @Override
    public void verifyTrust(X509Certificate[] certs, boolean enableRevocation, Collection<Pattern> subjectCertConstraints,
                            Collection<Pattern> issuerCertConstraints) throws WSSecurityException {
        verifyTrust(certs, enableRevocation, subjectCertConstraints);
        if (!matchesIssuerDnPattern(certs[0], issuerCertConstraints)) {
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
        }
    }

    /**
     * Evaluate whether a given public key should be trusted.
     *
     * @param publicKey The PublicKey to be evaluated
     * @throws WSSecurityException if the PublicKey is invalid
     */
    public void verifyTrust(PublicKey publicKey) throws WSSecurityException {
        //
        // If the public key is null, do not trust the signature
        //
        if (publicKey == null) {
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
        }

        //
        // Search the trusted certs for the transmitted public key (direct trust)
        //
        for (X509Certificate trustedCert : trustedCerts) {
            if (publicKey.equals(trustedCert.getPublicKey())) {
                return;
            }
        }
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
    }

    /**
     * Get an X509 Certificate (chain) according to a given serial number and issuer string.
     *
     * @param issuer The Issuer String
     * @param serialNumber The serial number of the certificate
     * @return the X509 Certificate (chain) that was found
     * @throws WSSecurityException
     */
    private X509Certificate[] getX509Certificates(
        String issuer,
        BigInteger serialNumber
    ) throws WSSecurityException {
        //
        // Convert the subject DN to a java X500Principal object first. This is to ensure
        // interop with a DN constructed from .NET, where e.g. it uses "S" instead of "ST".
        // Then convert it to a BouncyCastle X509Name, which will order the attributes of
        // the DN in a particular way (see WSS-168). If the conversion to an X500Principal
        // object fails (e.g. if the DN contains "E" instead of "EMAILADDRESS"), then fall
        // back on a direct conversion to a BC X509Name
        //
        Object issuerName = null;
        try {
            X500Principal issuerRDN = new X500Principal(issuer);
            issuerName = createBCX509Name(issuerRDN.getName());
        } catch (IllegalArgumentException ex) {
            issuerName = createBCX509Name(issuer);
        }

        for (X509Certificate trustedCert : trustedCerts) {
            if (trustedCert.getSerialNumber().compareTo(serialNumber) == 0) {
                Object certName =
                    createBCX509Name(trustedCert.getIssuerX500Principal().getName());
                if (certName.equals(issuerName)) {
                    return new X509Certificate[]{trustedCert};
                }
            }
        }

        return null;
    }

    /**
     * Get an X509 Certificate (chain) according to a given Thumbprint.
     *
     * @param thumb The SHA1 thumbprint info bytes
     * @return the X509 certificate (chain) that was found (can be null)
     * @throws WSSecurityException if problems during keystore handling or wrong certificate
     */
    private X509Certificate[] getX509Certificates(byte[] thumb) throws WSSecurityException {
        MessageDigest sha = null;

        if (trustedCerts == null) {
            return null;
        }

        try {
            sha = MessageDigest.getInstance("SHA1");
        } catch (NoSuchAlgorithmException e) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.FAILURE, e, "decoding.general"
            );
        }
        for (X509Certificate trustedCert : trustedCerts) {
            try {
                sha.update(trustedCert.getEncoded());
            } catch (CertificateEncodingException ex) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, ex, "encodeError"
                );
            }
            byte[] data = sha.digest();

            if (Arrays.equals(data, thumb)) {
                return new X509Certificate[]{trustedCert};
            }
        }
        return null;
    }

    /**
     * Get an X509 Certificate (chain) according to a given SubjectKeyIdentifier.
     *
     * @param skiBytes The SKI bytes
     * @return the X509 certificate (chain) that was found (can be null)
     */
    private X509Certificate[] getX509CertificatesSKI(byte[] skiBytes) throws WSSecurityException {
        if (trustedCerts == null) {
            return null;
        }
        for (X509Certificate trustedCert : trustedCerts) {
            byte[] data = getSKIBytesFromCert(trustedCert);
            if (data.length == skiBytes.length && Arrays.equals(data, skiBytes)) {
                return new X509Certificate[]{trustedCert};
            }
        }
        return null;
    }

    /**
     * Get an X509 Certificate (chain) according to a given DN of the subject of the certificate
     *
     * @param subjectDN The DN of subject to look for
     * @return An X509 Certificate (chain) with the same DN as given in the parameters
     * @throws WSSecurityException
     */
    private X509Certificate[] getX509CertificatesSubjectDN(String subjectDN)
        throws WSSecurityException {
        //
        // Convert the subject DN to a java X500Principal object first. This is to ensure
        // interop with a DN constructed from .NET, where e.g. it uses "S" instead of "ST".
        // Then convert it to a BouncyCastle X509Name, which will order the attributes of
        // the DN in a particular way (see WSS-168). If the conversion to an X500Principal
        // object fails (e.g. if the DN contains "E" instead of "EMAILADDRESS"), then fall
        // back on a direct conversion to a BC X509Name
        //
        Object subject;
        try {
            X500Principal subjectRDN = new X500Principal(subjectDN);
            subject = createBCX509Name(subjectRDN.getName());
        } catch (IllegalArgumentException ex) {
            subject = createBCX509Name(subjectDN);
        }

        if (trustedCerts != null) {
            for (X509Certificate trustedCert : trustedCerts) {
                X500Principal foundRDN = trustedCert.getSubjectX500Principal();
                Object certName = createBCX509Name(foundRDN.getName());

                if (subject.equals(certName)) {
                    return new X509Certificate[]{trustedCert};
                }
            }
        }

        return null;
    }

}
