View Javadoc
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> Every implementation of the Java platform is required to support the
95   * following standard {@code CertificateFactory} type:
96   * <ul>
97   * <li>{@code X.509}</li>
98   * </ul>
99   * and the following standard {@code CertPath} encodings:
100  * <ul>
101  * <li>{@code PKCS7}</li>
102  * <li>{@code PkiPath}</li>
103  * </ul>
104  * The type and encodings are described in the <a href=
105  * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
106  * CertificateFactory section</a> and the <a href=
107  * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
108  * CertPath Encodings section</a> of the
109  * Java Cryptography Architecture Standard Algorithm Name Documentation.
110  * Consult the release documentation for your implementation to see if any
111  * other types or encodings are supported.
112  *
113  * @author Hemma Prafullchandra
114  * @author Jan Luehe
115  * @author Sean Mullan
116  *
117  * @see Certificate
118  * @see X509Certificate
119  * @see CertPath
120  * @see CRL
121  * @see X509CRL
122  *
123  * @since 1.2
124  */
125 
126 public class CertificateFactory {
127 
128     // The certificate type
129     private String type;
130 
131     // The provider
132     private Provider provider;
133 
134     // The provider implementation
135     private CertificateFactorySpi certFacSpi;
136 
137     /**
138      * Creates a CertificateFactory object of the given type, and encapsulates
139      * the given provider implementation (SPI object) in it.
140      *
141      * @param certFacSpi the provider implementation.
142      * @param provider the provider.
143      * @param type the certificate type.
144      */
145     protected CertificateFactory(CertificateFactorySpi certFacSpi,
146                                  Provider provider, String type)
147     {
148         this.certFacSpi = certFacSpi;
149         this.provider = provider;
150         this.type = type;
151     }
152 
153     /**
154      * Returns a certificate factory object that implements the
155      * specified certificate type.
156      *
157      * <p> This method traverses the list of registered security Providers,
158      * starting with the most preferred Provider.
159      * A new CertificateFactory object encapsulating the
160      * CertificateFactorySpi implementation from the first
161      * Provider that supports the specified type is returned.
162      *
163      * <p> Note that the list of registered providers may be retrieved via
164      * the {@link Security#getProviders() Security.getProviders()} method.
165      *
166      * @param type the name of the requested certificate type.
167      * See the CertificateFactory section in the <a href=
168      * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
169      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
170      * for information about standard certificate types.
171      *
172      * @return a certificate factory object for the specified type.
173      *
174      * @exception CertificateException if no Provider supports a
175      *          CertificateFactorySpi implementation for the
176      *          specified type.
177      *
178      * @see java.security.Provider
179      */
180     public static final CertificateFactory getInstance(String type)
181             throws CertificateException {
182         try {
183             Instance instance = GetInstance.getInstance("CertificateFactory",
184                 CertificateFactorySpi.class, type);
185             return new CertificateFactory((CertificateFactorySpi)instance.impl,
186                 instance.provider, type);
187         } catch (NoSuchAlgorithmException e) {
188             throw new CertificateException(type + " not found", e);
189         }
190     }
191 
192     /**
193      * Returns a certificate factory object for the specified
194      * certificate type.
195      *
196      * <p> A new CertificateFactory object encapsulating the
197      * CertificateFactorySpi implementation from the specified provider
198      * is returned.  The specified provider must be registered
199      * in the security provider list.
200      *
201      * <p> Note that the list of registered providers may be retrieved via
202      * the {@link Security#getProviders() Security.getProviders()} method.
203      *
204      * @param type the certificate type.
205      * See the CertificateFactory section in the <a href=
206      * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
207      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
208      * for information about standard certificate types.
209      *
210      * @param provider the name of the provider.
211      *
212      * @return a certificate factory object for the specified type.
213      *
214      * @exception CertificateException if a CertificateFactorySpi
215      *          implementation for the specified algorithm is not
216      *          available from the specified provider.
217      *
218      * @exception NoSuchProviderException if the specified provider is not
219      *          registered in the security provider list.
220      *
221      * @exception IllegalArgumentException if the provider name is null
222      *          or empty.
223      *
224      * @see java.security.Provider
225      */
226     public static final CertificateFactory getInstance(String type,
227             String provider) throws CertificateException,
228             NoSuchProviderException {
229         try {
230             Instance instance = GetInstance.getInstance("CertificateFactory",
231                 CertificateFactorySpi.class, type, provider);
232             return new CertificateFactory((CertificateFactorySpi)instance.impl,
233                 instance.provider, type);
234         } catch (NoSuchAlgorithmException e) {
235             throw new CertificateException(type + " not found", e);
236         }
237     }
238 
239     /**
240      * Returns a certificate factory object for the specified
241      * certificate type.
242      *
243      * <p> A new CertificateFactory object encapsulating the
244      * CertificateFactorySpi implementation from the specified Provider
245      * object is returned.  Note that the specified Provider object
246      * does not have to be registered in the provider list.
247      *
248      * @param type the certificate type.
249      * See the CertificateFactory section in the <a href=
250      * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
251      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
252      * for information about standard certificate types.
253      * @param provider the provider.
254      *
255      * @return a certificate factory object for the specified type.
256      *
257      * @exception CertificateException if a CertificateFactorySpi
258      *          implementation for the specified algorithm is not available
259      *          from the specified Provider object.
260      *
261      * @exception IllegalArgumentException if the {@code provider} is
262      *          null.
263      *
264      * @see java.security.Provider
265      *
266      * @since 1.4
267      */
268     public static final CertificateFactory getInstance(String type,
269             Provider provider) throws CertificateException {
270         try {
271             Instance instance = GetInstance.getInstance("CertificateFactory",
272                 CertificateFactorySpi.class, type, provider);
273             return new CertificateFactory((CertificateFactorySpi)instance.impl,
274                 instance.provider, type);
275         } catch (NoSuchAlgorithmException e) {
276             throw new CertificateException(type + " not found", e);
277         }
278     }
279 
280     /**
281      * Returns the provider of this certificate factory.
282      *
283      * @return the provider of this certificate factory.
284      */
285     public final Provider getProvider() {
286         return this.provider;
287     }
288 
289     /**
290      * Returns the name of the certificate type associated with this
291      * certificate factory.
292      *
293      * @return the name of the certificate type associated with this
294      * certificate factory.
295      */
296     public final String getType() {
297         return this.type;
298     }
299 
300     /**
301      * Generates a certificate object and initializes it with
302      * the data read from the input stream {@code inStream}.
303      *
304      * <p>In order to take advantage of the specialized certificate format
305      * supported by this certificate factory,
306      * the returned certificate object can be typecast to the corresponding
307      * certificate class. For example, if this certificate
308      * factory implements X.509 certificates, the returned certificate object
309      * can be typecast to the {@code X509Certificate} class.
310      *
311      * <p>In the case of a certificate factory for X.509 certificates, the
312      * certificate provided in {@code inStream} must be DER-encoded and
313      * may be supplied in binary or printable (Base64) encoding. If the
314      * certificate is provided in Base64 encoding, it must be bounded at
315      * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
316      * the end by -----END CERTIFICATE-----.
317      *
318      * <p>Note that if the given input stream does not support
319      * {@link java.io.InputStream#mark(int) mark} and
320      * {@link java.io.InputStream#reset() reset}, this method will
321      * consume the entire input stream. Otherwise, each call to this
322      * method consumes one certificate and the read position of the
323      * input stream is positioned to the next available byte after
324      * the inherent end-of-certificate marker. If the data in the input stream
325      * does not contain an inherent end-of-certificate marker (other
326      * than EOF) and there is trailing data after the certificate is parsed, a
327      * {@code CertificateException} is thrown.
328      *
329      * @param inStream an input stream with the certificate data.
330      *
331      * @return a certificate object initialized with the data
332      * from the input stream.
333      *
334      * @exception CertificateException on parsing errors.
335      */
336     public final Certificate generateCertificate(InputStream inStream)
337         throws CertificateException
338     {
339         return certFacSpi.engineGenerateCertificate(inStream);
340     }
341 
342     /**
343      * Returns an iteration of the {@code CertPath} encodings supported
344      * by this certificate factory, with the default encoding first. See
345      * the CertPath Encodings section in the <a href=
346      * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
347      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
348      * for information about standard encoding names and their formats.
349      * <p>
350      * Attempts to modify the returned {@code Iterator} via its
351      * {@code remove} method result in an
352      * {@code UnsupportedOperationException}.
353      *
354      * @return an {@code Iterator} over the names of the supported
355      *         {@code CertPath} encodings (as {@code String}s)
356      * @since 1.4
357      */
358     public final Iterator<String> getCertPathEncodings() {
359         return(certFacSpi.engineGetCertPathEncodings());
360     }
361 
362     /**
363      * Generates a {@code CertPath} object and initializes it with
364      * the data read from the {@code InputStream} inStream. The data
365      * is assumed to be in the default encoding. The name of the default
366      * encoding is the first element of the {@code Iterator} returned by
367      * the {@link #getCertPathEncodings getCertPathEncodings} method.
368      *
369      * @param inStream an {@code InputStream} containing the data
370      * @return a {@code CertPath} initialized with the data from the
371      *   {@code InputStream}
372      * @exception CertificateException if an exception occurs while decoding
373      * @since 1.4
374      */
375     public final CertPath generateCertPath(InputStream inStream)
376         throws CertificateException
377     {
378         return(certFacSpi.engineGenerateCertPath(inStream));
379     }
380 
381     /**
382      * Generates a {@code CertPath} object and initializes it with
383      * the data read from the {@code InputStream} inStream. The data
384      * is assumed to be in the specified encoding. See
385      * the CertPath Encodings section in the <a href=
386      * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings">
387      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
388      * for information about standard encoding names and their formats.
389      *
390      * @param inStream an {@code InputStream} containing the data
391      * @param encoding the encoding used for the data
392      * @return a {@code CertPath} initialized with the data from the
393      *   {@code InputStream}
394      * @exception CertificateException if an exception occurs while decoding or
395      *   the encoding requested is not supported
396      * @since 1.4
397      */
398     public final CertPath generateCertPath(InputStream inStream,
399         String encoding) throws CertificateException
400     {
401         return(certFacSpi.engineGenerateCertPath(inStream, encoding));
402     }
403 
404     /**
405      * Generates a {@code CertPath} object and initializes it with
406      * a {@code List} of {@code Certificate}s.
407      * <p>
408      * The certificates supplied must be of a type supported by the
409      * {@code CertificateFactory}. They will be copied out of the supplied
410      * {@code List} object.
411      *
412      * @param certificates a {@code List} of {@code Certificate}s
413      * @return a {@code CertPath} initialized with the supplied list of
414      *   certificates
415      * @exception CertificateException if an exception occurs
416      * @since 1.4
417      */
418     public final CertPath
419         generateCertPath(List<? extends Certificate> certificates)
420         throws CertificateException
421     {
422         return(certFacSpi.engineGenerateCertPath(certificates));
423     }
424 
425     /**
426      * Returns a (possibly empty) collection view of the certificates read
427      * from the given input stream {@code inStream}.
428      *
429      * <p>In order to take advantage of the specialized certificate format
430      * supported by this certificate factory, each element in
431      * the returned collection view can be typecast to the corresponding
432      * certificate class. For example, if this certificate
433      * factory implements X.509 certificates, the elements in the returned
434      * collection can be typecast to the {@code X509Certificate} class.
435      *
436      * <p>In the case of a certificate factory for X.509 certificates,
437      * {@code inStream} may contain a sequence of DER-encoded certificates
438      * in the formats described for
439      * {@link #generateCertificate(java.io.InputStream) generateCertificate}.
440      * In addition, {@code inStream} may contain a PKCS#7 certificate
441      * chain. This is a PKCS#7 <i>SignedData</i> object, with the only
442      * significant field being <i>certificates</i>. In particular, the
443      * signature and the contents are ignored. This format allows multiple
444      * certificates to be downloaded at once. If no certificates are present,
445      * an empty collection is returned.
446      *
447      * <p>Note that if the given input stream does not support
448      * {@link java.io.InputStream#mark(int) mark} and
449      * {@link java.io.InputStream#reset() reset}, this method will
450      * consume the entire input stream.
451      *
452      * @param inStream the input stream with the certificates.
453      *
454      * @return a (possibly empty) collection view of
455      * java.security.cert.Certificate objects
456      * initialized with the data from the input stream.
457      *
458      * @exception CertificateException on parsing errors.
459      */
460     public final Collection<? extends Certificate> generateCertificates
461             (InputStream inStream) throws CertificateException {
462         return certFacSpi.engineGenerateCertificates(inStream);
463     }
464 
465     /**
466      * Generates a certificate revocation list (CRL) object and initializes it
467      * with the data read from the input stream {@code inStream}.
468      *
469      * <p>In order to take advantage of the specialized CRL format
470      * supported by this certificate factory,
471      * the returned CRL object can be typecast to the corresponding
472      * CRL class. For example, if this certificate
473      * factory implements X.509 CRLs, the returned CRL object
474      * can be typecast to the {@code X509CRL} class.
475      *
476      * <p>Note that if the given input stream does not support
477      * {@link java.io.InputStream#mark(int) mark} and
478      * {@link java.io.InputStream#reset() reset}, this method will
479      * consume the entire input stream. Otherwise, each call to this
480      * method consumes one CRL and the read position of the input stream
481      * is positioned to the next available byte after the inherent
482      * end-of-CRL marker. If the data in the
483      * input stream does not contain an inherent end-of-CRL marker (other
484      * than EOF) and there is trailing data after the CRL is parsed, a
485      * {@code CRLException} is thrown.
486      *
487      * @param inStream an input stream with the CRL data.
488      *
489      * @return a CRL object initialized with the data
490      * from the input stream.
491      *
492      * @exception CRLException on parsing errors.
493      */
494     public final CRL generateCRL(InputStream inStream)
495         throws CRLException
496     {
497         return certFacSpi.engineGenerateCRL(inStream);
498     }
499 
500     /**
501      * Returns a (possibly empty) collection view of the CRLs read
502      * from the given input stream {@code inStream}.
503      *
504      * <p>In order to take advantage of the specialized CRL format
505      * supported by this certificate factory, each element in
506      * the returned collection view can be typecast to the corresponding
507      * CRL class. For example, if this certificate
508      * factory implements X.509 CRLs, the elements in the returned
509      * collection can be typecast to the {@code X509CRL} class.
510      *
511      * <p>In the case of a certificate factory for X.509 CRLs,
512      * {@code inStream} may contain a sequence of DER-encoded CRLs.
513      * In addition, {@code inStream} may contain a PKCS#7 CRL
514      * set. This is a PKCS#7 <i>SignedData</i> object, with the only
515      * significant field being <i>crls</i>. In particular, the
516      * signature and the contents are ignored. This format allows multiple
517      * CRLs to be downloaded at once. If no CRLs are present,
518      * an empty collection is returned.
519      *
520      * <p>Note that if the given input stream does not support
521      * {@link java.io.InputStream#mark(int) mark} and
522      * {@link java.io.InputStream#reset() reset}, this method will
523      * consume the entire input stream.
524      *
525      * @param inStream the input stream with the CRLs.
526      *
527      * @return a (possibly empty) collection view of
528      * java.security.cert.CRL objects initialized with the data from the input
529      * stream.
530      *
531      * @exception CRLException on parsing errors.
532      */
533     public final Collection<? extends CRL> generateCRLs(InputStream inStream)
534             throws CRLException {
535         return certFacSpi.engineGenerateCRLs(inStream);
536     }
537 }