/*
 * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.security.validator;

import java.util.*;

import java.security.KeyStore;
import java.security.cert.*;

/**
 * Validator abstract base class. Concrete classes are instantiated by calling
 * one of the getInstance() methods. All methods defined in this class
 * must be safe for concurrent use by multiple threads.<p>
 *
 * The model is that a Validator instance is created specifying validation
 * settings, such as trust anchors or PKIX parameters. Then one or more
 * paths are validated using those parameters. In some cases, additional
 * information can be provided per path validation. This is independent of
 * the validation parameters and currently only used for TLS server validation.
 * <p>
 * Path validation is performed by calling one of the validate() methods. It
 * specifies a suggested path to be used for validation if available, or only
 * the end entity certificate otherwise. Optionally additional certificates can
 * be specified that the caller believes could be helpful. Implementations are
 * free to make use of this information or validate the path using other means.
 * validate() also checks that the end entity certificate is suitable for the
 * intended purpose as described below.
 *
 * <p>There are two orthogonal parameters to select the Validator
 * implementation: type and variant. Type selects the validation algorithm.
 * Currently supported are TYPE_SIMPLE and TYPE_PKIX. See SimpleValidator and
 * PKIXValidator for details.
 * <p>
 * Variant controls additional extension checks. Currently supported are
 * five variants:
 * <ul>
 * <li>VAR_GENERIC (no additional checks),
 * <li>VAR_TLS_CLIENT (TLS client specific checks)
 * <li>VAR_TLS_SERVER (TLS server specific checks), and
 * <li>VAR_CODE_SIGNING (code signing specific checks).
 * <li>VAR_JCE_SIGNING (JCE code signing specific checks).
 * <li>VAR_TSA_SERVER (TSA server specific checks).
 * <li>VAR_PLUGIN_CODE_SIGNING (Plugin/WebStart code signing specific checks).
 * </ul>
 * See EndEntityChecker for more information.
 * <p>
 * Examples:
 * <pre>
 *   // instantiate validator specifying type, variant, and trust anchors
 *   Validator validator = Validator.getInstance(Validator.TYPE_PKIX,
 *                                               Validator.VAR_TLS_CLIENT,
 *                                               trustedCerts);
 *   // validate one or more chains using the validator
 *   validator.validate(chain); // throws CertificateException if failed
 * </pre>
 *
 * @see SimpleValidator
 * @see PKIXValidator
 * @see EndEntityChecker
 *
 * @author Andreas Sterbenz
 */
public abstract class Validator {

    final static X509Certificate[] CHAIN0 = {};

    /**
     * Constant for a validator of type Simple.
     * @see #getInstance
     */
    public final static String TYPE_SIMPLE = "Simple";

    /**
     * Constant for a validator of type PKIX.
     * @see #getInstance
     */
    public final static String TYPE_PKIX = "PKIX";

    /**
     * Constant for a Generic variant of a validator.
     * @see #getInstance
     */
    public final static String VAR_GENERIC = "generic";

    /**
     * Constant for a Code Signing variant of a validator.
     * @see #getInstance
     */
    public final static String VAR_CODE_SIGNING = "code signing";

    /**
     * Constant for a JCE Code Signing variant of a validator.
     * @see #getInstance
     */
    public final static String VAR_JCE_SIGNING = "jce signing";

    /**
     * Constant for a TLS Client variant of a validator.
     * @see #getInstance
     */
    public final static String VAR_TLS_CLIENT = "tls client";

    /**
     * Constant for a TLS Server variant of a validator.
     * @see #getInstance
     */
    public final static String VAR_TLS_SERVER = "tls server";

    /**
     * Constant for a TSA Server variant of a validator.
     * @see #getInstance
     */
    public final static String VAR_TSA_SERVER = "tsa server";

    /**
     * Constant for a Code Signing variant of a validator for use by
     * the J2SE Plugin/WebStart code.
     * @see #getInstance
     */
    public final static String VAR_PLUGIN_CODE_SIGNING = "plugin code signing";

    final EndEntityChecker endEntityChecker;
    final String variant;

    /**
     * @deprecated
     * @see #setValidationDate
     */
    @Deprecated
    volatile Date validationDate;

    Validator(String type, String variant) {
        this.variant = variant;
        endEntityChecker = EndEntityChecker.getInstance(type, variant);
    }

    /**
     * Get a new Validator instance using the trusted certificates from the
     * specified KeyStore as trust anchors.
     */
    public static Validator getInstance(String type, String variant,
            KeyStore ks) {
        return getInstance(type, variant, KeyStores.getTrustedCerts(ks));
    }

    /**
     * Get a new Validator instance using the Set of X509Certificates as trust
     * anchors.
     */
    public static Validator getInstance(String type, String variant,
            Collection<X509Certificate> trustedCerts) {
        if (type.equals(TYPE_SIMPLE)) {
            return new SimpleValidator(variant, trustedCerts);
        } else if (type.equals(TYPE_PKIX)) {
            return new PKIXValidator(variant, trustedCerts);
        } else {
            throw new IllegalArgumentException
                ("Unknown validator type: " + type);
        }
    }

    /**
     * Get a new Validator instance using the provided PKIXBuilderParameters.
     * This method can only be used with the PKIX validator.
     */
    public static Validator getInstance(String type, String variant,
            PKIXBuilderParameters params) {
        if (type.equals(TYPE_PKIX) == false) {
            throw new IllegalArgumentException
                ("getInstance(PKIXBuilderParameters) can only be used "
                + "with PKIX validator");
        }
        return new PKIXValidator(variant, params);
    }

    /**
     * Validate the given certificate chain.
     */
    public final X509Certificate[] validate(X509Certificate[] chain)
            throws CertificateException {
        return validate(chain, null, null);
    }

    /**
     * Validate the given certificate chain. If otherCerts is non-null, it is
     * a Collection of additional X509Certificates that could be helpful for
     * path building.
     */
    public final X509Certificate[] validate(X509Certificate[] chain,
        Collection<X509Certificate> otherCerts) throws CertificateException {
        return validate(chain, otherCerts, null);
    }

    /**
     * Validate the given certificate chain. If otherCerts is non-null, it is
     * a Collection of additional X509Certificates that could be helpful for
     * path building.
     * <p>
     * Parameter is an additional parameter with variant specific meaning.
     * Currently, it is only defined for TLS_SERVER variant validators, where
     * it must be non null and the name of the TLS key exchange algorithm being
     * used (see JSSE X509TrustManager specification). In the future, it
     * could be used to pass in a PKCS#7 object for code signing to check time
     * stamps.
     * <p>
     * @return a non-empty chain that was used to validate the path. The
     * end entity cert is at index 0, the trust anchor at index n-1.
     */
    public final X509Certificate[] validate(X509Certificate[] chain,
            Collection<X509Certificate> otherCerts, Object parameter)
            throws CertificateException {
        chain = engineValidate(chain, otherCerts, parameter);
        // omit EE extension check if EE cert is also trust anchor
        if (chain.length > 1) {
            endEntityChecker.check(chain[0], parameter);
        }
        return chain;
    }

    abstract X509Certificate[] engineValidate(X509Certificate[] chain,
        Collection<X509Certificate> otherCerts, Object parameter) throws CertificateException;

    /**
     * Returns an immutable Collection of the X509Certificates this instance
     * uses as trust anchors.
     */
    public abstract Collection<X509Certificate> getTrustedCertificates();

    /**
     * Set the date to be used for subsequent validations. NOTE that
     * this is not a supported API, it is provided to simplify
     * writing tests only.
     *
     * @deprecated
     */
    @Deprecated
    public void setValidationDate(Date validationDate) {
        this.validationDate = validationDate;
    }

}
