KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > security > cert > CertificateFactory


1 /*
2  * @(#)CertificateFactory.java 1.28 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.security.cert;
9
10 import java.io.InputStream JavaDoc;
11 import java.util.Collection JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.List JavaDoc;
14 import java.security.Provider JavaDoc;
15 import java.security.AccessController JavaDoc;
16 import java.security.PrivilegedAction JavaDoc;
17 import java.security.NoSuchAlgorithmException JavaDoc;
18 import java.security.NoSuchProviderException JavaDoc;
19
20 import sun.security.jca.*;
21 import sun.security.jca.GetInstance.Instance;
22
23 /**
24  * This class defines the functionality of a certificate factory, which is
25  * used to generate certificate, certification path (<code>CertPath</code>)
26  * and certificate revocation list (CRL) objects from their encodings.
27  *
28  * <p>For encodings consisting of multiple certificates, use
29  * <code>generateCertificates</code> when you want to
30  * parse a collection of possibly unrelated certificates. Otherwise,
31  * use <code>generateCertPath</code> when you want to generate
32  * a <code>CertPath</code> (a certificate chain) and subsequently
33  * validate it with a <code>CertPathValidator</code>.
34  *
35  * <p>A certificate factory for X.509 must return certificates that are an
36  * instance of <code>java.security.cert.X509Certificate</code>, and CRLs
37  * that are an instance of <code>java.security.cert.X509CRL</code>.
38  *
39  * <p>The following example reads a file with Base64 encoded certificates,
40  * which are each bounded at the beginning by -----BEGIN CERTIFICATE-----, and
41  * bounded at the end by -----END CERTIFICATE-----. We convert the
42  * <code>FileInputStream</code> (which does not support <code>mark</code>
43  * and <code>reset</code>) to a <code>BufferedInputStream</code> (which
44  * supports those methods), so that each call to
45  * <code>generateCertificate</code> consumes only one certificate, and the
46  * read position of the input stream is positioned to the next certificate in
47  * the file:<p>
48  *
49  * <pre>
50  * FileInputStream fis = new FileInputStream(filename);
51  * BufferedInputStream bis = new BufferedInputStream(fis);
52  *
53  * CertificateFactory cf = CertificateFactory.getInstance("X.509");
54  *
55  * while (bis.available() > 0) {
56  * Certificate cert = cf.generateCertificate(bis);
57  * System.out.println(cert.toString());
58  * }
59  * </pre>
60  *
61  * <p>The following example parses a PKCS#7-formatted certificate reply stored
62  * in a file and extracts all the certificates from it:<p>
63  *
64  * <pre>
65  * FileInputStream fis = new FileInputStream(filename);
66  * CertificateFactory cf = CertificateFactory.getInstance("X.509");
67  * Collection c = cf.generateCertificates(fis);
68  * Iterator i = c.iterator();
69  * while (i.hasNext()) {
70  * Certificate cert = (Certificate)i.next();
71  * System.out.println(cert);
72  * }
73  * </pre>
74  *
75  * @author Hemma Prafullchandra
76  * @author Jan Luehe
77  * @author Sean Mullan
78  *
79  * @version 1.28, 05/05/04
80  *
81  * @see Certificate
82  * @see X509Certificate
83  * @see CertPath
84  * @see CRL
85  * @see X509CRL
86  *
87  * @since 1.2
88  */

89
90 public class CertificateFactory {
91
92     // The certificate type
93
private String JavaDoc type;
94
95     // The provider
96
private Provider JavaDoc provider;
97
98     // The provider implementation
99
private CertificateFactorySpi JavaDoc certFacSpi;
100
101     /**
102      * Creates a CertificateFactory object of the given type, and encapsulates
103      * the given provider implementation (SPI object) in it.
104      *
105      * @param certFacSpi the provider implementation.
106      * @param provider the provider.
107      * @param type the certificate type.
108      */

109     protected CertificateFactory(CertificateFactorySpi JavaDoc certFacSpi,
110                  Provider JavaDoc provider, String JavaDoc type)
111     {
112     this.certFacSpi = certFacSpi;
113     this.provider = provider;
114     this.type = type;
115     }
116
117     /**
118      * Generates a certificate factory object that implements the
119      * specified certificate type. If the default provider package
120      * provides an implementation of the requested certificate type,
121      * an instance of certificate factory containing that
122      * implementation is returned.
123      * If the type is not available in the default
124      * package, other packages are searched.
125      *
126      * @param type the name of the requested certificate type.
127      * See Appendix A in the <a HREF=
128      * "../../../../guide/security/CryptoSpec.html#AppA">
129      * Java Cryptography Architecture API Specification &amp; Reference </a>
130      * for information about standard certificate types.
131      *
132      * @return a certificate factory object for the specified type.
133      *
134      * @exception CertificateException if the requested certificate type is
135      * not available in the default provider package or any of the other
136      * provider packages that were searched.
137      */

138     public static final CertificateFactory JavaDoc getInstance(String JavaDoc type)
139         throws CertificateException JavaDoc {
140     try {
141         Instance instance = GetInstance.getInstance("CertificateFactory",
142             CertificateFactorySpi JavaDoc.class, type);
143         return new CertificateFactory JavaDoc((CertificateFactorySpi JavaDoc)instance.impl,
144             instance.provider, type);
145     } catch (NoSuchAlgorithmException JavaDoc e) {
146         throw new CertificateException JavaDoc(type + " not found", e);
147     }
148     }
149
150     /**
151      * Generates a certificate factory object for the specified
152      * certificate type from the specified provider.
153      *
154      * @param type the certificate type
155      * @param provider the name of the provider.
156      *
157      * @return a certificate factory object for the specified type.
158      *
159      * @exception CertificateException if the certificate type is
160      * not available from the specified provider.
161      *
162      * @exception NoSuchProviderException if the provider has not been
163      * configured.
164      *
165      * @see Provider
166      */

167     public static final CertificateFactory JavaDoc getInstance(String JavaDoc type,
168         String JavaDoc provider) throws CertificateException JavaDoc,
169         NoSuchProviderException JavaDoc {
170     try {
171         Instance instance = GetInstance.getInstance("CertificateFactory",
172             CertificateFactorySpi JavaDoc.class, type, provider);
173         return new CertificateFactory JavaDoc((CertificateFactorySpi JavaDoc)instance.impl,
174             instance.provider, type);
175     } catch (NoSuchAlgorithmException JavaDoc e) {
176         throw new CertificateException JavaDoc(type + " not found", e);
177     }
178     }
179
180     /**
181      * Generates a certificate factory object for the specified
182      * certificate type from the specified provider.
183      * Note: the <code>provider</code> doesn't have to be registered.
184      *
185      * @param type the certificate type
186      * @param provider the provider
187      *
188      * @return a certificate factory object for the specified type.
189      *
190      * @exception CertificateException if the certificate type is
191      * not available from the specified provider.
192      *
193      * @exception IllegalArgumentException if the <code>provider</code> is
194      * null.
195      *
196      * @see Provider
197      *
198      * @since 1.4
199      */

200     public static final CertificateFactory JavaDoc getInstance(String JavaDoc type,
201         Provider JavaDoc provider) throws CertificateException JavaDoc {
202     try {
203         Instance instance = GetInstance.getInstance("CertificateFactory",
204             CertificateFactorySpi JavaDoc.class, type, provider);
205         return new CertificateFactory JavaDoc((CertificateFactorySpi JavaDoc)instance.impl,
206             instance.provider, type);
207     } catch (NoSuchAlgorithmException JavaDoc e) {
208         throw new CertificateException JavaDoc(type + " not found", e);
209     }
210     }
211         
212     /**
213      * Returns the provider of this certificate factory.
214      *
215      * @return the provider of this certificate factory.
216      */

217     public final Provider JavaDoc getProvider() {
218     return this.provider;
219     }
220
221     /**
222      * Returns the name of the certificate type associated with this
223      * certificate factory.
224      *
225      * @return the name of the certificate type associated with this
226      * certificate factory.
227      */

228     public final String JavaDoc getType() {
229     return this.type;
230     }
231
232     /**
233      * Generates a certificate object and initializes it with
234      * the data read from the input stream <code>inStream</code>.
235      *
236      * <p>In order to take advantage of the specialized certificate format
237      * supported by this certificate factory,
238      * the returned certificate object can be typecast to the corresponding
239      * certificate class. For example, if this certificate
240      * factory implements X.509 certificates, the returned certificate object
241      * can be typecast to the <code>X509Certificate</code> class.
242      *
243      * <p>In the case of a certificate factory for X.509 certificates, the
244      * certificate provided in <code>inStream</code> must be DER-encoded and
245      * may be supplied in binary or printable (Base64) encoding. If the
246      * certificate is provided in Base64 encoding, it must be bounded at
247      * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
248      * the end by -----END CERTIFICATE-----.
249      *
250      * <p>Note that if the given input stream does not support
251      * {@link java.io.InputStream#mark(int) mark} and
252      * {@link java.io.InputStream#reset() reset}, this method will
253      * consume the entire input stream. Otherwise, each call to this
254      * method consumes one certificate and the read position of the
255      * input stream is positioned to the next available byte after
256      * the inherent end-of-certificate marker. If the data in the input stream
257      * does not contain an inherent end-of-certificate marker (other
258      * than EOF) and there is trailing data after the certificate is parsed, a
259      * <code>CertificateException</code> is thrown.
260      *
261      * @param inStream an input stream with the certificate data.
262      *
263      * @return a certificate object initialized with the data
264      * from the input stream.
265      *
266      * @exception CertificateException on parsing errors.
267      */

268     public final Certificate JavaDoc generateCertificate(InputStream JavaDoc inStream)
269         throws CertificateException JavaDoc
270     {
271     return certFacSpi.engineGenerateCertificate(inStream);
272     }
273
274     /**
275      * Returns an iteration of the <code>CertPath</code> encodings supported
276      * by this certificate factory, with the default encoding first. See
277      * Appendix A in the
278      * <a HREF="../../../../guide/security/certpath/CertPathProgGuide.html#AppA">
279      * Java Certification Path API Programmer's Guide</a> for information about
280      * standard encoding names and their formats.
281      * <p>
282      * Attempts to modify the returned <code>Iterator</code> via its
283      * <code>remove</code> method result in an
284      * <code>UnsupportedOperationException</code>.
285      *
286      * @return an <code>Iterator</code> over the names of the supported
287      * <code>CertPath</code> encodings (as <code>String</code>s)
288      * @since 1.4
289      */

290     public final Iterator JavaDoc<String JavaDoc> getCertPathEncodings() {
291         return(certFacSpi.engineGetCertPathEncodings());
292     }
293
294     /**
295      * Generates a <code>CertPath</code> object and initializes it with
296      * the data read from the <code>InputStream</code> inStream. The data
297      * is assumed to be in the default encoding. The name of the default
298      * encoding is the first element of the <code>Iterator</code> returned by
299      * the {@link #getCertPathEncodings getCertPathEncodings} method.
300      *
301      * @param inStream an <code>InputStream</code> containing the data
302      * @return a <code>CertPath</code> initialized with the data from the
303      * <code>InputStream</code>
304      * @exception CertificateException if an exception occurs while decoding
305      * @since 1.4
306      */

307     public final CertPath JavaDoc generateCertPath(InputStream JavaDoc inStream)
308         throws CertificateException JavaDoc
309     {
310         return(certFacSpi.engineGenerateCertPath(inStream));
311     }
312
313     /**
314      * Generates a <code>CertPath</code> object and initializes it with
315      * the data read from the <code>InputStream</code> inStream. The data
316      * is assumed to be in the specified encoding. See Appendix A in the
317      * <a HREF="../../../../guide/security/certpath/CertPathProgGuide.html#AppA">
318      * Java Certification Path API Programmer's Guide</a>
319      * for information about standard encoding names and their formats.
320      *
321      * @param inStream an <code>InputStream</code> containing the data
322      * @param encoding the encoding used for the data
323      * @return a <code>CertPath</code> initialized with the data from the
324      * <code>InputStream</code>
325      * @exception CertificateException if an exception occurs while decoding or
326      * the encoding requested is not supported
327      * @since 1.4
328      */

329     public final CertPath JavaDoc generateCertPath(InputStream JavaDoc inStream,
330         String JavaDoc encoding) throws CertificateException JavaDoc
331     {
332         return(certFacSpi.engineGenerateCertPath(inStream, encoding));
333     }
334
335     /**
336      * Generates a <code>CertPath</code> object and initializes it with
337      * a <code>List</code> of <code>Certificate</code>s.
338      * <p>
339      * The certificates supplied must be of a type supported by the
340      * <code>CertificateFactory</code>. They will be copied out of the supplied
341      * <code>List</code> object.
342      *
343      * @param certificates a <code>List</code> of <code>Certificate</code>s
344      * @return a <code>CertPath</code> initialized with the supplied list of
345      * certificates
346      * @exception CertificateException if an exception occurs
347      * @since 1.4
348      */

349     public final CertPath JavaDoc
350     generateCertPath(List JavaDoc<? extends Certificate JavaDoc> certificates)
351         throws CertificateException JavaDoc
352     {
353         return(certFacSpi.engineGenerateCertPath(certificates));
354     }
355
356     /**
357      * Returns a (possibly empty) collection view of the certificates read
358      * from the given input stream <code>inStream</code>.
359      *
360      * <p>In order to take advantage of the specialized certificate format
361      * supported by this certificate factory, each element in
362      * the returned collection view can be typecast to the corresponding
363      * certificate class. For example, if this certificate
364      * factory implements X.509 certificates, the elements in the returned
365      * collection can be typecast to the <code>X509Certificate</code> class.
366      *
367      * <p>In the case of a certificate factory for X.509 certificates,
368      * <code>inStream</code> may contain a sequence of DER-encoded certificates
369      * in the formats described for
370      * {@link #generateCertificate(java.io.InputStream) generateCertificate}.
371      * In addition, <code>inStream</code> may contain a PKCS#7 certificate
372      * chain. This is a PKCS#7 <i>SignedData</i> object, with the only
373      * significant field being <i>certificates</i>. In particular, the
374      * signature and the contents are ignored. This format allows multiple
375      * certificates to be downloaded at once. If no certificates are present,
376      * an empty collection is returned.
377      *
378      * <p>Note that if the given input stream does not support
379      * {@link java.io.InputStream#mark(int) mark} and
380      * {@link java.io.InputStream#reset() reset}, this method will
381      * consume the entire input stream.
382      *
383      * @param inStream the input stream with the certificates.
384      *
385      * @return a (possibly empty) collection view of
386      * java.security.cert.Certificate objects
387      * initialized with the data from the input stream.
388      *
389      * @exception CertificateException on parsing errors.
390      */

391     public final Collection JavaDoc<? extends Certificate JavaDoc> generateCertificates
392         (InputStream JavaDoc inStream) throws CertificateException JavaDoc {
393     return certFacSpi.engineGenerateCertificates(inStream);
394     }
395
396     /**
397      * Generates a certificate revocation list (CRL) object and initializes it
398      * with the data read from the input stream <code>inStream</code>.
399      *
400      * <p>In order to take advantage of the specialized CRL format
401      * supported by this certificate factory,
402      * the returned CRL object can be typecast to the corresponding
403      * CRL class. For example, if this certificate
404      * factory implements X.509 CRLs, the returned CRL object
405      * can be typecast to the <code>X509CRL</code> class.
406      *
407      * <p>Note that if the given input stream does not support
408      * {@link java.io.InputStream#mark(int) mark} and
409      * {@link java.io.InputStream#reset() reset}, this method will
410      * consume the entire input stream. Otherwise, each call to this
411      * method consumes one CRL and the read position of the input stream
412      * is positioned to the next available byte after the the inherent
413      * end-of-CRL marker. If the data in the
414      * input stream does not contain an inherent end-of-CRL marker (other
415      * than EOF) and there is trailing data after the CRL is parsed, a
416      * <code>CRLException</code> is thrown.
417      *
418      * @param inStream an input stream with the CRL data.
419      *
420      * @return a CRL object initialized with the data
421      * from the input stream.
422      *
423      * @exception CRLException on parsing errors.
424      */

425     public final CRL JavaDoc generateCRL(InputStream JavaDoc inStream)
426         throws CRLException JavaDoc
427     {
428     return certFacSpi.engineGenerateCRL(inStream);
429     }
430
431     /**
432      * Returns a (possibly empty) collection view of the CRLs read
433      * from the given input stream <code>inStream</code>.
434      *
435      * <p>In order to take advantage of the specialized CRL format
436      * supported by this certificate factory, each element in
437      * the returned collection view can be typecast to the corresponding
438      * CRL class. For example, if this certificate
439      * factory implements X.509 CRLs, the elements in the returned
440      * collection can be typecast to the <code>X509CRL</code> class.
441      *
442      * <p>In the case of a certificate factory for X.509 CRLs,
443      * <code>inStream</code> may contain a sequence of DER-encoded CRLs.
444      * In addition, <code>inStream</code> may contain a PKCS#7 CRL
445      * set. This is a PKCS#7 <i>SignedData</i> object, with the only
446      * significant field being <i>crls</i>. In particular, the
447      * signature and the contents are ignored. This format allows multiple
448      * CRLs to be downloaded at once. If no CRLs are present,
449      * an empty collection is returned.
450      *
451      * <p>Note that if the given input stream does not support
452      * {@link java.io.InputStream#mark(int) mark} and
453      * {@link java.io.InputStream#reset() reset}, this method will
454      * consume the entire input stream.
455      *
456      * @param inStream the input stream with the CRLs.
457      *
458      * @return a (possibly empty) collection view of
459      * java.security.cert.CRL objects initialized with the data from the input
460      * stream.
461      *
462      * @exception CRLException on parsing errors.
463      */

464     public final Collection JavaDoc<? extends CRL JavaDoc> generateCRLs(InputStream JavaDoc inStream)
465         throws CRLException JavaDoc {
466     return certFacSpi.engineGenerateCRLs(inStream);
467     }
468 }
469
Popular Tags