/*
 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


package javax.security.cert;

import java.io.InputStream;
import java.lang.Class;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.Security;

import java.math.BigInteger;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PublicKey;
import java.util.BitSet;
import java.util.Date;

/**
 * Abstract class for X.509 v1 certificates. This provides a standard
 * way to access all the version 1 attributes of an X.509 certificate.
 * Attributes that are specific to X.509 v2 or v3 are not available
 * through this interface. Future API evolution will provide full access to
 * complete X.509 v3 attributes.
 * <p>
 * The basic X.509 format was defined by
 * ISO/IEC and ANSI X9 and is described below in ASN.1:
 * <pre>
 * Certificate  ::=  SEQUENCE  {
 *     tbsCertificate       TBSCertificate,
 *     signatureAlgorithm   AlgorithmIdentifier,
 *     signature            BIT STRING  }
 * </pre>
 * <p>
 * These certificates are widely used to support authentication and
 * other functionality in Internet security systems. Common applications
 * include Privacy Enhanced Mail (PEM), Transport Layer Security (SSL),
 * code signing for trusted software distribution, and Secure Electronic
 * Transactions (SET).
 * <p>
 * These certificates are managed and vouched for by <em>Certificate
 * Authorities</em> (CAs). CAs are services which create certificates by
 * placing data in the X.509 standard format and then digitally signing
 * that data. CAs act as trusted third parties, making introductions
 * between principals who have no direct knowledge of each other.
 * CA certificates are either signed by themselves, or by some other
 * CA such as a "root" CA.
 * <p>
 * The ASN.1 definition of <code>tbsCertificate</code> is:
 * <pre>
 * TBSCertificate  ::=  SEQUENCE  {
 *     version         [0]  EXPLICIT Version DEFAULT v1,
 *     serialNumber         CertificateSerialNumber,
 *     signature            AlgorithmIdentifier,
 *     issuer               Name,
 *     validity             Validity,
 *     subject              Name,
 *     subjectPublicKeyInfo SubjectPublicKeyInfo,
 *     }
 * </pre>
 * <p>
 * Here is sample code to instantiate an X.509 certificate:
 * <pre>
 * InputStream inStream = new FileInputStream("fileName-of-cert");
 * X509Certificate cert = X509Certificate.getInstance(inStream);
 * inStream.close();
 * </pre>
 * OR
 * <pre>
 * byte[] certData = &lt;certificate read from a file, say&gt;
 * X509Certificate cert = X509Certificate.getInstance(certData);
 * </pre>
 * <p>
 * In either case, the code that instantiates an X.509 certificate
 * consults the Java security properties file to locate the actual
 * implementation or instantiates a default implementation.
 * <p>
 * The Java security properties file is located in the file named
 * &lt;JAVA_HOME&gt;/lib/security/java.security.
 * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
 * and specifies the directory where the JRE is installed.
 * In the Security properties file, a default implementation
 * for X.509 v1 may be given such as:
 * <pre>
 * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
 * </pre>
 * <p>
 * The value of this <code>cert.provider.x509v1</code> property has to be
 * changed to instatiate another implementation. If this security
 * property is not set, a default implementation will be used.
 * Currently, due to possible security restrictions on access to
 * Security properties, this value is looked up and cached at class
 * initialization time and will fallback on a default implementation if
 * the Security property is not accessible.
 *
 * <p><em>Note: The classes in the package <code>javax.security.cert</code>
 * exist for compatibility with earlier versions of the
 * Java Secure Sockets Extension (JSSE). New applications should instead
 * use the standard Java SE certificate classes located in
 * <code>java.security.cert</code>.</em></p>
 *
 * @author Hemma Prafullchandra
 * @since 1.4
 * @see Certificate
 * @see java.security.cert.X509Extension
 */
public abstract class X509Certificate extends Certificate {

    /*
     * Constant to lookup in the Security properties file.
     * In the Security properties file the default implementation
     * for X.509 v3 is given as:
     * <pre>
     * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
     * </pre>
     */
    private static final String X509_PROVIDER = "cert.provider.x509v1";
    private static String X509Provider;

    static {
        X509Provider = AccessController.doPrivileged(
            new PrivilegedAction<String>() {
                public String run() {
                    return Security.getProperty(X509_PROVIDER);
                }
            }
        );
    }

    /**
     * Instantiates an X509Certificate object, and initializes it with
     * the data read from the input stream <code>inStream</code>.
     * The implementation (X509Certificate is an abstract class) is
     * provided by the class specified as the value of the
     * <code>cert.provider.x509v1</code>
     * property in the security properties file.
     *
     * <p>Note: Only one DER-encoded
     * certificate is expected to be in the input stream.
     * Also, all X509Certificate
     * subclasses must provide a constructor of the form:
     * <code><pre>
     * public &lt;subClass&gt;(InputStream inStream) ...
     * </pre></code>
     *
     * @param inStream an input stream with the data to be read to
     *        initialize the certificate.
     * @return an X509Certificate object initialized with the data
     *         from the input stream.
     * @exception CertificateException if a class initialization
     *            or certificate parsing error occurs.
     */
    public static final X509Certificate getInstance(InputStream inStream)
    throws CertificateException {
        return getInst((Object)inStream);
    }

    /**
     * Instantiates an X509Certificate object, and initializes it with
     * the specified byte array.
     * The implementation (X509Certificate is an abstract class) is
     * provided by the class specified as the value of the
     * <code>cert.provider.x509v1</code>
     * property in the security properties file.
     *
     * <p>Note: All X509Certificate
     * subclasses must provide a constructor of the form:
     * <code><pre>
     * public &lt;subClass&gt;(InputStream inStream) ...
     * </pre></code>
     *
     * @param certData a byte array containing the DER-encoded
     *        certificate.
     * @return an X509Certificate object initialized with the data
     *         from <code>certData</code>.
     * @exception CertificateException if a class initialization
     *            or certificate parsing error occurs.
     */
    public static final X509Certificate getInstance(byte[] certData)
    throws CertificateException {
        return getInst((Object)certData);
    }

    private static final X509Certificate getInst(Object value)
    throws CertificateException {
        /*
         * This turns out not to work for now. To run under JDK1.2 we would
         * need to call beginPrivileged() but we can't do that and run
         * under JDK1.1.
         */
        String className = X509Provider;
        if (className == null || className.length() == 0) {
            // shouldn't happen, but assume corrupted properties file
            // provide access to sun implementation
            className = "com.sun.security.cert.internal.x509.X509V1CertImpl";
        }
        try {
            Class[] params = null;
            if (value instanceof InputStream) {
                params = new Class[] { InputStream.class };
            } else if (value instanceof byte[]) {
                params = new Class[] { value.getClass() };
            } else
                throw new CertificateException("Unsupported argument type");
            Class<?> certClass = Class.forName(className);

            // get the appropriate constructor and instantiate it
            Constructor<?> cons = certClass.getConstructor(params);

            // get a new instance
            Object obj = cons.newInstance(new Object[] {value});
            return (X509Certificate)obj;

        } catch (ClassNotFoundException e) {
          throw new CertificateException("Could not find class: " + e);
        } catch (IllegalAccessException e) {
          throw new CertificateException("Could not access class: " + e);
        } catch (InstantiationException e) {
          throw new CertificateException("Problems instantiating: " + e);
        } catch (InvocationTargetException e) {
          throw new CertificateException("InvocationTargetException: "
                                         + e.getTargetException());
        } catch (NoSuchMethodException e) {
          throw new CertificateException("Could not find class method: "
                                          + e.getMessage());
        }
    }

    /**
     * Checks that the certificate is currently valid. It is if
     * the current date and time are within the validity period given in the
     * certificate.
     * <p>
     * The validity period consists of two date/time values:
     * the first and last dates (and times) on which the certificate
     * is valid. It is defined in
     * ASN.1 as:
     * <pre>
     * validity             Validity<p>
     * Validity ::= SEQUENCE {
     *     notBefore      CertificateValidityDate,
     *     notAfter       CertificateValidityDate }<p>
     * CertificateValidityDate ::= CHOICE {
     *     utcTime        UTCTime,
     *     generalTime    GeneralizedTime }
     * </pre>
     *
     * @exception CertificateExpiredException if the certificate has expired.
     * @exception CertificateNotYetValidException if the certificate is not
     *            yet valid.
     */
    public abstract void checkValidity()
        throws CertificateExpiredException, CertificateNotYetValidException;

    /**
     * Checks that the specified date is within the certificate's
     * validity period. In other words, this determines whether the
     * certificate would be valid at the specified date/time.
     *
     * @param date the Date to check against to see if this certificate
     *        is valid at that date/time.
     * @exception CertificateExpiredException if the certificate has expired
     *            with respect to the <code>date</code> supplied.
     * @exception CertificateNotYetValidException if the certificate is not
     *            yet valid with respect to the <code>date</code> supplied.
     * @see #checkValidity()
     */
    public abstract void checkValidity(Date date)
        throws CertificateExpiredException, CertificateNotYetValidException;

    /**
     * Gets the <code>version</code> (version number) value from the
     * certificate. The ASN.1 definition for this is:
     * <pre>
     * version         [0]  EXPLICIT Version DEFAULT v1<p>
     * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
     * </pre>
     *
     * @return the version number from the ASN.1 encoding, i.e. 0, 1 or 2.
     */
    public abstract int getVersion();

    /**
     * Gets the <code>serialNumber</code> value from the certificate.
     * The serial number is an integer assigned by the certification
     * authority to each certificate. It must be unique for each
     * certificate issued by a given CA (i.e., the issuer name and
     * serial number identify a unique certificate).
     * The ASN.1 definition for this is:
     * <pre>
     * serialNumber     CertificateSerialNumber<p>
     *
     * CertificateSerialNumber  ::=  INTEGER
     * </pre>
     *
     * @return the serial number.
     */
    public abstract BigInteger getSerialNumber();

    /**
     * Gets the <code>issuer</code> (issuer distinguished name) value from
     * the certificate. The issuer name identifies the entity that signed (and
     * issued) the certificate.
     *
     * <p>The issuer name field contains an
     * X.500 distinguished name (DN).
     * The ASN.1 definition for this is:
     * <pre>
     * issuer    Name<p>
     *
     * Name ::= CHOICE { RDNSequence }
     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
     * RelativeDistinguishedName ::=
     *     SET OF AttributeValueAssertion
     *
     * AttributeValueAssertion ::= SEQUENCE {
     *                               AttributeType,
     *                               AttributeValue }
     * AttributeType ::= OBJECT IDENTIFIER
     * AttributeValue ::= ANY
     * </pre>
     * The <code>Name</code> describes a hierarchical name composed of
     * attributes, such as country name, and corresponding values, such as US.
     * The type of the <code>AttributeValue</code> component is determined by
     * the <code>AttributeType</code>; in general it will be a
     * <code>directoryString</code>. A <code>directoryString</code> is usually
     * one of <code>PrintableString</code>,
     * <code>TeletexString</code> or <code>UniversalString</code>.
     *
     * @return a Principal whose name is the issuer distinguished name.
     */
    public abstract Principal getIssuerDN();

    /**
     * Gets the <code>subject</code> (subject distinguished name) value
     * from the certificate.
     * The ASN.1 definition for this is:
     * <pre>
     * subject    Name
     * </pre>
     *
     * <p>See {@link #getIssuerDN() getIssuerDN} for <code>Name</code>
     * and other relevant definitions.
     *
     * @return a Principal whose name is the subject name.
     * @see #getIssuerDN()
     */
    public abstract Principal getSubjectDN();

    /**
     * Gets the <code>notBefore</code> date from the validity period of
     * the certificate.
     * The relevant ASN.1 definitions are:
     * <pre>
     * validity             Validity<p>
     *
     * Validity ::= SEQUENCE {
     *     notBefore      CertificateValidityDate,
     *     notAfter       CertificateValidityDate }<p>
     * CertificateValidityDate ::= CHOICE {
     *     utcTime        UTCTime,
     *     generalTime    GeneralizedTime }
     * </pre>
     *
     * @return the start date of the validity period.
     * @see #checkValidity()
     */
    public abstract Date getNotBefore();

    /**
     * Gets the <code>notAfter</code> date from the validity period of
     * the certificate. See {@link #getNotBefore() getNotBefore}
     * for relevant ASN.1 definitions.
     *
     * @return the end date of the validity period.
     * @see #checkValidity()
     */
    public abstract Date getNotAfter();

    /**
     * Gets the signature algorithm name for the certificate
     * signature algorithm. An example is the string "SHA-1/DSA".
     * The ASN.1 definition for this is:
     * <pre>
     * signatureAlgorithm   AlgorithmIdentifier<p>
     * AlgorithmIdentifier  ::=  SEQUENCE  {
     *     algorithm               OBJECT IDENTIFIER,
     *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
     *                             -- contains a value of the type
     *                             -- registered for use with the
     *                             -- algorithm object identifier value
     * </pre>
     *
     * <p>The algorithm name is determined from the <code>algorithm</code>
     * OID string.
     *
     * @return the signature algorithm name.
     */
    public abstract String getSigAlgName();

    /**
     * Gets the signature algorithm OID string from the certificate.
     * An OID is represented by a set of positive whole numbers separated
     * by periods.
     * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
     * with DSA signature algorithm, as per the PKIX part I.
     *
     * <p>See {@link #getSigAlgName() getSigAlgName} for
     * relevant ASN.1 definitions.
     *
     * @return the signature algorithm OID string.
     */
    public abstract String getSigAlgOID();

    /**
     * Gets the DER-encoded signature algorithm parameters from this
     * certificate's signature algorithm. In most cases, the signature
     * algorithm parameters are null; the parameters are usually
     * supplied with the certificate's public key.
     *
     * <p>See {@link #getSigAlgName() getSigAlgName} for
     * relevant ASN.1 definitions.
     *
     * @return the DER-encoded signature algorithm parameters, or
     *         null if no parameters are present.
     */
    public abstract byte[] getSigAlgParams();
}
