/**
 * 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.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.security.MessageDigest;
import java.security.NoSuchProviderException;
import java.security.cert.CertPath;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.security.auth.x500.X500Principal;

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

/**
 * This Abstract Base Class implements the accessor and keystore-independent methods and
 * functionality of the Crypto interface.
 */
public abstract class CryptoBase implements Crypto {
    public static final String SKI_OID = "2.5.29.14";  //NOPMD - not an IP address
    /**
     * OID For the NameConstraints Extension to X.509
     *
     * http://java.sun.com/j2se/1.4.2/docs/api/
     * http://www.ietf.org/rfc/rfc3280.txt (s. 4.2.1.11)
     */
    public static final String NAME_CONSTRAINTS_OID = "2.5.29.30";  //NOPMD - not an IP address

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

    private static final Constructor<?> BC_509CLASS_CONS;

    protected CertificateFactory certificateFactory;
    private String defaultAlias;
    private String cryptoProvider;
    private String trustProvider;

    static {
        Constructor<?> cons = null;
        try {
            Class<?> c = Class.forName("org.bouncycastle.asn1.x500.X500Name");
            cons = c.getConstructor(new Class[] {String.class});
        } catch (Exception e) { //NOPMD
          //ignore
        }
        BC_509CLASS_CONS = cons;
    }

    /**
     * Constructor
     */
    protected CryptoBase() {
    }

    /**
     * Get the crypto provider associated with this implementation
     * @return the crypto provider
     */
    public String getCryptoProvider() {
        return cryptoProvider;
    }

    /**
     * Set the crypto provider associated with this implementation
     * @param provider the crypto provider to set
     */
    public void setCryptoProvider(String provider) {
        cryptoProvider = provider;
    }

    /**
     * Set the crypto provider used for truststore operations associated with this implementation
     * @param provider the name of the provider
     */
    public void setTrustProvider(String provider) {
        trustProvider = provider;
    }

    /**
     * Get the crypto provider used for truststore operation associated with this implementation.
     * @return a crypto provider name
     */
    public String getTrustProvider() {
        return trustProvider;
    }

    /**
     * Retrieves the identifier name of the default certificate. This should be the certificate
     * that is used for signature and encryption. This identifier corresponds to the certificate
     * that should be used whenever KeyInfo is not present in a signed or an encrypted
     * message. May return null. The identifier is implementation specific, e.g. it could be the
     * KeyStore alias.
     *
     * @return name of the default X509 certificate.
     */
    public String getDefaultX509Identifier() throws WSSecurityException {
        return defaultAlias;
    }

    /**
     * Sets the identifier name of the default certificate. This should be the certificate
     * that is used for signature and encryption. This identifier corresponds to the certificate
     * that should be used whenever KeyInfo is not present in a signed or an encrypted
     * message. The identifier is implementation specific, e.g. it could be the KeyStore alias.
     *
     * @param identifier name of the default X509 certificate.
     */
    public void setDefaultX509Identifier(String identifier) {
        defaultAlias = identifier;
    }

    /**
     * Sets the CertificateFactory instance on this Crypto instance
     *
     * @param certFactory the CertificateFactory the CertificateFactory instance to set
     */
    public void setCertificateFactory(CertificateFactory certFactory) {
        this.certificateFactory = certFactory;
    }

    /**
     * Get the CertificateFactory instance on this Crypto instance
     *
     * @return Returns a <code>CertificateFactory</code> to construct
     *         X509 certificates
     * @throws WSSecurityException
     */
    public CertificateFactory getCertificateFactory() throws WSSecurityException {
        if (certificateFactory != null) {
            return certificateFactory;
        }

        try {
            String provider = getCryptoProvider();
            if (provider == null || provider.length() == 0) {
                certificateFactory = CertificateFactory.getInstance("X.509");
            } else {
                certificateFactory = CertificateFactory.getInstance("X.509", provider);
            }
        } catch (CertificateException e) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "unsupportedCertType"
            );
        } catch (NoSuchProviderException e) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "noSecProvider"
            );
        }

        return certificateFactory;
    }

    /**
     * Load a X509Certificate from the input stream.
     *
     * @param in The <code>InputStream</code> containing the X509Certificate
     * @return An X509 certificate
     * @throws WSSecurityException
     */
    public X509Certificate loadCertificate(InputStream in) throws WSSecurityException {
        try {
            CertificateFactory certFactory = getCertificateFactory();
            return (X509Certificate) certFactory.generateCertificate(in);
        } catch (CertificateException e) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "parseError"
            );
        }
    }

    /**
     * Reads the SubjectKeyIdentifier information from the certificate.
     * <p/>
     * If the the certificate does not contain a SKI extension then
     * try to compute the SKI according to RFC3280 using the
     * SHA-1 hash value of the public key. The second method described
     * in RFC3280 is not support. Also only RSA public keys are supported.
     * If we cannot compute the SKI throw a WSSecurityException.
     *
     * @param cert The certificate to read SKI
     * @return The byte array containing the binary SKI data
     */
    public byte[] getSKIBytesFromCert(X509Certificate cert) throws WSSecurityException {
        //
        // Gets the DER-encoded OCTET string for the extension value (extnValue)
        // identified by the passed-in oid String. The oid string is represented
        // by a set of positive whole numbers separated by periods.
        //
        byte[] derEncodedValue = cert.getExtensionValue(SKI_OID);

        if (cert.getVersion() < 3 || derEncodedValue == null) {
            X509SubjectPublicKeyInfo spki = new X509SubjectPublicKeyInfo(cert.getPublicKey());
            byte[] value = spki.getSubjectPublicKey();
            try {
                MessageDigest digest = MessageDigest.getInstance("SHA-1");
                return digest.digest(value);
            } catch (Exception ex) {
                throw new WSSecurityException(
                    WSSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN, ex, "noSKIHandling",
                    new Object[] {"No SKI certificate extension and no SHA1 message digest available"}
                );
            }
        }

        //
        // Strip away first (four) bytes from the DerValue (tag and length of
        // ExtensionValue OCTET STRING and KeyIdentifier OCTET STRING)
        //
        DERDecoder extVal = new DERDecoder(derEncodedValue);
        extVal.expect(DERDecoder.TYPE_OCTET_STRING);  // ExtensionValue OCTET STRING
        extVal.getLength();
        extVal.expect(DERDecoder.TYPE_OCTET_STRING);  // KeyIdentifier OCTET STRING
        int keyIDLen = extVal.getLength();
        return extVal.getBytes(keyIDLen);
    }

    /**
     * Get a byte array given an array of X509 certificates.
     * <p/>
     *
     * @param certs The certificates to convert
     * @return The byte array for the certificates
     * @throws WSSecurityException
     */
    public byte[] getBytesFromCertificates(X509Certificate[] certs)
        throws WSSecurityException {
        try {
            CertPath path = getCertificateFactory().generateCertPath(Arrays.asList(certs));
            return path.getEncoded();
        } catch (CertificateEncodingException e) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "encodeError"
            );
        } catch (CertificateException e) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "parseError"
            );
        }
    }

    /**
     * Construct an array of X509Certificate's from the byte array.
     * <p/>
     *
     * @param data The <code>byte</code> array containing the X509 data
     * @return An array of X509 certificates
     * @throws WSSecurityException
     */
    public X509Certificate[] getCertificatesFromBytes(byte[] data)
        throws WSSecurityException {
        CertPath path = null;
        try (InputStream in = new ByteArrayInputStream(data)) {
            path = getCertificateFactory().generateCertPath(in);
        } catch (CertificateException | IOException e) {
            throw new WSSecurityException(
                WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "parseError"
            );
        }

        List<?> l = path.getCertificates();
        X509Certificate[] certs = new X509Certificate[l.size()];
        int i = 0;
        for (Object cert : l) {
            certs[i++] = (X509Certificate) cert;
        }
        return certs;
    }

    protected Object createBCX509Name(String s) {
        if (BC_509CLASS_CONS != null) {
             try {
                 return BC_509CLASS_CONS.newInstance(s);
             } catch (Exception e) { //NOPMD
                 //ignore
             }
        }
        return new X500Principal(s);
    }

    /**
     * @return      true if the certificate's SubjectDN matches the constraints defined in the
     *              subject DNConstraints; false, otherwise. The certificate subject DN only
     *              has to match ONE of the subject cert constraints (not all).
     */
    protected boolean
    matchesSubjectDnPattern(
        final X509Certificate cert, final Collection<Pattern> subjectDNPatterns
    ) {
        if (cert == null) {
            LOG.debug("The certificate is null so no constraints matching was possible");
            return false;
        }
        String subjectName = cert.getSubjectX500Principal().getName();
        if (subjectDNPatterns == null || subjectDNPatterns.isEmpty()) {
            LOG.warn("No Subject DN Certificate Constraints were defined. This could be a security issue");
            return true;
        }
        return matchesName(subjectName, subjectDNPatterns);
    }

    /**
     * @return      true if the certificate's Issuer DN matches the constraints defined in the
     *              subject DNConstraints; false, otherwise. The certificate subject DN only
     *              has to match ONE of the subject cert constraints (not all).
     */
    protected boolean
    matchesIssuerDnPattern(
        final X509Certificate cert, final Collection<Pattern> issuerDNPatterns
    ) {
        if (cert == null) {
            LOG.debug("The certificate is null so no constraints matching was possible");
            return false;
        }
        String issuerDn = cert.getIssuerDN().getName();
        return matchesName(issuerDn, issuerDNPatterns);
    }

    /**
     * @return      true if the provided name matches the constraints defined in the
     *              subject DNConstraints; false, otherwise. The certificate (subject) DN only
     *              has to match ONE of the (subject) cert constraints (not all).
     */
    protected boolean
    matchesName(
        final String name, final Collection<Pattern> patterns
    ) {
        if (patterns != null && !patterns.isEmpty()) {
            if (name == null || name.isEmpty()) {
                LOG.debug("The name is null so no constraints matching was possible");
                return false;
            }
            boolean subjectMatch = false;
            for (Pattern subjectDNPattern : patterns) {
                final Matcher matcher = subjectDNPattern.matcher(name);
                if (matcher.matches()) {
                    LOG.debug("Name {} matches with pattern {}", name, subjectDNPattern);
                    subjectMatch = true;
                    break;
                }
            }
            if (!subjectMatch) {
                return false;
            }
        }

        return true;
    }

    /**
     * Extracts the NameConstraints sequence from the certificate.
     * Handles the case where the data is encoded directly as {@link DERDecoder#TYPE_SEQUENCE}
     * or where the sequence has been encoded as an {@link DERDecoder#TYPE_OCTET_STRING}.
     * <p>
     * By contract, the values retrieved from calls to {@link X509Certificate#getExtensionValue(String)}
     * should always be DER-encoded OCTET strings; however, because of ambiguity in the RFC and
     * the potential for a future breaking change to this contract, testing whether the bytes
     * returned are tagged as a sequence or an encoded octet string is prudent. Considering the fact
     * that it is a single byte comparison, the performance hit is negligible.
     *
     * @param cert the certificate to extract NameConstraints from
     * @return the NameConstraints, or null if not present
     * @throws WSSecurityException if a processing error occurs decoding the Octet String
     */
    protected byte[] getNameConstraints(final X509Certificate cert) throws WSSecurityException {
        byte[] bytes = cert.getExtensionValue(NAME_CONSTRAINTS_OID);
        if (bytes == null || bytes.length <= 0) {
            return null;
        }

        switch (bytes[0]) {
            case DERDecoder.TYPE_OCTET_STRING:
                DERDecoder extVal = new DERDecoder(bytes);
                extVal.expect(DERDecoder.TYPE_OCTET_STRING);
                int seqLen = extVal.getLength();
                return extVal.getBytes(seqLen);
            case DERDecoder.TYPE_SEQUENCE:
                return bytes;
            default:
                throw new IllegalArgumentException(
                        "Invalid type for NameConstraints; must be Sequence or OctetString-encoded Sequence");
        }
    }
}
