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