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