1 /* 2 * Copyright (c) 1998, 2016, 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}/../technotes/guides/security/StandardNames.html#CertificateFactory"> 105 * CertificateFactory section</a> and the <a href= 106 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathEncodings"> 107 * CertPath Encodings section</a> of the 108 * Java Cryptography Architecture Standard Algorithm Name Documentation. 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}/../technotes/guides/security/StandardNames.html#CertificateFactory"> 176 * Java Cryptography Architecture Standard Algorithm Name Documentation</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}/../technotes/guides/security/StandardNames.html#CertificateFactory"> 217 * Java Cryptography Architecture Standard Algorithm Name Documentation</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}/../technotes/guides/security/StandardNames.html#CertificateFactory"> 264 * Java Cryptography Architecture Standard Algorithm Name Documentation</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}/../technotes/guides/security/StandardNames.html#CertPathEncodings"> 363 * Java Cryptography Architecture Standard Algorithm Name Documentation</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}/../technotes/guides/security/StandardNames.html#CertPathEncodings"> 403 * Java Cryptography Architecture Standard Algorithm Name Documentation</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 }