src/java.base/share/classes/java/security/cert/CertificateFactory.java
changeset 47216 71c04702a3d5
parent 45118 e4258d800b54
child 58242 94bb65cb37d3
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1998, 2017, 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}/../specs/security/standard-names.html#certificatefactory-types">
       
   105  * CertificateFactory section</a> and the <a href=
       
   106  * "{@docRoot}/../specs/security/standard-names.html#certpath-encodings">
       
   107  * CertPath Encodings section</a> of the
       
   108  * Java Security Standard Algorithm Names Specification.
       
   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}/../specs/security/standard-names.html#certificatefactory-types">
       
   176      * Java Security Standard Algorithm Names Specification</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}/../specs/security/standard-names.html#certificatefactory-types">
       
   217      * Java Security Standard Algorithm Names Specification</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}/../specs/security/standard-names.html#certificatefactory-types">
       
   264      * Java Security Standard Algorithm Names Specification</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}/../specs/security/standard-names.html#certpath-encodings">
       
   363      * Java Security Standard Algorithm Names Specification</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}/../specs/security/standard-names.html#certpath-encodings">
       
   403      * Java Security Standard Algorithm Names Specification</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 }