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
26package java.security.cert;
27
28import java.io.InputStream;
29import java.util.Collection;
30import java.util.Iterator;
31import java.util.List;
32import java.security.Provider;
33import java.security.Security;
34import java.security.AccessController;
35import java.security.PrivilegedAction;
36import java.security.NoSuchAlgorithmException;
37import java.security.NoSuchProviderException;
38
39import sun.security.jca.*;
40import 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
149public 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