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