Home | History | Annotate | Download | only in cert
      1 /*
      2  * Copyright (c) 2000, 2011, 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.security.AccessController;
     29 import java.security.InvalidAlgorithmParameterException;
     30 import java.security.NoSuchAlgorithmException;
     31 import java.security.NoSuchProviderException;
     32 import java.security.PrivilegedAction;
     33 import java.security.Provider;
     34 import java.security.Security;
     35 import java.util.Collection;
     36 
     37 import sun.security.jca.*;
     38 import sun.security.jca.GetInstance.Instance;
     39 
     40 /**
     41  * A class for retrieving <code>Certificate</code>s and <code>CRL</code>s
     42  * from a repository.
     43  * <p>
     44  * This class uses a provider-based architecture.
     45  * To create a <code>CertStore</code>, call one of the static
     46  * <code>getInstance</code> methods, passing in the type of
     47  * <code>CertStore</code> desired, any applicable initialization parameters
     48  * and optionally the name of the provider desired.
     49  * <p>
     50  * Once the <code>CertStore</code> has been created, it can be used to
     51  * retrieve <code>Certificate</code>s and <code>CRL</code>s by calling its
     52  * {@link #getCertificates(CertSelector selector) getCertificates} and
     53  * {@link #getCRLs(CRLSelector selector) getCRLs} methods.
     54  * <p>
     55  * Unlike a {@link java.security.KeyStore KeyStore}, which provides access
     56  * to a cache of private keys and trusted certificates, a
     57  * <code>CertStore</code> is designed to provide access to a potentially
     58  * vast repository of untrusted certificates and CRLs. For example, an LDAP
     59  * implementation of <code>CertStore</code> provides access to certificates
     60  * and CRLs stored in one or more directories using the LDAP protocol and the
     61  * schema as defined in the RFC service attribute.
     62  *
     63  * <p> Android provides the following <code>CertStore</code> types:
     64  * <table>
     65  *     <thead>
     66  *         <tr>
     67  *             <th>Name</th>
     68  *             <th>Supported (API Levels)</th>
     69  *         </tr>
     70  *     </thead>
     71  *     <tbody>
     72  *         <tr>
     73  *             <td>Collection</td>
     74  *             <td>1+</td>
     75  *         </tr>
     76  *     </tbody>
     77  * </table>
     78  *
     79  * This type is described in the <a href=
     80  * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
     81  * CertStore section</a> of the
     82  * Java Cryptography Architecture Standard Algorithm Name Documentation.
     83  *
     84  * <p>
     85  * <b>Concurrent Access</b>
     86  * <p>
     87  * All public methods of <code>CertStore</code> objects must be thread-safe.
     88  * That is, multiple threads may concurrently invoke these methods on a
     89  * single <code>CertStore</code> object (or more than one) with no
     90  * ill effects. This allows a <code>CertPathBuilder</code> to search for a
     91  * CRL while simultaneously searching for further certificates, for instance.
     92  * <p>
     93  * The static methods of this class are also guaranteed to be thread-safe.
     94  * Multiple threads may concurrently invoke the static methods defined in
     95  * this class with no ill effects.
     96  *
     97  * @since       1.4
     98  * @author      Sean Mullan, Steve Hanna
     99  */
    100 public class CertStore {
    101     /*
    102      * Constant to lookup in the Security properties file to determine
    103      * the default certstore type. In the Security properties file, the
    104      * default certstore type is given as:
    105      * <pre>
    106      * certstore.type=LDAP
    107      * </pre>
    108      */
    109     private static final String CERTSTORE_TYPE = "certstore.type";
    110     private CertStoreSpi storeSpi;
    111     private Provider provider;
    112     private String type;
    113     private CertStoreParameters params;
    114 
    115     /**
    116      * Creates a <code>CertStore</code> object of the given type, and
    117      * encapsulates the given provider implementation (SPI object) in it.
    118      *
    119      * @param storeSpi the provider implementation
    120      * @param provider the provider
    121      * @param type the type
    122      * @param params the initialization parameters (may be <code>null</code>)
    123      */
    124     protected CertStore(CertStoreSpi storeSpi, Provider provider,
    125                         String type, CertStoreParameters params) {
    126         this.storeSpi = storeSpi;
    127         this.provider = provider;
    128         this.type = type;
    129         if (params != null)
    130             this.params = (CertStoreParameters) params.clone();
    131     }
    132 
    133     /**
    134      * Returns a <code>Collection</code> of <code>Certificate</code>s that
    135      * match the specified selector. If no <code>Certificate</code>s
    136      * match the selector, an empty <code>Collection</code> will be returned.
    137      * <p>
    138      * For some <code>CertStore</code> types, the resulting
    139      * <code>Collection</code> may not contain <b>all</b> of the
    140      * <code>Certificate</code>s that match the selector. For instance,
    141      * an LDAP <code>CertStore</code> may not search all entries in the
    142      * directory. Instead, it may just search entries that are likely to
    143      * contain the <code>Certificate</code>s it is looking for.
    144      * <p>
    145      * Some <code>CertStore</code> implementations (especially LDAP
    146      * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
    147      * unless a non-null <code>CertSelector</code> is provided that
    148      * includes specific criteria that can be used to find the certificates.
    149      * Issuer and/or subject names are especially useful criteria.
    150      *
    151      * @param selector A <code>CertSelector</code> used to select which
    152      *  <code>Certificate</code>s should be returned. Specify <code>null</code>
    153      *  to return all <code>Certificate</code>s (if supported).
    154      * @return A <code>Collection</code> of <code>Certificate</code>s that
    155      *         match the specified selector (never <code>null</code>)
    156      * @throws CertStoreException if an exception occurs
    157      */
    158     public final Collection<? extends Certificate> getCertificates
    159             (CertSelector selector) throws CertStoreException {
    160         return storeSpi.engineGetCertificates(selector);
    161     }
    162 
    163     /**
    164      * Returns a <code>Collection</code> of <code>CRL</code>s that
    165      * match the specified selector. If no <code>CRL</code>s
    166      * match the selector, an empty <code>Collection</code> will be returned.
    167      * <p>
    168      * For some <code>CertStore</code> types, the resulting
    169      * <code>Collection</code> may not contain <b>all</b> of the
    170      * <code>CRL</code>s that match the selector. For instance,
    171      * an LDAP <code>CertStore</code> may not search all entries in the
    172      * directory. Instead, it may just search entries that are likely to
    173      * contain the <code>CRL</code>s it is looking for.
    174      * <p>
    175      * Some <code>CertStore</code> implementations (especially LDAP
    176      * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
    177      * unless a non-null <code>CRLSelector</code> is provided that
    178      * includes specific criteria that can be used to find the CRLs.
    179      * Issuer names and/or the certificate to be checked are especially useful.
    180      *
    181      * @param selector A <code>CRLSelector</code> used to select which
    182      *  <code>CRL</code>s should be returned. Specify <code>null</code>
    183      *  to return all <code>CRL</code>s (if supported).
    184      * @return A <code>Collection</code> of <code>CRL</code>s that
    185      *         match the specified selector (never <code>null</code>)
    186      * @throws CertStoreException if an exception occurs
    187      */
    188     public final Collection<? extends CRL> getCRLs(CRLSelector selector)
    189             throws CertStoreException {
    190         return storeSpi.engineGetCRLs(selector);
    191     }
    192 
    193     /**
    194      * Returns a <code>CertStore</code> object that implements the specified
    195      * <code>CertStore</code> type and is initialized with the specified
    196      * parameters.
    197      *
    198      * <p> This method traverses the list of registered security Providers,
    199      * starting with the most preferred Provider.
    200      * A new CertStore object encapsulating the
    201      * CertStoreSpi implementation from the first
    202      * Provider that supports the specified type is returned.
    203      *
    204      * <p> Note that the list of registered providers may be retrieved via
    205      * the {@link Security#getProviders() Security.getProviders()} method.
    206      *
    207      * <p>The <code>CertStore</code> that is returned is initialized with the
    208      * specified <code>CertStoreParameters</code>. The type of parameters
    209      * needed may vary between different types of <code>CertStore</code>s.
    210      * Note that the specified <code>CertStoreParameters</code> object is
    211      * cloned.
    212      *
    213      * @param type the name of the requested <code>CertStore</code> type.
    214      * See the CertStore section in the <a href=
    215      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
    216      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    217      * for information about standard types.
    218      *
    219      * @param params the initialization parameters (may be <code>null</code>).
    220      *
    221      * @return a <code>CertStore</code> object that implements the specified
    222      *          <code>CertStore</code> type.
    223      *
    224      * @throws NoSuchAlgorithmException if no Provider supports a
    225      *          CertStoreSpi implementation for the specified type.
    226      *
    227      * @throws InvalidAlgorithmParameterException if the specified
    228      *          initialization parameters are inappropriate for this
    229      *          <code>CertStore</code>.
    230      *
    231      * @see java.security.Provider
    232      */
    233     public static CertStore getInstance(String type, CertStoreParameters params)
    234             throws InvalidAlgorithmParameterException,
    235             NoSuchAlgorithmException {
    236         try {
    237             Instance instance = GetInstance.getInstance("CertStore",
    238                 CertStoreSpi.class, type, params);
    239             return new CertStore((CertStoreSpi)instance.impl,
    240                 instance.provider, type, params);
    241         } catch (NoSuchAlgorithmException e) {
    242             return handleException(e);
    243         }
    244     }
    245 
    246     private static CertStore handleException(NoSuchAlgorithmException e)
    247             throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    248         Throwable cause = e.getCause();
    249         if (cause instanceof InvalidAlgorithmParameterException) {
    250             throw (InvalidAlgorithmParameterException)cause;
    251         }
    252         throw e;
    253     }
    254 
    255     /**
    256      * Returns a <code>CertStore</code> object that implements the specified
    257      * <code>CertStore</code> type.
    258      *
    259      * <p> A new CertStore object encapsulating the
    260      * CertStoreSpi implementation from the specified provider
    261      * is returned.  The specified provider must be registered
    262      * in the security provider list.
    263      *
    264      * <p> Note that the list of registered providers may be retrieved via
    265      * the {@link Security#getProviders() Security.getProviders()} method.
    266      *
    267      * <p>The <code>CertStore</code> that is returned is initialized with the
    268      * specified <code>CertStoreParameters</code>. The type of parameters
    269      * needed may vary between different types of <code>CertStore</code>s.
    270      * Note that the specified <code>CertStoreParameters</code> object is
    271      * cloned.
    272      *
    273      * @param type the requested <code>CertStore</code> type.
    274      * See the CertStore section in the <a href=
    275      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
    276      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    277      * for information about standard types.
    278      *
    279      * @param params the initialization parameters (may be <code>null</code>).
    280      *
    281      * @param provider the name of the provider.
    282      *
    283      * @return a <code>CertStore</code> object that implements the
    284      *          specified type.
    285      *
    286      * @throws NoSuchAlgorithmException if a CertStoreSpi
    287      *          implementation for the specified type is not
    288      *          available from the specified provider.
    289      *
    290      * @throws InvalidAlgorithmParameterException if the specified
    291      *          initialization parameters are inappropriate for this
    292      *          <code>CertStore</code>.
    293      *
    294      * @throws NoSuchProviderException if the specified provider is not
    295      *          registered in the security provider list.
    296      *
    297      * @exception IllegalArgumentException if the <code>provider</code> is
    298      *          null or empty.
    299      *
    300      * @see java.security.Provider
    301      */
    302     public static CertStore getInstance(String type,
    303             CertStoreParameters params, String provider)
    304             throws InvalidAlgorithmParameterException,
    305             NoSuchAlgorithmException, NoSuchProviderException {
    306         try {
    307             Instance instance = GetInstance.getInstance("CertStore",
    308                 CertStoreSpi.class, type, params, provider);
    309             return new CertStore((CertStoreSpi)instance.impl,
    310                 instance.provider, type, params);
    311         } catch (NoSuchAlgorithmException e) {
    312             return handleException(e);
    313         }
    314     }
    315 
    316     /**
    317      * Returns a <code>CertStore</code> object that implements the specified
    318      * <code>CertStore</code> type.
    319      *
    320      * <p> A new CertStore object encapsulating the
    321      * CertStoreSpi implementation from the specified Provider
    322      * object is returned.  Note that the specified Provider object
    323      * does not have to be registered in the provider list.
    324      *
    325      * <p>The <code>CertStore</code> that is returned is initialized with the
    326      * specified <code>CertStoreParameters</code>. The type of parameters
    327      * needed may vary between different types of <code>CertStore</code>s.
    328      * Note that the specified <code>CertStoreParameters</code> object is
    329      * cloned.
    330      *
    331      * @param type the requested <code>CertStore</code> type.
    332      * See the CertStore section in the <a href=
    333      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#CertStore">
    334      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    335      * for information about standard types.
    336      *
    337      * @param params the initialization parameters (may be <code>null</code>).
    338      *
    339      * @param provider the provider.
    340      *
    341      * @return a <code>CertStore</code> object that implements the
    342      *          specified type.
    343      *
    344      * @exception NoSuchAlgorithmException if a CertStoreSpi
    345      *          implementation for the specified type is not available
    346      *          from the specified Provider object.
    347      *
    348      * @throws InvalidAlgorithmParameterException if the specified
    349      *          initialization parameters are inappropriate for this
    350      *          <code>CertStore</code>
    351      *
    352      * @exception IllegalArgumentException if the <code>provider</code> is
    353      *          null.
    354      *
    355      * @see java.security.Provider
    356      */
    357     public static CertStore getInstance(String type, CertStoreParameters params,
    358             Provider provider) throws NoSuchAlgorithmException,
    359             InvalidAlgorithmParameterException {
    360         try {
    361             Instance instance = GetInstance.getInstance("CertStore",
    362                 CertStoreSpi.class, type, params, provider);
    363             return new CertStore((CertStoreSpi)instance.impl,
    364                 instance.provider, type, params);
    365         } catch (NoSuchAlgorithmException e) {
    366             return handleException(e);
    367         }
    368     }
    369 
    370     /**
    371      * Returns the parameters used to initialize this <code>CertStore</code>.
    372      * Note that the <code>CertStoreParameters</code> object is cloned before
    373      * it is returned.
    374      *
    375      * @return the parameters used to initialize this <code>CertStore</code>
    376      * (may be <code>null</code>)
    377      */
    378     public final CertStoreParameters getCertStoreParameters() {
    379         return (params == null ? null : (CertStoreParameters) params.clone());
    380     }
    381 
    382     /**
    383      * Returns the type of this <code>CertStore</code>.
    384      *
    385      * @return the type of this <code>CertStore</code>
    386      */
    387     public final String getType() {
    388         return this.type;
    389     }
    390 
    391     /**
    392      * Returns the provider of this <code>CertStore</code>.
    393      *
    394      * @return the provider of this <code>CertStore</code>
    395      */
    396     public final Provider getProvider() {
    397         return this.provider;
    398     }
    399 
    400     /**
    401      * Returns the default <code>CertStore</code> type as specified in the
    402      * Java security properties file, or the string &quot;LDAP&quot; if no
    403      * such property exists. The Java security properties file is located in
    404      * the file named &lt;JAVA_HOME&gt;/lib/security/java.security.
    405      * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
    406      * and specifies the directory where the JRE is installed.
    407      *
    408      * <p>The default <code>CertStore</code> type can be used by applications
    409      * that do not want to use a hard-coded type when calling one of the
    410      * <code>getInstance</code> methods, and want to provide a default
    411      * <code>CertStore</code> type in case a user does not specify its own.
    412      *
    413      * <p>The default <code>CertStore</code> type can be changed by setting
    414      * the value of the "certstore.type" security property (in the Java
    415      * security properties file) to the desired type.
    416      *
    417      * @return the default <code>CertStore</code> type as specified in the
    418      * Java security properties file, or the string &quot;LDAP&quot;
    419      * if no such property exists.
    420      */
    421     public final static String getDefaultType() {
    422         String cstype;
    423         cstype = AccessController.doPrivileged(new PrivilegedAction<String>() {
    424             public String run() {
    425                 return Security.getProperty(CERTSTORE_TYPE);
    426             }
    427         });
    428         if (cstype == null) {
    429             cstype = "LDAP";
    430         }
    431         return cstype;
    432     }
    433 }
    434