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