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 "LDAP" if no 403 * such property exists. The Java security properties file is located in 404 * the file named <JAVA_HOME>/lib/security/java.security. 405 * <JAVA_HOME> 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 "LDAP" 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