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 }