001 /*
002 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.security.cert;
027
028 import java.security.AccessController;
029 import java.security.InvalidAlgorithmParameterException;
030 import java.security.NoSuchAlgorithmException;
031 import java.security.NoSuchProviderException;
032 import java.security.PrivilegedAction;
033 import java.security.Provider;
034 import java.security.Security;
035 import java.util.Collection;
036
037 import sun.security.jca.*;
038 import sun.security.jca.GetInstance.Instance;
039
040 /**
041 * A class for retrieving <code>Certificate</code>s and <code>CRL</code>s
042 * from a repository.
043 * <p>
044 * This class uses a provider-based architecture.
045 * To create a <code>CertStore</code>, call one of the static
046 * <code>getInstance</code> methods, passing in the type of
047 * <code>CertStore</code> desired, any applicable initialization parameters
048 * and optionally the name of the provider desired.
049 * <p>
050 * Once the <code>CertStore</code> has been created, it can be used to
051 * retrieve <code>Certificate</code>s and <code>CRL</code>s by calling its
052 * {@link #getCertificates(CertSelector selector) getCertificates} and
053 * {@link #getCRLs(CRLSelector selector) getCRLs} methods.
054 * <p>
055 * Unlike a {@link java.security.KeyStore KeyStore}, which provides access
056 * to a cache of private keys and trusted certificates, a
057 * <code>CertStore</code> is designed to provide access to a potentially
058 * vast repository of untrusted certificates and CRLs. For example, an LDAP
059 * implementation of <code>CertStore</code> provides access to certificates
060 * and CRLs stored in one or more directories using the LDAP protocol and the
061 * schema as defined in the RFC service attribute. See Appendix A in the
062 * <a href= "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
063 * Java Certification Path API Programmer's Guide</a> for more information about
064 * standard <code>CertStore</code> types.
065 * <p>
066 * <b>Concurrent Access</b>
067 * <p>
068 * All public methods of <code>CertStore</code> objects must be thread-safe.
069 * That is, multiple threads may concurrently invoke these methods on a
070 * single <code>CertStore</code> object (or more than one) with no
071 * ill effects. This allows a <code>CertPathBuilder</code> to search for a
072 * CRL while simultaneously searching for further certificates, for instance.
073 * <p>
074 * The static methods of this class are also guaranteed to be thread-safe.
075 * Multiple threads may concurrently invoke the static methods defined in
076 * this class with no ill effects.
077 *
078 * @version 1.24 05/05/07
079 * @since 1.4
080 * @author Sean Mullan, Steve Hanna
081 */
082 public class CertStore {
083 /*
084 * Constant to lookup in the Security properties file to determine
085 * the default certstore type. In the Security properties file, the
086 * default certstore type is given as:
087 * <pre>
088 * certstore.type=LDAP
089 * </pre>
090 */
091 private static final String CERTSTORE_TYPE = "certstore.type";
092 private CertStoreSpi storeSpi;
093 private Provider provider;
094 private String type;
095 private CertStoreParameters params;
096
097 /**
098 * Creates a <code>CertStore</code> object of the given type, and
099 * encapsulates the given provider implementation (SPI object) in it.
100 *
101 * @param storeSpi the provider implementation
102 * @param provider the provider
103 * @param type the type
104 * @param params the initialization parameters (may be <code>null</code>)
105 */
106 protected CertStore(CertStoreSpi storeSpi, Provider provider,
107 String type, CertStoreParameters params) {
108 this .storeSpi = storeSpi;
109 this .provider = provider;
110 this .type = type;
111 if (params != null)
112 this .params = (CertStoreParameters) params.clone();
113 }
114
115 /**
116 * Returns a <code>Collection</code> of <code>Certificate</code>s that
117 * match the specified selector. If no <code>Certificate</code>s
118 * match the selector, an empty <code>Collection</code> will be returned.
119 * <p>
120 * For some <code>CertStore</code> types, the resulting
121 * <code>Collection</code> may not contain <b>all</b> of the
122 * <code>Certificate</code>s that match the selector. For instance,
123 * an LDAP <code>CertStore</code> may not search all entries in the
124 * directory. Instead, it may just search entries that are likely to
125 * contain the <code>Certificate</code>s it is looking for.
126 * <p>
127 * Some <code>CertStore</code> implementations (especially LDAP
128 * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
129 * unless a non-null <code>CertSelector</code> is provided that
130 * includes specific criteria that can be used to find the certificates.
131 * Issuer and/or subject names are especially useful criteria.
132 *
133 * @param selector A <code>CertSelector</code> used to select which
134 * <code>Certificate</code>s should be returned. Specify <code>null</code>
135 * to return all <code>Certificate</code>s (if supported).
136 * @return A <code>Collection</code> of <code>Certificate</code>s that
137 * match the specified selector (never <code>null</code>)
138 * @throws CertStoreException if an exception occurs
139 */
140 public final Collection<? extends Certificate> getCertificates(
141 CertSelector selector) throws CertStoreException {
142 return storeSpi.engineGetCertificates(selector);
143 }
144
145 /**
146 * Returns a <code>Collection</code> of <code>CRL</code>s that
147 * match the specified selector. If no <code>CRL</code>s
148 * match the selector, an empty <code>Collection</code> will be returned.
149 * <p>
150 * For some <code>CertStore</code> types, the resulting
151 * <code>Collection</code> may not contain <b>all</b> of the
152 * <code>CRL</code>s that match the selector. For instance,
153 * an LDAP <code>CertStore</code> may not search all entries in the
154 * directory. Instead, it may just search entries that are likely to
155 * contain the <code>CRL</code>s it is looking for.
156 * <p>
157 * Some <code>CertStore</code> implementations (especially LDAP
158 * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
159 * unless a non-null <code>CRLSelector</code> is provided that
160 * includes specific criteria that can be used to find the CRLs.
161 * Issuer names and/or the certificate to be checked are especially useful.
162 *
163 * @param selector A <code>CRLSelector</code> used to select which
164 * <code>CRL</code>s should be returned. Specify <code>null</code>
165 * to return all <code>CRL</code>s (if supported).
166 * @return A <code>Collection</code> of <code>CRL</code>s that
167 * match the specified selector (never <code>null</code>)
168 * @throws CertStoreException if an exception occurs
169 */
170 public final Collection<? extends CRL> getCRLs(CRLSelector selector)
171 throws CertStoreException {
172 return storeSpi.engineGetCRLs(selector);
173 }
174
175 /**
176 * Returns a <code>CertStore</code> object that implements the specified
177 * <code>CertStore</code> type and is initialized with the specified
178 * parameters.
179 *
180 * <p> This method traverses the list of registered security Providers,
181 * starting with the most preferred Provider.
182 * A new CertStore object encapsulating the
183 * CertStoreSpi implementation from the first
184 * Provider that supports the specified type is returned.
185 *
186 * <p> Note that the list of registered providers may be retrieved via
187 * the {@link Security#getProviders() Security.getProviders()} method.
188 *
189 * <p>The <code>CertStore</code> that is returned is initialized with the
190 * specified <code>CertStoreParameters</code>. The type of parameters
191 * needed may vary between different types of <code>CertStore</code>s.
192 * Note that the specified <code>CertStoreParameters</code> object is
193 * cloned.
194 *
195 * @param type the name of the requested <code>CertStore</code> type.
196 * See Appendix A in the <a href=
197 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
198 * Java Certification Path API Programmer's Guide </a>
199 * for information about standard types.
200 *
201 * @param params the initialization parameters (may be <code>null</code>).
202 *
203 * @return a <code>CertStore</code> object that implements the specified
204 * <code>CertStore</code> type.
205 *
206 * @throws NoSuchAlgorithmException if no Provider supports a
207 * CertStoreSpi implementation for the specified type.
208 *
209 * @throws InvalidAlgorithmParameterException if the specified
210 * initialization parameters are inappropriate for this
211 * <code>CertStore</code>.
212 *
213 * @see java.security.Provider
214 */
215 public static CertStore getInstance(String type,
216 CertStoreParameters params)
217 throws InvalidAlgorithmParameterException,
218 NoSuchAlgorithmException {
219 try {
220 Instance instance = GetInstance.getInstance("CertStore",
221 CertStoreSpi.class, type, params);
222 return new CertStore((CertStoreSpi) instance.impl,
223 instance.provider, type, params);
224 } catch (NoSuchAlgorithmException e) {
225 return handleException(e);
226 }
227 }
228
229 private static CertStore handleException(NoSuchAlgorithmException e)
230 throws NoSuchAlgorithmException,
231 InvalidAlgorithmParameterException {
232 Throwable cause = e.getCause();
233 if (cause instanceof InvalidAlgorithmParameterException) {
234 throw (InvalidAlgorithmParameterException) cause;
235 }
236 throw e;
237 }
238
239 /**
240 * Returns a <code>CertStore</code> object that implements the specified
241 * <code>CertStore</code> type.
242 *
243 * <p> A new CertStore object encapsulating the
244 * CertStoreSpi implementation from the specified provider
245 * is returned. The specified provider must be registered
246 * in the security provider list.
247 *
248 * <p> Note that the list of registered providers may be retrieved via
249 * the {@link Security#getProviders() Security.getProviders()} method.
250 *
251 * <p>The <code>CertStore</code> that is returned is initialized with the
252 * specified <code>CertStoreParameters</code>. The type of parameters
253 * needed may vary between different types of <code>CertStore</code>s.
254 * Note that the specified <code>CertStoreParameters</code> object is
255 * cloned.
256 *
257 * @param type the requested <code>CertStore</code> type.
258 * See Appendix A in the <a href=
259 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
260 * Java Certification Path API Programmer's Guide </a>
261 * for information about standard types.
262 *
263 * @param params the initialization parameters (may be <code>null</code>).
264 *
265 * @param provider the name of the provider.
266 *
267 * @return a <code>CertStore</code> object that implements the
268 * specified type.
269 *
270 * @throws NoSuchAlgorithmException if a CertStoreSpi
271 * implementation for the specified type is not
272 * available from the specified provider.
273 *
274 * @throws InvalidAlgorithmParameterException if the specified
275 * initialization parameters are inappropriate for this
276 * <code>CertStore</code>.
277 *
278 * @throws NoSuchProviderException if the specified provider is not
279 * registered in the security provider list.
280 *
281 * @exception IllegalArgumentException if the <code>provider</code> is
282 * null or empty.
283 *
284 * @see java.security.Provider
285 */
286 public static CertStore getInstance(String type,
287 CertStoreParameters params, String provider)
288 throws InvalidAlgorithmParameterException,
289 NoSuchAlgorithmException, NoSuchProviderException {
290 try {
291 Instance instance = GetInstance.getInstance("CertStore",
292 CertStoreSpi.class, type, params, provider);
293 return new CertStore((CertStoreSpi) instance.impl,
294 instance.provider, type, params);
295 } catch (NoSuchAlgorithmException e) {
296 return handleException(e);
297 }
298 }
299
300 /**
301 * Returns a <code>CertStore</code> object that implements the specified
302 * <code>CertStore</code> type.
303 *
304 * <p> A new CertStore object encapsulating the
305 * CertStoreSpi implementation from the specified Provider
306 * object is returned. Note that the specified Provider object
307 * does not have to be registered in the provider list.
308 *
309 * <p>The <code>CertStore</code> that is returned is initialized with the
310 * specified <code>CertStoreParameters</code>. The type of parameters
311 * needed may vary between different types of <code>CertStore</code>s.
312 * Note that the specified <code>CertStoreParameters</code> object is
313 * cloned.
314 *
315 * @param type the requested <code>CertStore</code> type.
316 * See Appendix A in the <a href=
317 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
318 * Java Certification Path API Programmer's Guide </a>
319 * for information about standard types.
320 *
321 * @param params the initialization parameters (may be <code>null</code>).
322 *
323 * @param provider the provider.
324 *
325 * @return a <code>CertStore</code> object that implements the
326 * specified type.
327 *
328 * @exception NoSuchAlgorithmException if a CertStoreSpi
329 * implementation for the specified type is not available
330 * from the specified Provider object.
331 *
332 * @throws InvalidAlgorithmParameterException if the specified
333 * initialization parameters are inappropriate for this
334 * <code>CertStore</code>
335 *
336 * @exception IllegalArgumentException if the <code>provider</code> is
337 * null.
338 *
339 * @see java.security.Provider
340 */
341 public static CertStore getInstance(String type,
342 CertStoreParameters params, Provider provider)
343 throws NoSuchAlgorithmException,
344 InvalidAlgorithmParameterException {
345 try {
346 Instance instance = GetInstance.getInstance("CertStore",
347 CertStoreSpi.class, type, params, provider);
348 return new CertStore((CertStoreSpi) instance.impl,
349 instance.provider, type, params);
350 } catch (NoSuchAlgorithmException e) {
351 return handleException(e);
352 }
353 }
354
355 /**
356 * Returns the parameters used to initialize this <code>CertStore</code>.
357 * Note that the <code>CertStoreParameters</code> object is cloned before
358 * it is returned.
359 *
360 * @return the parameters used to initialize this <code>CertStore</code>
361 * (may be <code>null</code>)
362 */
363 public final CertStoreParameters getCertStoreParameters() {
364 return (params == null ? null : (CertStoreParameters) params
365 .clone());
366 }
367
368 /**
369 * Returns the type of this <code>CertStore</code>.
370 *
371 * @return the type of this <code>CertStore</code>
372 */
373 public final String getType() {
374 return this .type;
375 }
376
377 /**
378 * Returns the provider of this <code>CertStore</code>.
379 *
380 * @return the provider of this <code>CertStore</code>
381 */
382 public final Provider getProvider() {
383 return this .provider;
384 }
385
386 /**
387 * Returns the default <code>CertStore</code> type as specified in the
388 * Java security properties file, or the string "LDAP" if no
389 * such property exists. The Java security properties file is located in
390 * the file named <JAVA_HOME>/lib/security/java.security.
391 * <JAVA_HOME> refers to the value of the java.home system property,
392 * and specifies the directory where the JRE is installed.
393 *
394 * <p>The default <code>CertStore</code> type can be used by applications
395 * that do not want to use a hard-coded type when calling one of the
396 * <code>getInstance</code> methods, and want to provide a default
397 * <code>CertStore</code> type in case a user does not specify its own.
398 *
399 * <p>The default <code>CertStore</code> type can be changed by setting
400 * the value of the "certstore.type" security property (in the Java
401 * security properties file) to the desired type.
402 *
403 * @return the default <code>CertStore</code> type as specified in the
404 * Java security properties file, or the string "LDAP"
405 * if no such property exists.
406 */
407 public final static String getDefaultType() {
408 String cstype;
409 cstype = AccessController
410 .doPrivileged(new PrivilegedAction<String>() {
411 public String run() {
412 return Security.getProperty(CERTSTORE_TYPE);
413 }
414 });
415 if (cstype == null) {
416 cstype = "LDAP";
417 }
418 return cstype;
419 }
420 }
|