Home | History | Annotate | Download | only in cert
      1 /*
      2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package java.security.cert;
     27 
     28 import java.io.InputStream;
     29 import java.util.Collection;
     30 import java.util.Iterator;
     31 import java.util.List;
     32 import java.security.Provider;
     33 import java.security.Security;
     34 import java.security.AccessController;
     35 import java.security.PrivilegedAction;
     36 import java.security.NoSuchAlgorithmException;
     37 import java.security.NoSuchProviderException;
     38 
     39 import sun.security.jca.*;
     40 import sun.security.jca.GetInstance.Instance;
     41 
     42 /**
     43  * This class defines the functionality of a certificate factory, which is
     44  * used to generate certificate, certification path ({@code CertPath})
     45  * and certificate revocation list (CRL) objects from their encodings.
     46  *
     47  * <p>For encodings consisting of multiple certificates, use
     48  * {@code generateCertificates} when you want to
     49  * parse a collection of possibly unrelated certificates. Otherwise,
     50  * use {@code generateCertPath} when you want to generate
     51  * a {@code CertPath} (a certificate chain) and subsequently
     52  * validate it with a {@code CertPathValidator}.
     53  *
     54  * <p>A certificate factory for X.509 must return certificates that are an
     55  * instance of {@code java.security.cert.X509Certificate}, and CRLs
     56  * that are an instance of {@code java.security.cert.X509CRL}.
     57  *
     58  * <p>The following example reads a file with Base64 encoded certificates,
     59  * which are each bounded at the beginning by -----BEGIN CERTIFICATE-----, and
     60  * bounded at the end by -----END CERTIFICATE-----. We convert the
     61  * {@code FileInputStream} (which does not support {@code mark}
     62  * and {@code reset}) to a {@code BufferedInputStream} (which
     63  * supports those methods), so that each call to
     64  * {@code generateCertificate} consumes only one certificate, and the
     65  * read position of the input stream is positioned to the next certificate in
     66  * the file:
     67  *
     68  * <pre>{@code
     69  * FileInputStream fis = new FileInputStream(filename);
     70  * BufferedInputStream bis = new BufferedInputStream(fis);
     71  *
     72  * CertificateFactory cf = CertificateFactory.getInstance("X.509");
     73  *
     74  * while (bis.available() > 0) {
     75  *    Certificate cert = cf.generateCertificate(bis);
     76  *    System.out.println(cert.toString());
     77  * }
     78  * }</pre>
     79  *
     80  * <p>The following example parses a PKCS#7-formatted certificate reply stored
     81  * in a file and extracts all the certificates from it:
     82  *
     83  * <pre>
     84  * FileInputStream fis = new FileInputStream(filename);
     85  * CertificateFactory cf = CertificateFactory.getInstance("X.509");
     86  * Collection c = cf.generateCertificates(fis);
     87  * Iterator i = c.iterator();
     88  * while (i.hasNext()) {
     89  *    Certificate cert = (Certificate)i.next();
     90  *    System.out.println(cert);
     91  * }
     92  * </pre>
     93  *
     94  * <p> Android provides the following <code>CertificateFactory</code> types:
     95  * <table>
     96  *   <thead>
     97  *     <tr>
     98  *       <th>Algorithm</th>
     99  *       <th>Supported API Levels</th>
    100  *     </tr>
    101  *   </thead>
    102  *   <tbody>
    103  *     <tr>
    104  *       <td>X.509</td>
    105  *       <td>1+</td>
    106  *     </tr>
    107  *   </tbody>
    108  * </table>
    109  * and the following <code>CertPath</code> encodings:
    110  * <table>
    111  *     <thead>
    112  *         <tr>
    113  *             <th>Name</th>
    114  *             <th>Supported (API Levels)</th>
    115  *         </tr>
    116  *     </thead>
    117  *     <tbody>
    118  *         <tr>
    119  *             <td>PKCS7</td>
    120  *             <td>1+</td>
    121  *         </tr>
    122  *         <tr>
    123  *             <td>PkiPath</td>
    124  *             <td>1+</td>
    125  *         </tr>
    126  *     </tbody>
    127  * </table>
    128  *
    129  * The type and encodings are described in the <a href=
    130  * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
    131  * CertificateFactory section</a> and the <a href=
    132  * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
    133  * CertPath Encodings section</a> of the
    134  * Java Cryptography Architecture Standard Algorithm Name Documentation.
    135  *
    136  * @author Hemma Prafullchandra
    137  * @author Jan Luehe
    138  * @author Sean Mullan
    139  *
    140  * @see Certificate
    141  * @see X509Certificate
    142  * @see CertPath
    143  * @see CRL
    144  * @see X509CRL
    145  *
    146  * @since 1.2
    147  */
    148 
    149 public class CertificateFactory {
    150 
    151     // The certificate type
    152     private String type;
    153 
    154     // The provider
    155     private Provider provider;
    156 
    157     // The provider implementation
    158     private CertificateFactorySpi certFacSpi;
    159 
    160     /**
    161      * Creates a CertificateFactory object of the given type, and encapsulates
    162      * the given provider implementation (SPI object) in it.
    163      *
    164      * @param certFacSpi the provider implementation.
    165      * @param provider the provider.
    166      * @param type the certificate type.
    167      */
    168     protected CertificateFactory(CertificateFactorySpi certFacSpi,
    169                                  Provider provider, String type)
    170     {
    171         this.certFacSpi = certFacSpi;
    172         this.provider = provider;
    173         this.type = type;
    174     }
    175 
    176     /**
    177      * Returns a certificate factory object that implements the
    178      * specified certificate type.
    179      *
    180      * <p> This method traverses the list of registered security Providers,
    181      * starting with the most preferred Provider.
    182      * A new CertificateFactory object encapsulating the
    183      * CertificateFactorySpi implementation from the first
    184      * Provider that supports the specified type is returned.
    185      *
    186      * <p> Note that the list of registered providers may be retrieved via
    187      * the {@link Security#getProviders() Security.getProviders()} method.
    188      *
    189      * @param type the name of the requested certificate type.
    190      * See the CertificateFactory section in the <a href=
    191      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
    192      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    193      * for information about standard certificate types.
    194      *
    195      * @return a certificate factory object for the specified type.
    196      *
    197      * @exception CertificateException if no Provider supports a
    198      *          CertificateFactorySpi implementation for the
    199      *          specified type.
    200      *
    201      * @see java.security.Provider
    202      */
    203     public static final CertificateFactory getInstance(String type)
    204             throws CertificateException {
    205         try {
    206             Instance instance = GetInstance.getInstance("CertificateFactory",
    207                 CertificateFactorySpi.class, type);
    208             return new CertificateFactory((CertificateFactorySpi)instance.impl,
    209                 instance.provider, type);
    210         } catch (NoSuchAlgorithmException e) {
    211             throw new CertificateException(type + " not found", e);
    212         }
    213     }
    214 
    215     /**
    216      * Returns a certificate factory object for the specified
    217      * certificate type.
    218      *
    219      * <p> A new CertificateFactory object encapsulating the
    220      * CertificateFactorySpi implementation from the specified provider
    221      * is returned.  The specified provider must be registered
    222      * in the security provider list.
    223      *
    224      * <p> Note that the list of registered providers may be retrieved via
    225      * the {@link Security#getProviders() Security.getProviders()} method.
    226      *
    227      * @param type the certificate type.
    228      * See the CertificateFactory section in the <a href=
    229      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
    230      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    231      * for information about standard certificate types.
    232      *
    233      * @param provider the name of the provider.
    234      *
    235      * @return a certificate factory object for the specified type.
    236      *
    237      * @exception CertificateException if a CertificateFactorySpi
    238      *          implementation for the specified algorithm is not
    239      *          available from the specified provider.
    240      *
    241      * @exception NoSuchProviderException if the specified provider is not
    242      *          registered in the security provider list.
    243      *
    244      * @exception IllegalArgumentException if the provider name is null
    245      *          or empty.
    246      *
    247      * @see java.security.Provider
    248      */
    249     public static final CertificateFactory getInstance(String type,
    250             String provider) throws CertificateException,
    251             NoSuchProviderException {
    252         try {
    253             Instance instance = GetInstance.getInstance("CertificateFactory",
    254                 CertificateFactorySpi.class, type, provider);
    255             return new CertificateFactory((CertificateFactorySpi)instance.impl,
    256                 instance.provider, type);
    257         } catch (NoSuchAlgorithmException e) {
    258             throw new CertificateException(type + " not found", e);
    259         }
    260     }
    261 
    262     /**
    263      * Returns a certificate factory object for the specified
    264      * certificate type.
    265      *
    266      * <p> A new CertificateFactory object encapsulating the
    267      * CertificateFactorySpi implementation from the specified Provider
    268      * object is returned.  Note that the specified Provider object
    269      * does not have to be registered in the provider list.
    270      *
    271      * @param type the certificate type.
    272      * See the CertificateFactory section in the <a href=
    273      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
    274      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    275      * for information about standard certificate types.
    276      * @param provider the provider.
    277      *
    278      * @return a certificate factory object for the specified type.
    279      *
    280      * @exception CertificateException if a CertificateFactorySpi
    281      *          implementation for the specified algorithm is not available
    282      *          from the specified Provider object.
    283      *
    284      * @exception IllegalArgumentException if the {@code provider} is
    285      *          null.
    286      *
    287      * @see java.security.Provider
    288      *
    289      * @since 1.4
    290      */
    291     public static final CertificateFactory getInstance(String type,
    292             Provider provider) throws CertificateException {
    293         try {
    294             Instance instance = GetInstance.getInstance("CertificateFactory",
    295                 CertificateFactorySpi.class, type, provider);
    296             return new CertificateFactory((CertificateFactorySpi)instance.impl,
    297                 instance.provider, type);
    298         } catch (NoSuchAlgorithmException e) {
    299             throw new CertificateException(type + " not found", e);
    300         }
    301     }
    302 
    303     /**
    304      * Returns the provider of this certificate factory.
    305      *
    306      * @return the provider of this certificate factory.
    307      */
    308     public final Provider getProvider() {
    309         return this.provider;
    310     }
    311 
    312     /**
    313      * Returns the name of the certificate type associated with this
    314      * certificate factory.
    315      *
    316      * @return the name of the certificate type associated with this
    317      * certificate factory.
    318      */
    319     public final String getType() {
    320         return this.type;
    321     }
    322 
    323     /**
    324      * Generates a certificate object and initializes it with
    325      * the data read from the input stream {@code inStream}.
    326      *
    327      * <p>In order to take advantage of the specialized certificate format
    328      * supported by this certificate factory,
    329      * the returned certificate object can be typecast to the corresponding
    330      * certificate class. For example, if this certificate
    331      * factory implements X.509 certificates, the returned certificate object
    332      * can be typecast to the {@code X509Certificate} class.
    333      *
    334      * <p>In the case of a certificate factory for X.509 certificates, the
    335      * certificate provided in {@code inStream} must be DER-encoded and
    336      * may be supplied in binary or printable (Base64) encoding. If the
    337      * certificate is provided in Base64 encoding, it must be bounded at
    338      * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
    339      * the end by -----END CERTIFICATE-----.
    340      *
    341      * <p>Note that if the given input stream does not support
    342      * {@link java.io.InputStream#mark(int) mark} and
    343      * {@link java.io.InputStream#reset() reset}, this method will
    344      * consume the entire input stream. Otherwise, each call to this
    345      * method consumes one certificate and the read position of the
    346      * input stream is positioned to the next available byte after
    347      * the inherent end-of-certificate marker. If the data in the input stream
    348      * does not contain an inherent end-of-certificate marker (other
    349      * than EOF) and there is trailing data after the certificate is parsed, a
    350      * {@code CertificateException} is thrown.
    351      *
    352      * @param inStream an input stream with the certificate data.
    353      *
    354      * @return a certificate object initialized with the data
    355      * from the input stream.
    356      *
    357      * @exception CertificateException on parsing errors.
    358      */
    359     public final Certificate generateCertificate(InputStream inStream)
    360         throws CertificateException
    361     {
    362         return certFacSpi.engineGenerateCertificate(inStream);
    363     }
    364 
    365     /**
    366      * Returns an iteration of the {@code CertPath} encodings supported
    367      * by this certificate factory, with the default encoding first. See
    368      * the CertPath Encodings section in the <a href=
    369      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
    370      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    371      * for information about standard encoding names and their formats.
    372      * <p>
    373      * Attempts to modify the returned {@code Iterator} via its
    374      * {@code remove} method result in an
    375      * {@code UnsupportedOperationException}.
    376      *
    377      * @return an {@code Iterator} over the names of the supported
    378      *         {@code CertPath} encodings (as {@code String}s)
    379      * @since 1.4
    380      */
    381     public final Iterator<String> getCertPathEncodings() {
    382         return(certFacSpi.engineGetCertPathEncodings());
    383     }
    384 
    385     /**
    386      * Generates a {@code CertPath} object and initializes it with
    387      * the data read from the {@code InputStream} inStream. The data
    388      * is assumed to be in the default encoding. The name of the default
    389      * encoding is the first element of the {@code Iterator} returned by
    390      * the {@link #getCertPathEncodings getCertPathEncodings} method.
    391      *
    392      * @param inStream an {@code InputStream} containing the data
    393      * @return a {@code CertPath} initialized with the data from the
    394      *   {@code InputStream}
    395      * @exception CertificateException if an exception occurs while decoding
    396      * @since 1.4
    397      */
    398     public final CertPath generateCertPath(InputStream inStream)
    399         throws CertificateException
    400     {
    401         return(certFacSpi.engineGenerateCertPath(inStream));
    402     }
    403 
    404     /**
    405      * Generates a {@code CertPath} object and initializes it with
    406      * the data read from the {@code InputStream} inStream. The data
    407      * is assumed to be in the specified encoding. See
    408      * the CertPath Encodings section in the <a href=
    409      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
    410      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    411      * for information about standard encoding names and their formats.
    412      *
    413      * @param inStream an {@code InputStream} containing the data
    414      * @param encoding the encoding used for the data
    415      * @return a {@code CertPath} initialized with the data from the
    416      *   {@code InputStream}
    417      * @exception CertificateException if an exception occurs while decoding or
    418      *   the encoding requested is not supported
    419      * @since 1.4
    420      */
    421     public final CertPath generateCertPath(InputStream inStream,
    422         String encoding) throws CertificateException
    423     {
    424         return(certFacSpi.engineGenerateCertPath(inStream, encoding));
    425     }
    426 
    427     /**
    428      * Generates a {@code CertPath} object and initializes it with
    429      * a {@code List} of {@code Certificate}s.
    430      * <p>
    431      * The certificates supplied must be of a type supported by the
    432      * {@code CertificateFactory}. They will be copied out of the supplied
    433      * {@code List} object.
    434      *
    435      * @param certificates a {@code List} of {@code Certificate}s
    436      * @return a {@code CertPath} initialized with the supplied list of
    437      *   certificates
    438      * @exception CertificateException if an exception occurs
    439      * @since 1.4
    440      */
    441     public final CertPath
    442         generateCertPath(List<? extends Certificate> certificates)
    443         throws CertificateException
    444     {
    445         return(certFacSpi.engineGenerateCertPath(certificates));
    446     }
    447 
    448     /**
    449      * Returns a (possibly empty) collection view of the certificates read
    450      * from the given input stream {@code inStream}.
    451      *
    452      * <p>In order to take advantage of the specialized certificate format
    453      * supported by this certificate factory, each element in
    454      * the returned collection view can be typecast to the corresponding
    455      * certificate class. For example, if this certificate
    456      * factory implements X.509 certificates, the elements in the returned
    457      * collection can be typecast to the {@code X509Certificate} class.
    458      *
    459      * <p>In the case of a certificate factory for X.509 certificates,
    460      * {@code inStream} may contain a sequence of DER-encoded certificates
    461      * in the formats described for
    462      * {@link #generateCertificate(java.io.InputStream) generateCertificate}.
    463      * In addition, {@code inStream} may contain a PKCS#7 certificate
    464      * chain. This is a PKCS#7 <i>SignedData</i> object, with the only
    465      * significant field being <i>certificates</i>. In particular, the
    466      * signature and the contents are ignored. This format allows multiple
    467      * certificates to be downloaded at once. If no certificates are present,
    468      * an empty collection is returned.
    469      *
    470      * <p>Note that if the given input stream does not support
    471      * {@link java.io.InputStream#mark(int) mark} and
    472      * {@link java.io.InputStream#reset() reset}, this method will
    473      * consume the entire input stream.
    474      *
    475      * @param inStream the input stream with the certificates.
    476      *
    477      * @return a (possibly empty) collection view of
    478      * java.security.cert.Certificate objects
    479      * initialized with the data from the input stream.
    480      *
    481      * @exception CertificateException on parsing errors.
    482      */
    483     public final Collection<? extends Certificate> generateCertificates
    484             (InputStream inStream) throws CertificateException {
    485         return certFacSpi.engineGenerateCertificates(inStream);
    486     }
    487 
    488     /**
    489      * Generates a certificate revocation list (CRL) object and initializes it
    490      * with the data read from the input stream {@code inStream}.
    491      *
    492      * <p>In order to take advantage of the specialized CRL format
    493      * supported by this certificate factory,
    494      * the returned CRL object can be typecast to the corresponding
    495      * CRL class. For example, if this certificate
    496      * factory implements X.509 CRLs, the returned CRL object
    497      * can be typecast to the {@code X509CRL} class.
    498      *
    499      * <p>Note that if the given input stream does not support
    500      * {@link java.io.InputStream#mark(int) mark} and
    501      * {@link java.io.InputStream#reset() reset}, this method will
    502      * consume the entire input stream. Otherwise, each call to this
    503      * method consumes one CRL and the read position of the input stream
    504      * is positioned to the next available byte after the inherent
    505      * end-of-CRL marker. If the data in the
    506      * input stream does not contain an inherent end-of-CRL marker (other
    507      * than EOF) and there is trailing data after the CRL is parsed, a
    508      * {@code CRLException} is thrown.
    509      *
    510      * @param inStream an input stream with the CRL data.
    511      *
    512      * @return a CRL object initialized with the data
    513      * from the input stream.
    514      *
    515      * @exception CRLException on parsing errors.
    516      */
    517     public final CRL generateCRL(InputStream inStream)
    518         throws CRLException
    519     {
    520         return certFacSpi.engineGenerateCRL(inStream);
    521     }
    522 
    523     /**
    524      * Returns a (possibly empty) collection view of the CRLs read
    525      * from the given input stream {@code inStream}.
    526      *
    527      * <p>In order to take advantage of the specialized CRL format
    528      * supported by this certificate factory, each element in
    529      * the returned collection view can be typecast to the corresponding
    530      * CRL class. For example, if this certificate
    531      * factory implements X.509 CRLs, the elements in the returned
    532      * collection can be typecast to the {@code X509CRL} class.
    533      *
    534      * <p>In the case of a certificate factory for X.509 CRLs,
    535      * {@code inStream} may contain a sequence of DER-encoded CRLs.
    536      * In addition, {@code inStream} may contain a PKCS#7 CRL
    537      * set. This is a PKCS#7 <i>SignedData</i> object, with the only
    538      * significant field being <i>crls</i>. In particular, the
    539      * signature and the contents are ignored. This format allows multiple
    540      * CRLs to be downloaded at once. If no CRLs are present,
    541      * an empty collection is returned.
    542      *
    543      * <p>Note that if the given input stream does not support
    544      * {@link java.io.InputStream#mark(int) mark} and
    545      * {@link java.io.InputStream#reset() reset}, this method will
    546      * consume the entire input stream.
    547      *
    548      * @param inStream the input stream with the CRLs.
    549      *
    550      * @return a (possibly empty) collection view of
    551      * java.security.cert.CRL objects initialized with the data from the input
    552      * stream.
    553      *
    554      * @exception CRLException on parsing errors.
    555      */
    556     public final Collection<? extends CRL> generateCRLs(InputStream inStream)
    557             throws CRLException {
    558         return certFacSpi.engineGenerateCRLs(inStream);
    559     }
    560 }
    561