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