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