Home | History | Annotate | Download | only in cert
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 
     28 package javax.security.cert;
     29 
     30 import com.sun.security.cert.internal.x509.X509V1CertImpl;
     31 
     32 import java.io.InputStream;
     33 import java.lang.Class;
     34 import java.lang.reflect.Constructor;
     35 import java.lang.reflect.InvocationTargetException;
     36 import java.security.Security;
     37 
     38 import java.math.BigInteger;
     39 import java.security.AccessController;
     40 import java.security.Principal;
     41 import java.security.PrivilegedAction;
     42 import java.security.PublicKey;
     43 import java.util.BitSet;
     44 import java.util.Date;
     45 
     46 /**
     47  * Abstract class for X.509 v1 certificates. This provides a standard
     48  * way to access all the version 1 attributes of an X.509 certificate.
     49  * Attributes that are specific to X.509 v2 or v3 are not available
     50  * through this interface. Future API evolution will provide full access to
     51  * complete X.509 v3 attributes.
     52  * <p>
     53  * The basic X.509 format was defined by
     54  * ISO/IEC and ANSI X9 and is described below in ASN.1:
     55  * <pre>
     56  * Certificate  ::=  SEQUENCE  {
     57  *     tbsCertificate       TBSCertificate,
     58  *     signatureAlgorithm   AlgorithmIdentifier,
     59  *     signature            BIT STRING  }
     60  * </pre>
     61  * <p>
     62  * These certificates are widely used to support authentication and
     63  * other functionality in Internet security systems. Common applications
     64  * include Privacy Enhanced Mail (PEM), Transport Layer Security (SSL),
     65  * code signing for trusted software distribution, and Secure Electronic
     66  * Transactions (SET).
     67  * <p>
     68  * These certificates are managed and vouched for by <em>Certificate
     69  * Authorities</em> (CAs). CAs are services which create certificates by
     70  * placing data in the X.509 standard format and then digitally signing
     71  * that data. CAs act as trusted third parties, making introductions
     72  * between principals who have no direct knowledge of each other.
     73  * CA certificates are either signed by themselves, or by some other
     74  * CA such as a "root" CA.
     75  * <p>
     76  * The ASN.1 definition of {@code tbsCertificate} is:
     77  * <pre>
     78  * TBSCertificate  ::=  SEQUENCE  {
     79  *     version         [0]  EXPLICIT Version DEFAULT v1,
     80  *     serialNumber         CertificateSerialNumber,
     81  *     signature            AlgorithmIdentifier,
     82  *     issuer               Name,
     83  *     validity             Validity,
     84  *     subject              Name,
     85  *     subjectPublicKeyInfo SubjectPublicKeyInfo,
     86  *     }
     87  * </pre>
     88  * <p>
     89  * Here is sample code to instantiate an X.509 certificate:
     90  * <pre>
     91  * InputStream inStream = new FileInputStream("fileName-of-cert");
     92  * X509Certificate cert = X509Certificate.getInstance(inStream);
     93  * inStream.close();
     94  * </pre>
     95  * OR
     96  * <pre>
     97  * byte[] certData = &lt;certificate read from a file, say&gt;
     98  * X509Certificate cert = X509Certificate.getInstance(certData);
     99  * </pre>
    100  * <p>
    101  * In either case, the code that instantiates an X.509 certificate
    102  * consults the value of the {@code cert.provider.x509v1} security property
    103  * to locate the actual implementation or instantiates a default implementation.
    104  * <p>
    105  * The {@code cert.provider.x509v1} property is set to a default
    106  * implementation for X.509 such as:
    107  * <pre>
    108  * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
    109  * </pre>
    110  * <p>
    111  * The value of this {@code cert.provider.x509v1} property has to be
    112  * changed to instantiate another implementation. If this security
    113  * property is not set, a default implementation will be used.
    114  * Currently, due to possible security restrictions on access to
    115  * Security properties, this value is looked up and cached at class
    116  * initialization time and will fallback on a default implementation if
    117  * the Security property is not accessible.
    118  *
    119  * <p><em>Note: The classes in the package {@code javax.security.cert}
    120  * exist for compatibility with earlier versions of the
    121  * Java Secure Sockets Extension (JSSE). New applications should instead
    122  * use the standard Java SE certificate classes located in
    123  * {@code java.security.cert}.</em></p>
    124  *
    125  * @author Hemma Prafullchandra
    126  * @since 1.4
    127  * @see Certificate
    128  * @see java.security.cert.X509Extension
    129  * @see java.security.Security security properties
    130  */
    131 public abstract class X509Certificate extends Certificate {
    132 
    133     /*
    134      * Constant to lookup in the Security properties file.
    135      * In the Security properties file the default implementation
    136      * for X.509 v3 is given as:
    137      * <pre>
    138      * cert.provider.x509v1=com.sun.security.cert.internal.x509.X509V1CertImpl
    139      * </pre>
    140      */
    141     private static final String X509_PROVIDER = "cert.provider.x509v1";
    142     private static String X509Provider;
    143 
    144     // Android-added.
    145     private static final String DEFAULT_X509_CERT_CLASS = X509V1CertImpl.class.getName();
    146 
    147     static {
    148         X509Provider = AccessController.doPrivileged(
    149             new PrivilegedAction<String>() {
    150                 public String run() {
    151                     return Security.getProperty(X509_PROVIDER);
    152                 }
    153             }
    154         );
    155     }
    156 
    157     /**
    158      * Instantiates an X509Certificate object, and initializes it with
    159      * the data read from the input stream {@code inStream}.
    160      * The implementation (X509Certificate is an abstract class) is
    161      * provided by the class specified as the value of the
    162      * {@code cert.provider.x509v1} security property.
    163      *
    164      * <p>Note: Only one DER-encoded
    165      * certificate is expected to be in the input stream.
    166      * Also, all X509Certificate
    167      * subclasses must provide a constructor of the form:
    168      * <pre>{@code
    169      * public <subClass>(InputStream inStream) ...
    170      * }</pre>
    171      *
    172      * @param inStream an input stream with the data to be read to
    173      *        initialize the certificate.
    174      * @return an X509Certificate object initialized with the data
    175      *         from the input stream.
    176      * @exception CertificateException if a class initialization
    177      *            or certificate parsing error occurs.
    178      */
    179     public static final X509Certificate getInstance(InputStream inStream)
    180     throws CertificateException {
    181         return getInst((Object)inStream);
    182     }
    183 
    184     /**
    185      * Instantiates an X509Certificate object, and initializes it with
    186      * the specified byte array.
    187      * The implementation (X509Certificate is an abstract class) is
    188      * provided by the class specified as the value of the
    189      * {@code cert.provider.x509v1} security property.
    190      *
    191      * <p>Note: All X509Certificate
    192      * subclasses must provide a constructor of the form:
    193      * <pre>{@code
    194      * public <subClass>(InputStream inStream) ...
    195      * }</pre>
    196      *
    197      * @param certData a byte array containing the DER-encoded
    198      *        certificate.
    199      * @return an X509Certificate object initialized with the data
    200      *         from {@code certData}.
    201      * @exception CertificateException if a class initialization
    202      *            or certificate parsing error occurs.
    203      */
    204     public static final X509Certificate getInstance(byte[] certData)
    205     throws CertificateException {
    206         return getInst((Object)certData);
    207     }
    208 
    209     private static final X509Certificate getInst(Object value)
    210     throws CertificateException {
    211         /*
    212          * This turns out not to work for now. To run under JDK1.2 we would
    213          * need to call beginPrivileged() but we can't do that and run
    214          * under JDK1.1.
    215          */
    216         String className = X509Provider;
    217         if (className == null || className.length() == 0) {
    218             // shouldn't happen, but assume corrupted properties file
    219             // provide access to sun implementation
    220             //
    221             // Android-changed.
    222             className = DEFAULT_X509_CERT_CLASS;
    223         }
    224         try {
    225             Class<?>[] params = null;
    226             if (value instanceof InputStream) {
    227                 params = new Class<?>[] { InputStream.class };
    228             } else if (value instanceof byte[]) {
    229                 params = new Class<?>[] { value.getClass() };
    230             } else
    231                 throw new CertificateException("Unsupported argument type");
    232             Class<?> certClass = Class.forName(className);
    233 
    234             // get the appropriate constructor and instantiate it
    235             Constructor<?> cons = certClass.getConstructor(params);
    236 
    237             // get a new instance
    238             Object obj = cons.newInstance(new Object[] {value});
    239             return (X509Certificate)obj;
    240 
    241         } catch (ClassNotFoundException e) {
    242           throw new CertificateException("Could not find class: " + e);
    243         } catch (IllegalAccessException e) {
    244           throw new CertificateException("Could not access class: " + e);
    245         } catch (InstantiationException e) {
    246           throw new CertificateException("Problems instantiating: " + e);
    247         } catch (InvocationTargetException e) {
    248           throw new CertificateException("InvocationTargetException: "
    249                                          + e.getTargetException());
    250         } catch (NoSuchMethodException e) {
    251           throw new CertificateException("Could not find class method: "
    252                                           + e.getMessage());
    253         }
    254     }
    255 
    256     /**
    257      * Checks that the certificate is currently valid. It is if
    258      * the current date and time are within the validity period given in the
    259      * certificate.
    260      * <p>
    261      * The validity period consists of two date/time values:
    262      * the first and last dates (and times) on which the certificate
    263      * is valid. It is defined in
    264      * ASN.1 as:
    265      * <pre>
    266      * validity             Validity
    267      *
    268      * Validity ::= SEQUENCE {
    269      *     notBefore      CertificateValidityDate,
    270      *     notAfter       CertificateValidityDate }
    271      *
    272      * CertificateValidityDate ::= CHOICE {
    273      *     utcTime        UTCTime,
    274      *     generalTime    GeneralizedTime }
    275      * </pre>
    276      *
    277      * @exception CertificateExpiredException if the certificate has expired.
    278      * @exception CertificateNotYetValidException if the certificate is not
    279      *            yet valid.
    280      */
    281     public abstract void checkValidity()
    282         throws CertificateExpiredException, CertificateNotYetValidException;
    283 
    284     /**
    285      * Checks that the specified date is within the certificate's
    286      * validity period. In other words, this determines whether the
    287      * certificate would be valid at the specified date/time.
    288      *
    289      * @param date the Date to check against to see if this certificate
    290      *        is valid at that date/time.
    291      * @exception CertificateExpiredException if the certificate has expired
    292      *            with respect to the {@code date} supplied.
    293      * @exception CertificateNotYetValidException if the certificate is not
    294      *            yet valid with respect to the {@code date} supplied.
    295      * @see #checkValidity()
    296      */
    297     public abstract void checkValidity(Date date)
    298         throws CertificateExpiredException, CertificateNotYetValidException;
    299 
    300     /**
    301      * Gets the {@code version} (version number) value from the
    302      * certificate. The ASN.1 definition for this is:
    303      * <pre>
    304      * version         [0]  EXPLICIT Version DEFAULT v1
    305      *
    306      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
    307      * </pre>
    308      *
    309      * @return the version number from the ASN.1 encoding, i.e. 0, 1 or 2.
    310      */
    311     public abstract int getVersion();
    312 
    313     /**
    314      * Gets the {@code serialNumber} value from the certificate.
    315      * The serial number is an integer assigned by the certification
    316      * authority to each certificate. It must be unique for each
    317      * certificate issued by a given CA (i.e., the issuer name and
    318      * serial number identify a unique certificate).
    319      * The ASN.1 definition for this is:
    320      * <pre>
    321      * serialNumber     CertificateSerialNumber
    322      *
    323      * CertificateSerialNumber  ::=  INTEGER
    324      * </pre>
    325      *
    326      * @return the serial number.
    327      */
    328     public abstract BigInteger getSerialNumber();
    329 
    330     /**
    331      * Gets the {@code issuer} (issuer distinguished name) value from
    332      * the certificate. The issuer name identifies the entity that signed (and
    333      * issued) the certificate.
    334      *
    335      * <p>The issuer name field contains an
    336      * X.500 distinguished name (DN).
    337      * The ASN.1 definition for this is:
    338      * <pre>
    339      * issuer    Name
    340      *
    341      * Name ::= CHOICE { RDNSequence }
    342      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
    343      * RelativeDistinguishedName ::=
    344      *     SET OF AttributeValueAssertion
    345      *
    346      * AttributeValueAssertion ::= SEQUENCE {
    347      *                               AttributeType,
    348      *                               AttributeValue }
    349      * AttributeType ::= OBJECT IDENTIFIER
    350      * AttributeValue ::= ANY
    351      * </pre>
    352      * The {@code Name} describes a hierarchical name composed of
    353      * attributes, such as country name, and corresponding values, such as US.
    354      * The type of the {@code AttributeValue} component is determined by
    355      * the {@code AttributeType}; in general it will be a
    356      * {@code directoryString}. A {@code directoryString} is usually
    357      * one of {@code PrintableString},
    358      * {@code TeletexString} or {@code UniversalString}.
    359      *
    360      * @return a Principal whose name is the issuer distinguished name.
    361      */
    362     public abstract Principal getIssuerDN();
    363 
    364     /**
    365      * Gets the {@code subject} (subject distinguished name) value
    366      * from the certificate.
    367      * The ASN.1 definition for this is:
    368      * <pre>
    369      * subject    Name
    370      * </pre>
    371      *
    372      * <p>See {@link #getIssuerDN() getIssuerDN} for {@code Name}
    373      * and other relevant definitions.
    374      *
    375      * @return a Principal whose name is the subject name.
    376      * @see #getIssuerDN()
    377      */
    378     public abstract Principal getSubjectDN();
    379 
    380     /**
    381      * Gets the {@code notBefore} date from the validity period of
    382      * the certificate.
    383      * The relevant ASN.1 definitions are:
    384      * <pre>
    385      * validity             Validity
    386      *
    387      * Validity ::= SEQUENCE {
    388      *     notBefore      CertificateValidityDate,
    389      *     notAfter       CertificateValidityDate }
    390      *
    391      * CertificateValidityDate ::= CHOICE {
    392      *     utcTime        UTCTime,
    393      *     generalTime    GeneralizedTime }
    394      * </pre>
    395      *
    396      * @return the start date of the validity period.
    397      * @see #checkValidity()
    398      */
    399     public abstract Date getNotBefore();
    400 
    401     /**
    402      * Gets the {@code notAfter} date from the validity period of
    403      * the certificate. See {@link #getNotBefore() getNotBefore}
    404      * for relevant ASN.1 definitions.
    405      *
    406      * @return the end date of the validity period.
    407      * @see #checkValidity()
    408      */
    409     public abstract Date getNotAfter();
    410 
    411     /**
    412      * Gets the signature algorithm name for the certificate
    413      * signature algorithm. An example is the string "SHA-1/DSA".
    414      * The ASN.1 definition for this is:
    415      * <pre>
    416      * signatureAlgorithm   AlgorithmIdentifier
    417      *
    418      * AlgorithmIdentifier  ::=  SEQUENCE  {
    419      *     algorithm               OBJECT IDENTIFIER,
    420      *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
    421      *                             -- contains a value of the type
    422      *                             -- registered for use with the
    423      *                             -- algorithm object identifier value
    424      * </pre>
    425      *
    426      * <p>The algorithm name is determined from the {@code algorithm}
    427      * OID string.
    428      *
    429      * @return the signature algorithm name.
    430      */
    431     public abstract String getSigAlgName();
    432 
    433     /**
    434      * Gets the signature algorithm OID string from the certificate.
    435      * An OID is represented by a set of positive whole numbers separated
    436      * by periods.
    437      * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
    438      * with DSA signature algorithm, as per the PKIX part I.
    439      *
    440      * <p>See {@link #getSigAlgName() getSigAlgName} for
    441      * relevant ASN.1 definitions.
    442      *
    443      * @return the signature algorithm OID string.
    444      */
    445     public abstract String getSigAlgOID();
    446 
    447     /**
    448      * Gets the DER-encoded signature algorithm parameters from this
    449      * certificate's signature algorithm. In most cases, the signature
    450      * algorithm parameters are null; the parameters are usually
    451      * supplied with the certificate's public key.
    452      *
    453      * <p>See {@link #getSigAlgName() getSigAlgName} for
    454      * relevant ASN.1 definitions.
    455      *
    456      * @return the DER-encoded signature algorithm parameters, or
    457      *         null if no parameters are present.
    458      */
    459     public abstract byte[] getSigAlgParams();
    460 }
    461