1 /*
2  * Copyright (c) 1998, 2017, 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.util.Objects;
33 import java.security.Provider;
34 import java.security.Security;
35 import java.security.NoSuchAlgorithmException;
36 import java.security.NoSuchProviderException;
37
38 import sun.security.jca.*;
39 import sun.security.jca.GetInstance.Instance;
40
41 /**
42  * This class defines the functionality of a certificate factory, which is
43  * used to generate certificate, certification path ({@code CertPath})
44  * and certificate revocation list (CRL) objects from their encodings.
45  *
46  * <p>For encodings consisting of multiple certificates, use
47  * {@code generateCertificates} when you want to
48  * parse a collection of possibly unrelated certificates. Otherwise,
49  * use {@code generateCertPath} when you want to generate
50  * a {@code CertPath} (a certificate chain) and subsequently
51  * validate it with a {@code CertPathValidator}.
52  *
53  * <p>A certificate factory for X.509 must return certificates that are an
54  * instance of {@code java.security.cert.X509Certificate}, and CRLs
55  * that are an instance of {@code java.security.cert.X509CRL}.
56  *
57  * <p>The following example reads a file with Base64 encoded certificates,
58  * which are each bounded at the beginning by -----BEGIN CERTIFICATE-----, and
59  * bounded at the end by -----END CERTIFICATE-----. We convert the
60  * {@code FileInputStream} (which does not support {@code mark}
61  * and {@code reset}) to a {@code BufferedInputStream} (which
62  * supports those methods), so that each call to
63  * {@code generateCertificate} consumes only one certificate, and the
64  * read position of the input stream is positioned to the next certificate in
65  * the file:
66  *
67  * <pre>{@code
68  * FileInputStream fis = new FileInputStream(filename);
69  * BufferedInputStream bis = new BufferedInputStream(fis);
70  *
71  * CertificateFactory cf = CertificateFactory.getInstance("X.509");
72  *
73  * while (bis.available() > 0) {
74  *    Certificate cert = cf.generateCertificate(bis);
75  *    System.out.println(cert.toString());
76  * }
77  * }</pre>
78  *
79  * <p>The following example parses a PKCS#7-formatted certificate reply stored
80  * in a file and extracts all the certificates from it:
81  *
82  * <pre>
83  * FileInputStream fis = new FileInputStream(filename);
84  * CertificateFactory cf = CertificateFactory.getInstance("X.509");
85  * Collection c = cf.generateCertificates(fis);
86  * Iterator i = c.iterator();
87  * while (i.hasNext()) {
88  *    Certificate cert = (Certificate)i.next();
89  *    System.out.println(cert);
90  * }
91  * </pre>
92  *
93  * <p> Every implementation of the Java platform is required to support the
94  * following standard {@code CertificateFactory} type:
95  * <ul>
96  * <li>{@code X.509}</li>
97  * </ul>
98  * and the following standard {@code CertPath} encodings:
99  * <ul>
100  * <li>{@code PKCS7}</li>
101  * <li>{@code PkiPath}</li>
102  * </ul>
103  * The type and encodings are described in the <a href=
104  * "{@docRoot}/../specs/security/standard-names.html#certificatefactory-types">
105  * CertificateFactory section</a> and the <a href=
106  * "{@docRoot}/../specs/security/standard-names.html#certpath-encodings">
107  * CertPath Encodings section</a> of the
108  * Java Security Standard Algorithm Names Specification.
109  * Consult the release documentation for your implementation to see if any
110  * other types or encodings are supported.
111  *
112  * @author Hemma Prafullchandra
113  * @author Jan Luehe
114  * @author Sean Mullan
115  *
116  * @see Certificate
117  * @see X509Certificate
118  * @see CertPath
119  * @see CRL
120  * @see X509CRL
121  *
122  * @since 1.2
123  */

124
125 public class CertificateFactory {
126
127     // The certificate type
128     private String type;
129
130     // The provider
131     private Provider provider;
132
133     // The provider implementation
134     private CertificateFactorySpi certFacSpi;
135
136     /**
137      * Creates a CertificateFactory object of the given type, and encapsulates
138      * the given provider implementation (SPI object) in it.
139      *
140      * @param certFacSpi the provider implementation.
141      * @param provider the provider.
142      * @param type the certificate type.
143      */

144     protected CertificateFactory(CertificateFactorySpi certFacSpi,
145                                  Provider provider, String type)
146     {
147         this.certFacSpi = certFacSpi;
148         this.provider = provider;
149         this.type = type;
150     }
151
152     /**
153      * Returns a certificate factory object that implements the
154      * specified certificate type.
155      *
156      * <p> This method traverses the list of registered security Providers,
157      * starting with the most preferred Provider.
158      * A new CertificateFactory object encapsulating the
159      * CertificateFactorySpi implementation from the first
160      * Provider that supports the specified type is returned.
161      *
162      * <p> Note that the list of registered providers may be retrieved via
163      * the {@link Security#getProviders() Security.getProviders()} method.
164      *
165      * @implNote
166      * The JDK Reference Implementation additionally uses the
167      * {@code jdk.security.provider.preferred}
168      * {@link Security#getProperty(String) Security} property to determine
169      * the preferred provider order for the specified algorithm. This
170      * may be different than the order of providers returned by
171      * {@link Security#getProviders() Security.getProviders()}.
172      *
173      * @param type the name of the requested certificate type.
174      * See the CertificateFactory section in the <a href=
175      * "{@docRoot}/../specs/security/standard-names.html#certificatefactory-types">
176      * Java Security Standard Algorithm Names Specification</a>
177      * for information about standard certificate types.
178      *
179      * @return a certificate factory object for the specified type
180      *
181      * @throws CertificateException if no {@code Provider} supports a
182      *         {@code CertificateFactorySpi} implementation for the
183      *         specified type
184      *
185      * @throws NullPointerException if {@code type} is {@code null}
186      *
187      * @see java.security.Provider
188      */

189     public static final CertificateFactory getInstance(String type)
190             throws CertificateException {
191         Objects.requireNonNull(type, "null type name");
192         try {
193             Instance instance = GetInstance.getInstance("CertificateFactory",
194                 CertificateFactorySpi.class, type);
195             return new CertificateFactory((CertificateFactorySpi)instance.impl,
196                 instance.provider, type);
197         } catch (NoSuchAlgorithmException e) {
198             throw new CertificateException(type + " not found", e);
199         }
200     }
201
202     /**
203      * Returns a certificate factory object for the specified
204      * certificate type.
205      *
206      * <p> A new CertificateFactory object encapsulating the
207      * CertificateFactorySpi implementation from the specified provider
208      * is returned.  The specified provider must be registered
209      * in the security provider list.
210      *
211      * <p> Note that the list of registered providers may be retrieved via
212      * the {@link Security#getProviders() Security.getProviders()} method.
213      *
214      * @param type the certificate type.
215      * See the CertificateFactory section in the <a href=
216      * "{@docRoot}/../specs/security/standard-names.html#certificatefactory-types">
217      * Java Security Standard Algorithm Names Specification</a>
218      * for information about standard certificate types.
219      *
220      * @param provider the name of the provider.
221      *
222      * @return a certificate factory object for the specified type
223      *
224      * @throws CertificateException if a {@code CertificateFactorySpi}
225      *         implementation for the specified algorithm is not
226      *         available from the specified provider
227      *
228      * @throws IllegalArgumentException if the provider name is {@code null}
229      *         or empty
230      *
231      * @throws NoSuchProviderException if the specified provider is not
232      *         registered in the security provider list
233      *
234      * @throws NullPointerException if {@code type} is {@code null}
235      *
236      * @see java.security.Provider
237      */

238     public static final CertificateFactory getInstance(String type,
239             String provider) throws CertificateException,
240             NoSuchProviderException {
241         Objects.requireNonNull(type, "null type name");
242         try {
243             Instance instance = GetInstance.getInstance("CertificateFactory",
244                 CertificateFactorySpi.class, type, provider);
245             return new CertificateFactory((CertificateFactorySpi)instance.impl,
246                 instance.provider, type);
247         } catch (NoSuchAlgorithmException e) {
248             throw new CertificateException(type + " not found", e);
249         }
250     }
251
252     /**
253      * Returns a certificate factory object for the specified
254      * certificate type.
255      *
256      * <p> A new CertificateFactory object encapsulating the
257      * CertificateFactorySpi implementation from the specified Provider
258      * object is returned.  Note that the specified Provider object
259      * does not have to be registered in the provider list.
260      *
261      * @param type the certificate type.
262      * See the CertificateFactory section in the <a href=
263      * "{@docRoot}/../specs/security/standard-names.html#certificatefactory-types">
264      * Java Security Standard Algorithm Names Specification</a>
265      * for information about standard certificate types.
266      * @param provider the provider.
267      *
268      * @return a certificate factory object for the specified type
269      *
270      * @throws CertificateException if a {@code CertificateFactorySpi}
271      *         implementation for the specified algorithm is not available
272      *         from the specified {@code Provider} object
273      *
274      * @throws IllegalArgumentException if the {@code provider} is
275      *         {@code null}
276      *
277      * @throws NullPointerException if {@code type} is {@code null}
278      *
279      * @see java.security.Provider
280      *
281      * @since 1.4
282      */

283     public static final CertificateFactory getInstance(String type,
284             Provider provider) throws CertificateException {
285         Objects.requireNonNull(type, "null type name");
286         try {
287             Instance instance = GetInstance.getInstance("CertificateFactory",
288                 CertificateFactorySpi.class, type, provider);
289             return new CertificateFactory((CertificateFactorySpi)instance.impl,
290                 instance.provider, type);
291         } catch (NoSuchAlgorithmException e) {
292             throw new CertificateException(type + " not found", e);
293         }
294     }
295
296     /**
297      * Returns the provider of this certificate factory.
298      *
299      * @return the provider of this certificate factory.
300      */

301     public final Provider getProvider() {
302         return this.provider;
303     }
304
305     /**
306      * Returns the name of the certificate type associated with this
307      * certificate factory.
308      *
309      * @return the name of the certificate type associated with this
310      * certificate factory.
311      */

312     public final String getType() {
313         return this.type;
314     }
315
316     /**
317      * Generates a certificate object and initializes it with
318      * the data read from the input stream {@code inStream}.
319      *
320      * <p>In order to take advantage of the specialized certificate format
321      * supported by this certificate factory,
322      * the returned certificate object can be typecast to the corresponding
323      * certificate class. For example, if this certificate
324      * factory implements X.509 certificates, the returned certificate object
325      * can be typecast to the {@code X509Certificate} class.
326      *
327      * <p>In the case of a certificate factory for X.509 certificates, the
328      * certificate provided in {@code inStream} must be DER-encoded and
329      * may be supplied in binary or printable (Base64) encoding. If the
330      * certificate is provided in Base64 encoding, it must be bounded at
331      * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
332      * the end by -----END CERTIFICATE-----.
333      *
334      * <p>Note that if the given input stream does not support
335      * {@link java.io.InputStream#mark(int) mark} and
336      * {@link java.io.InputStream#reset() reset}, this method will
337      * consume the entire input stream. Otherwise, each call to this
338      * method consumes one certificate and the read position of the
339      * input stream is positioned to the next available byte after
340      * the inherent end-of-certificate marker. If the data in the input stream
341      * does not contain an inherent end-of-certificate marker (other
342      * than EOF) and there is trailing data after the certificate is parsed, a
343      * {@code CertificateException} is thrown.
344      *
345      * @param inStream an input stream with the certificate data.
346      *
347      * @return a certificate object initialized with the data
348      * from the input stream.
349      *
350      * @exception CertificateException on parsing errors.
351      */

352     public final Certificate generateCertificate(InputStream inStream)
353         throws CertificateException
354     {
355         return certFacSpi.engineGenerateCertificate(inStream);
356     }
357
358     /**
359      * Returns an iteration of the {@code CertPath} encodings supported
360      * by this certificate factory, with the default encoding first. See
361      * the CertPath Encodings section in the <a href=
362      * "{@docRoot}/../specs/security/standard-names.html#certpath-encodings">
363      * Java Security Standard Algorithm Names Specification</a>
364      * for information about standard encoding names and their formats.
365      * <p>
366      * Attempts to modify the returned {@code Iterator} via its
367      * {@code remove} method result in an
368      * {@code UnsupportedOperationException}.
369      *
370      * @return an {@code Iterator} over the names of the supported
371      *         {@code CertPath} encodings (as {@code String}s)
372      * @since 1.4
373      */

374     public final Iterator<String> getCertPathEncodings() {
375         return(certFacSpi.engineGetCertPathEncodings());
376     }
377
378     /**
379      * Generates a {@code CertPath} object and initializes it with
380      * the data read from the {@code InputStream} inStream. The data
381      * is assumed to be in the default encoding. The name of the default
382      * encoding is the first element of the {@code Iterator} returned by
383      * the {@link #getCertPathEncodings getCertPathEncodings} method.
384      *
385      * @param inStream an {@code InputStream} containing the data
386      * @return a {@code CertPath} initialized with the data from the
387      *   {@code InputStream}
388      * @exception CertificateException if an exception occurs while decoding
389      * @since 1.4
390      */

391     public final CertPath generateCertPath(InputStream inStream)
392         throws CertificateException
393     {
394         return(certFacSpi.engineGenerateCertPath(inStream));
395     }
396
397     /**
398      * Generates a {@code CertPath} object and initializes it with
399      * the data read from the {@code InputStream} inStream. The data
400      * is assumed to be in the specified encoding. See
401      * the CertPath Encodings section in the <a href=
402      * "{@docRoot}/../specs/security/standard-names.html#certpath-encodings">
403      * Java Security Standard Algorithm Names Specification</a>
404      * for information about standard encoding names and their formats.
405      *
406      * @param inStream an {@code InputStream} containing the data
407      * @param encoding the encoding used for the data
408      * @return a {@code CertPath} initialized with the data from the
409      *   {@code InputStream}
410      * @exception CertificateException if an exception occurs while decoding or
411      *   the encoding requested is not supported
412      * @since 1.4
413      */

414     public final CertPath generateCertPath(InputStream inStream,
415         String encoding) throws CertificateException
416     {
417         return(certFacSpi.engineGenerateCertPath(inStream, encoding));
418     }
419
420     /**
421      * Generates a {@code CertPath} object and initializes it with
422      * a {@code List} of {@code Certificate}s.
423      * <p>
424      * The certificates supplied must be of a type supported by the
425      * {@code CertificateFactory}. They will be copied out of the supplied
426      * {@code List} object.
427      *
428      * @param certificates a {@code List} of {@code Certificate}s
429      * @return a {@code CertPath} initialized with the supplied list of
430      *   certificates
431      * @exception CertificateException if an exception occurs
432      * @since 1.4
433      */

434     public final CertPath
435         generateCertPath(List<? extends Certificate> certificates)
436         throws CertificateException
437     {
438         return(certFacSpi.engineGenerateCertPath(certificates));
439     }
440
441     /**
442      * Returns a (possibly empty) collection view of the certificates read
443      * from the given input stream {@code inStream}.
444      *
445      * <p>In order to take advantage of the specialized certificate format
446      * supported by this certificate factory, each element in
447      * the returned collection view can be typecast to the corresponding
448      * certificate class. For example, if this certificate
449      * factory implements X.509 certificates, the elements in the returned
450      * collection can be typecast to the {@code X509Certificate} class.
451      *
452      * <p>In the case of a certificate factory for X.509 certificates,
453      * {@code inStream} may contain a sequence of DER-encoded certificates
454      * in the formats described for
455      * {@link #generateCertificate(java.io.InputStream) generateCertificate}.
456      * In addition, {@code inStream} may contain a PKCS#7 certificate
457      * chain. This is a PKCS#7 <i>SignedData</i> object, with the only
458      * significant field being <i>certificates</i>. In particular, the
459      * signature and the contents are ignored. This format allows multiple
460      * certificates to be downloaded at once. If no certificates are present,
461      * an empty collection is returned.
462      *
463      * <p>Note that if the given input stream does not support
464      * {@link java.io.InputStream#mark(int) mark} and
465      * {@link java.io.InputStream#reset() reset}, this method will
466      * consume the entire input stream.
467      *
468      * @param inStream the input stream with the certificates.
469      *
470      * @return a (possibly empty) collection view of
471      * java.security.cert.Certificate objects
472      * initialized with the data from the input stream.
473      *
474      * @exception CertificateException on parsing errors.
475      */

476     public final Collection<? extends Certificate> generateCertificates
477             (InputStream inStream) throws CertificateException {
478         return certFacSpi.engineGenerateCertificates(inStream);
479     }
480
481     /**
482      * Generates a certificate revocation list (CRL) object and initializes it
483      * with the data read from the input stream {@code inStream}.
484      *
485      * <p>In order to take advantage of the specialized CRL format
486      * supported by this certificate factory,
487      * the returned CRL object can be typecast to the corresponding
488      * CRL class. For example, if this certificate
489      * factory implements X.509 CRLs, the returned CRL object
490      * can be typecast to the {@code X509CRL} class.
491      *
492      * <p>Note that if the given input stream does not support
493      * {@link java.io.InputStream#mark(int) mark} and
494      * {@link java.io.InputStream#reset() reset}, this method will
495      * consume the entire input stream. Otherwise, each call to this
496      * method consumes one CRL and the read position of the input stream
497      * is positioned to the next available byte after the inherent
498      * end-of-CRL marker. If the data in the
499      * input stream does not contain an inherent end-of-CRL marker (other
500      * than EOF) and there is trailing data after the CRL is parsed, a
501      * {@code CRLException} is thrown.
502      *
503      * @param inStream an input stream with the CRL data.
504      *
505      * @return a CRL object initialized with the data
506      * from the input stream.
507      *
508      * @exception CRLException on parsing errors.
509      */

510     public final CRL generateCRL(InputStream inStream)
511         throws CRLException
512     {
513         return certFacSpi.engineGenerateCRL(inStream);
514     }
515
516     /**
517      * Returns a (possibly empty) collection view of the CRLs read
518      * from the given input stream {@code inStream}.
519      *
520      * <p>In order to take advantage of the specialized CRL format
521      * supported by this certificate factory, each element in
522      * the returned collection view can be typecast to the corresponding
523      * CRL class. For example, if this certificate
524      * factory implements X.509 CRLs, the elements in the returned
525      * collection can be typecast to the {@code X509CRL} class.
526      *
527      * <p>In the case of a certificate factory for X.509 CRLs,
528      * {@code inStream} may contain a sequence of DER-encoded CRLs.
529      * In addition, {@code inStream} may contain a PKCS#7 CRL
530      * set. This is a PKCS#7 <i>SignedData</i> object, with the only
531      * significant field being <i>crls</i>. In particular, the
532      * signature and the contents are ignored. This format allows multiple
533      * CRLs to be downloaded at once. If no CRLs are present,
534      * an empty collection is returned.
535      *
536      * <p>Note that if the given input stream does not support
537      * {@link java.io.InputStream#mark(int) mark} and
538      * {@link java.io.InputStream#reset() reset}, this method will
539      * consume the entire input stream.
540      *
541      * @param inStream the input stream with the CRLs.
542      *
543      * @return a (possibly empty) collection view of
544      * java.security.cert.CRL objects initialized with the data from the input
545      * stream.
546      *
547      * @exception CRLException on parsing errors.
548      */

549     public final Collection<? extends CRL> generateCRLs(InputStream inStream)
550             throws CRLException {
551         return certFacSpi.engineGenerateCRLs(inStream);
552     }
553 }
554