• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
CertStore(CertStoreSpi storeSpi, Provider provider, String type, CertStoreParameters params)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      */
getCertificates(CertSelector selector)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      */
getCRLs(CRLSelector selector)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      */
getInstance(String type, CertStoreParameters params)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 
handleException(NoSuchAlgorithmException e)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      */
getInstance(String type, CertStoreParameters params, String provider)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      */
getInstance(String type, CertStoreParameters params, Provider provider)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      */
getCertStoreParameters()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      */
getType()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      */
getProvider()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      */
getDefaultType()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