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