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             // Android-added: Check for Bouncy Castle deprecation
    254             Providers.checkBouncyCastleDeprecation(provider, "CertificateFactory", type);
    255             Instance instance = GetInstance.getInstance("CertificateFactory",
    256                 CertificateFactorySpi.class, type, provider);
    257             return new CertificateFactory((CertificateFactorySpi)instance.impl,
    258                 instance.provider, type);
    259         } catch (NoSuchAlgorithmException e) {
    260             throw new CertificateException(type + " not found", e);
    261         }
    262     }
    263 
    264     /**
    265      * Returns a certificate factory object for the specified
    266      * certificate type.
    267      *
    268      * <p> A new CertificateFactory object encapsulating the
    269      * CertificateFactorySpi implementation from the specified Provider
    270      * object is returned.  Note that the specified Provider object
    271      * does not have to be registered in the provider list.
    272      *
    273      * @param type the certificate type.
    274      * See the CertificateFactory section in the <a href=
    275      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertificateFactory">
    276      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    277      * for information about standard certificate types.
    278      * @param provider the provider.
    279      *
    280      * @return a certificate factory object for the specified type.
    281      *
    282      * @exception CertificateException if a CertificateFactorySpi
    283      *          implementation for the specified algorithm is not available
    284      *          from the specified Provider object.
    285      *
    286      * @exception IllegalArgumentException if the {@code provider} is
    287      *          null.
    288      *
    289      * @see java.security.Provider
    290      *
    291      * @since 1.4
    292      */
    293     public static final CertificateFactory getInstance(String type,
    294             Provider provider) throws CertificateException {
    295         try {
    296             // Android-added: Check for Bouncy Castle deprecation
    297             Providers.checkBouncyCastleDeprecation(provider, "CertificateFactory", type);
    298             Instance instance = GetInstance.getInstance("CertificateFactory",
    299                 CertificateFactorySpi.class, type, provider);
    300             return new CertificateFactory((CertificateFactorySpi)instance.impl,
    301                 instance.provider, type);
    302         } catch (NoSuchAlgorithmException e) {
    303             throw new CertificateException(type + " not found", e);
    304         }
    305     }
    306 
    307     /**
    308      * Returns the provider of this certificate factory.
    309      *
    310      * @return the provider of this certificate factory.
    311      */
    312     public final Provider getProvider() {
    313         return this.provider;
    314     }
    315 
    316     /**
    317      * Returns the name of the certificate type associated with this
    318      * certificate factory.
    319      *
    320      * @return the name of the certificate type associated with this
    321      * certificate factory.
    322      */
    323     public final String getType() {
    324         return this.type;
    325     }
    326 
    327     /**
    328      * Generates a certificate object and initializes it with
    329      * the data read from the input stream {@code inStream}.
    330      *
    331      * <p>In order to take advantage of the specialized certificate format
    332      * supported by this certificate factory,
    333      * the returned certificate object can be typecast to the corresponding
    334      * certificate class. For example, if this certificate
    335      * factory implements X.509 certificates, the returned certificate object
    336      * can be typecast to the {@code X509Certificate} class.
    337      *
    338      * <p>In the case of a certificate factory for X.509 certificates, the
    339      * certificate provided in {@code inStream} must be DER-encoded and
    340      * may be supplied in binary or printable (Base64) encoding. If the
    341      * certificate is provided in Base64 encoding, it must be bounded at
    342      * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
    343      * the end by -----END CERTIFICATE-----.
    344      *
    345      * <p>Note that if the given input stream does not support
    346      * {@link java.io.InputStream#mark(int) mark} and
    347      * {@link java.io.InputStream#reset() reset}, this method will
    348      * consume the entire input stream. Otherwise, each call to this
    349      * method consumes one certificate and the read position of the
    350      * input stream is positioned to the next available byte after
    351      * the inherent end-of-certificate marker. If the data in the input stream
    352      * does not contain an inherent end-of-certificate marker (other
    353      * than EOF) and there is trailing data after the certificate is parsed, a
    354      * {@code CertificateException} is thrown.
    355      *
    356      * @param inStream an input stream with the certificate data.
    357      *
    358      * @return a certificate object initialized with the data
    359      * from the input stream.
    360      *
    361      * @exception CertificateException on parsing errors.
    362      */
    363     public final Certificate generateCertificate(InputStream inStream)
    364         throws CertificateException
    365     {
    366         return certFacSpi.engineGenerateCertificate(inStream);
    367     }
    368 
    369     /**
    370      * Returns an iteration of the {@code CertPath} encodings supported
    371      * by this certificate factory, with the default encoding first. See
    372      * the CertPath Encodings section in the <a href=
    373      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
    374      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    375      * for information about standard encoding names and their formats.
    376      * <p>
    377      * Attempts to modify the returned {@code Iterator} via its
    378      * {@code remove} method result in an
    379      * {@code UnsupportedOperationException}.
    380      *
    381      * @return an {@code Iterator} over the names of the supported
    382      *         {@code CertPath} encodings (as {@code String}s)
    383      * @since 1.4
    384      */
    385     public final Iterator<String> getCertPathEncodings() {
    386         return(certFacSpi.engineGetCertPathEncodings());
    387     }
    388 
    389     /**
    390      * Generates a {@code CertPath} object and initializes it with
    391      * the data read from the {@code InputStream} inStream. The data
    392      * is assumed to be in the default encoding. The name of the default
    393      * encoding is the first element of the {@code Iterator} returned by
    394      * the {@link #getCertPathEncodings getCertPathEncodings} method.
    395      *
    396      * @param inStream an {@code InputStream} containing the data
    397      * @return a {@code CertPath} initialized with the data from the
    398      *   {@code InputStream}
    399      * @exception CertificateException if an exception occurs while decoding
    400      * @since 1.4
    401      */
    402     public final CertPath generateCertPath(InputStream inStream)
    403         throws CertificateException
    404     {
    405         return(certFacSpi.engineGenerateCertPath(inStream));
    406     }
    407 
    408     /**
    409      * Generates a {@code CertPath} object and initializes it with
    410      * the data read from the {@code InputStream} inStream. The data
    411      * is assumed to be in the specified encoding. See
    412      * the CertPath Encodings section in the <a href=
    413      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertPathEncodings">
    414      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    415      * for information about standard encoding names and their formats.
    416      *
    417      * @param inStream an {@code InputStream} containing the data
    418      * @param encoding the encoding used for the data
    419      * @return a {@code CertPath} initialized with the data from the
    420      *   {@code InputStream}
    421      * @exception CertificateException if an exception occurs while decoding or
    422      *   the encoding requested is not supported
    423      * @since 1.4
    424      */
    425     public final CertPath generateCertPath(InputStream inStream,
    426         String encoding) throws CertificateException
    427     {
    428         return(certFacSpi.engineGenerateCertPath(inStream, encoding));
    429     }
    430 
    431     /**
    432      * Generates a {@code CertPath} object and initializes it with
    433      * a {@code List} of {@code Certificate}s.
    434      * <p>
    435      * The certificates supplied must be of a type supported by the
    436      * {@code CertificateFactory}. They will be copied out of the supplied
    437      * {@code List} object.
    438      *
    439      * @param certificates a {@code List} of {@code Certificate}s
    440      * @return a {@code CertPath} initialized with the supplied list of
    441      *   certificates
    442      * @exception CertificateException if an exception occurs
    443      * @since 1.4
    444      */
    445     public final CertPath
    446         generateCertPath(List<? extends Certificate> certificates)
    447         throws CertificateException
    448     {
    449         return(certFacSpi.engineGenerateCertPath(certificates));
    450     }
    451 
    452     /**
    453      * Returns a (possibly empty) collection view of the certificates read
    454      * from the given input stream {@code inStream}.
    455      *
    456      * <p>In order to take advantage of the specialized certificate format
    457      * supported by this certificate factory, each element in
    458      * the returned collection view can be typecast to the corresponding
    459      * certificate class. For example, if this certificate
    460      * factory implements X.509 certificates, the elements in the returned
    461      * collection can be typecast to the {@code X509Certificate} class.
    462      *
    463      * <p>In the case of a certificate factory for X.509 certificates,
    464      * {@code inStream} may contain a sequence of DER-encoded certificates
    465      * in the formats described for
    466      * {@link #generateCertificate(java.io.InputStream) generateCertificate}.
    467      * In addition, {@code inStream} may contain a PKCS#7 certificate
    468      * chain. This is a PKCS#7 <i>SignedData</i> object, with the only
    469      * significant field being <i>certificates</i>. In particular, the
    470      * signature and the contents are ignored. This format allows multiple
    471      * certificates to be downloaded at once. If no certificates are present,
    472      * an empty collection is returned.
    473      *
    474      * <p>Note that if the given input stream does not support
    475      * {@link java.io.InputStream#mark(int) mark} and
    476      * {@link java.io.InputStream#reset() reset}, this method will
    477      * consume the entire input stream.
    478      *
    479      * @param inStream the input stream with the certificates.
    480      *
    481      * @return a (possibly empty) collection view of
    482      * java.security.cert.Certificate objects
    483      * initialized with the data from the input stream.
    484      *
    485      * @exception CertificateException on parsing errors.
    486      */
    487     public final Collection<? extends Certificate> generateCertificates
    488             (InputStream inStream) throws CertificateException {
    489         return certFacSpi.engineGenerateCertificates(inStream);
    490     }
    491 
    492     /**
    493      * Generates a certificate revocation list (CRL) object and initializes it
    494      * with the data read from the input stream {@code inStream}.
    495      *
    496      * <p>In order to take advantage of the specialized CRL format
    497      * supported by this certificate factory,
    498      * the returned CRL object can be typecast to the corresponding
    499      * CRL class. For example, if this certificate
    500      * factory implements X.509 CRLs, the returned CRL object
    501      * can be typecast to the {@code X509CRL} class.
    502      *
    503      * <p>Note that if the given input stream does not support
    504      * {@link java.io.InputStream#mark(int) mark} and
    505      * {@link java.io.InputStream#reset() reset}, this method will
    506      * consume the entire input stream. Otherwise, each call to this
    507      * method consumes one CRL and the read position of the input stream
    508      * is positioned to the next available byte after the inherent
    509      * end-of-CRL marker. If the data in the
    510      * input stream does not contain an inherent end-of-CRL marker (other
    511      * than EOF) and there is trailing data after the CRL is parsed, a
    512      * {@code CRLException} is thrown.
    513      *
    514      * @param inStream an input stream with the CRL data.
    515      *
    516      * @return a CRL object initialized with the data
    517      * from the input stream.
    518      *
    519      * @exception CRLException on parsing errors.
    520      */
    521     public final CRL generateCRL(InputStream inStream)
    522         throws CRLException
    523     {
    524         return certFacSpi.engineGenerateCRL(inStream);
    525     }
    526 
    527     /**
    528      * Returns a (possibly empty) collection view of the CRLs read
    529      * from the given input stream {@code inStream}.
    530      *
    531      * <p>In order to take advantage of the specialized CRL format
    532      * supported by this certificate factory, each element in
    533      * the returned collection view can be typecast to the corresponding
    534      * CRL class. For example, if this certificate
    535      * factory implements X.509 CRLs, the elements in the returned
    536      * collection can be typecast to the {@code X509CRL} class.
    537      *
    538      * <p>In the case of a certificate factory for X.509 CRLs,
    539      * {@code inStream} may contain a sequence of DER-encoded CRLs.
    540      * In addition, {@code inStream} may contain a PKCS#7 CRL
    541      * set. This is a PKCS#7 <i>SignedData</i> object, with the only
    542      * significant field being <i>crls</i>. In particular, the
    543      * signature and the contents are ignored. This format allows multiple
    544      * CRLs to be downloaded at once. If no CRLs are present,
    545      * an empty collection is returned.
    546      *
    547      * <p>Note that if the given input stream does not support
    548      * {@link java.io.InputStream#mark(int) mark} and
    549      * {@link java.io.InputStream#reset() reset}, this method will
    550      * consume the entire input stream.
    551      *
    552      * @param inStream the input stream with the CRLs.
    553      *
    554      * @return a (possibly empty) collection view of
    555      * java.security.cert.CRL objects initialized with the data from the input
    556      * stream.
    557      *
    558      * @exception CRLException on parsing errors.
    559      */
    560     public final Collection<? extends CRL> generateCRLs(InputStream inStream)
    561             throws CRLException {
    562         return certFacSpi.engineGenerateCRLs(inStream);
    563     }
    564 }
    565