• 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  * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#CertificateFactory">
131  * CertificateFactory section</a> and the <a href=
132  * "https://docs.oracle.com/javase/8/docs/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      * "https://docs.oracle.com/javase/8/docs/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      * "https://docs.oracle.com/javase/8/docs/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             // 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      * "https://docs.oracle.com/javase/8/docs/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      */
getInstance(String type, Provider provider)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      */
getProvider()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      */
getType()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      */
generateCertificate(InputStream inStream)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      * "https://docs.oracle.com/javase/8/docs/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      */
getCertPathEncodings()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      */
generateCertPath(InputStream inStream)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      * "https://docs.oracle.com/javase/8/docs/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      */
generateCertPath(InputStream inStream, String encoding)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
generateCertPath(List<? extends Certificate> certificates)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      */
generateCertificates(InputStream inStream)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      */
generateCRL(InputStream inStream)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      */
generateCRLs(InputStream inStream)560     public final Collection<? extends CRL> generateCRLs(InputStream inStream)
561             throws CRLException {
562         return certFacSpi.engineGenerateCRLs(inStream);
563     }
564 }
565