1. /*
  2. * @(#)CertStore.java 1.13 04/06/28
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.security.cert;
  8. import java.security.AccessController;
  9. import java.security.InvalidAlgorithmParameterException;
  10. import java.security.NoSuchAlgorithmException;
  11. import java.security.NoSuchProviderException;
  12. import java.security.PrivilegedAction;
  13. import java.security.Provider;
  14. import java.security.Security;
  15. import java.util.Collection;
  16. import sun.security.jca.*;
  17. import sun.security.jca.GetInstance.Instance;
  18. /**
  19. * A class for retrieving <code>Certificate</code>s and <code>CRL</code>s
  20. * from a repository.
  21. * <p>
  22. * This class uses a provider-based architecture, as described in the
  23. * Java Cryptography Architecture.
  24. * To create a <code>CertStore</code>, call one of the static
  25. * <code>getInstance</code> methods, passing in the type of
  26. * <code>CertStore</code> desired, any applicable initialization parameters
  27. * and optionally the name of the provider desired.
  28. * <p>
  29. * Once the <code>CertStore</code> has been created, it can be used to
  30. * retrieve <code>Certificate</code>s and <code>CRL</code>s by calling its
  31. * {@link #getCertificates(CertSelector selector) getCertificates} and
  32. * {@link #getCRLs(CRLSelector selector) getCRLs} methods.
  33. * <p>
  34. * Unlike a {@link java.security.KeyStore KeyStore}, which provides access
  35. * to a cache of private keys and trusted certificates, a
  36. * <code>CertStore</code> is designed to provide access to a potentially
  37. * vast repository of untrusted certificates and CRLs. For example, an LDAP
  38. * implementation of <code>CertStore</code> provides access to certificates
  39. * and CRLs stored in one or more directories using the LDAP protocol and the
  40. * schema as defined in the RFC service attribute. See Appendix A in the
  41. * <a href= "../../../../guide/security/certpath/CertPathProgGuide.html#AppA">
  42. * Java Certification Path API Programmer's Guide</a> for more information about
  43. * standard <code>CertStore</code> types.
  44. * <p>
  45. * <b>Concurrent Access</b>
  46. * <p>
  47. * All public methods of <code>CertStore</code> objects must be thread-safe.
  48. * That is, multiple threads may concurrently invoke these methods on a
  49. * single <code>CertStore</code> object (or more than one) with no
  50. * ill effects. This allows a <code>CertPathBuilder</code> to search for a
  51. * CRL while simultaneously searching for further certificates, for instance.
  52. * <p>
  53. * The static methods of this class are also guaranteed to be thread-safe.
  54. * Multiple threads may concurrently invoke the static methods defined in
  55. * this class with no ill effects.
  56. *
  57. * @version 1.13 06/28/04
  58. * @since 1.4
  59. * @author Sean Mullan, Steve Hanna
  60. */
  61. public class CertStore {
  62. /*
  63. * Constant to lookup in the Security properties file to determine
  64. * the default certstore type. In the Security properties file, the
  65. * default certstore type is given as:
  66. * <pre>
  67. * certstore.type=LDAP
  68. * </pre>
  69. */
  70. private static final String CERTSTORE_TYPE = "certstore.type";
  71. private CertStoreSpi storeSpi;
  72. private Provider provider;
  73. private String type;
  74. private CertStoreParameters params;
  75. /**
  76. * Creates a <code>CertStore</code> object of the given type, and
  77. * encapsulates the given provider implementation (SPI object) in it.
  78. *
  79. * @param storeSpi the provider implementation
  80. * @param provider the provider
  81. * @param type the type
  82. * @param params the initialization parameters (may be <code>null</code>)
  83. */
  84. protected CertStore(CertStoreSpi storeSpi, Provider provider,
  85. String type, CertStoreParameters params) {
  86. this.storeSpi = storeSpi;
  87. this.provider = provider;
  88. this.type = type;
  89. if (params != null)
  90. this.params = (CertStoreParameters) params.clone();
  91. }
  92. /**
  93. * Returns a <code>Collection</code> of <code>Certificate</code>s that
  94. * match the specified selector. If no <code>Certificate</code>s
  95. * match the selector, an empty <code>Collection</code> will be returned.
  96. * <p>
  97. * For some <code>CertStore</code> types, the resulting
  98. * <code>Collection</code> may not contain <b>all</b> of the
  99. * <code>Certificate</code>s that match the selector. For instance,
  100. * an LDAP <code>CertStore</code> may not search all entries in the
  101. * directory. Instead, it may just search entries that are likely to
  102. * contain the <code>Certificate</code>s it is looking for.
  103. * <p>
  104. * Some <code>CertStore</code> implementations (especially LDAP
  105. * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
  106. * unless a non-null <code>CertSelector</code> is provided that
  107. * includes specific criteria that can be used to find the certificates.
  108. * Issuer and/or subject names are especially useful criteria.
  109. *
  110. * @param selector A <code>CertSelector</code> used to select which
  111. * <code>Certificate</code>s should be returned. Specify <code>null</code>
  112. * to return all <code>Certificate</code>s (if supported).
  113. * @return A <code>Collection</code> of <code>Certificate</code>s that
  114. * match the specified selector (never <code>null</code>)
  115. * @throws CertStoreException if an exception occurs
  116. */
  117. public final Collection<? extends Certificate> getCertificates
  118. (CertSelector selector) throws CertStoreException {
  119. return storeSpi.engineGetCertificates(selector);
  120. }
  121. /**
  122. * Returns a <code>Collection</code> of <code>CRL</code>s that
  123. * match the specified selector. If no <code>CRL</code>s
  124. * match the selector, an empty <code>Collection</code> will be returned.
  125. * <p>
  126. * For some <code>CertStore</code> types, the resulting
  127. * <code>Collection</code> may not contain <b>all</b> of the
  128. * <code>CRL</code>s that match the selector. For instance,
  129. * an LDAP <code>CertStore</code> may not search all entries in the
  130. * directory. Instead, it may just search entries that are likely to
  131. * contain the <code>CRL</code>s it is looking for.
  132. * <p>
  133. * Some <code>CertStore</code> implementations (especially LDAP
  134. * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
  135. * unless a non-null <code>CRLSelector</code> is provided that
  136. * includes specific criteria that can be used to find the CRLs.
  137. * Issuer names and/or the certificate to be checked are especially useful.
  138. *
  139. * @param selector A <code>CRLSelector</code> used to select which
  140. * <code>CRL</code>s should be returned. Specify <code>null</code>
  141. * to return all <code>CRL</code>s (if supported).
  142. * @return A <code>Collection</code> of <code>CRL</code>s that
  143. * match the specified selector (never <code>null</code>)
  144. * @throws CertStoreException if an exception occurs
  145. */
  146. public final Collection<? extends CRL> getCRLs(CRLSelector selector)
  147. throws CertStoreException {
  148. return storeSpi.engineGetCRLs(selector);
  149. }
  150. /**
  151. * Returns a <code>CertStore</code> object that implements the specified
  152. * <code>CertStore</code> type and is initialized with the specified
  153. * parameters.
  154. *
  155. * <p>If the default provider package provides an implementation
  156. * of the specified <code>CertStore</code> type, an instance of
  157. * <code>CertStore</code> containing that implementation is returned.
  158. * If the requested type is not available in the default package, other
  159. * packages are searched.
  160. *
  161. * <p>The <code>CertStore</code> that is returned is initialized with the
  162. * specified <code>CertStoreParameters</code>. The type of parameters
  163. * needed may vary between different types of <code>CertStore</code>s.
  164. * Note that the specified <code>CertStoreParameters</code> object is
  165. * cloned.
  166. *
  167. * @param type the name of the requested <code>CertStore</code> type
  168. * @param params the initialization parameters (may be <code>null</code>)
  169. * @return a <code>CertStore</code> object that implements the specified
  170. * <code>CertStore</code> type
  171. * @throws NoSuchAlgorithmException if the requested type is not
  172. * available in the default provider package or any of the other provider
  173. * packages that were searched
  174. * @throws InvalidAlgorithmParameterException if the specified
  175. * initialization parameters are inappropriate for this
  176. * <code>CertStore</code>
  177. */
  178. public static CertStore getInstance(String type, CertStoreParameters params)
  179. throws InvalidAlgorithmParameterException,
  180. NoSuchAlgorithmException {
  181. try {
  182. Instance instance = GetInstance.getInstance("CertStore",
  183. CertStoreSpi.class, type, params);
  184. return new CertStore((CertStoreSpi)instance.impl,
  185. instance.provider, type, params);
  186. } catch (NoSuchAlgorithmException e) {
  187. return handleException(e);
  188. }
  189. }
  190. private static CertStore handleException(NoSuchAlgorithmException e)
  191. throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
  192. Throwable cause = e.getCause();
  193. if (cause instanceof InvalidAlgorithmParameterException) {
  194. throw (InvalidAlgorithmParameterException)cause;
  195. }
  196. throw e;
  197. }
  198. /**
  199. * Returns a <code>CertStore</code> object that implements the specified
  200. * <code>CertStore</code> type, as supplied by the specified provider
  201. * and initialized with the specified parameters.
  202. *
  203. * <p>The <code>CertStore</code> that is returned is initialized with the
  204. * specified <code>CertStoreParameters</code>. The type of parameters
  205. * needed may vary between different types of <code>CertStore</code>s.
  206. * Note that the specified <code>CertStoreParameters</code> object is
  207. * cloned.
  208. *
  209. * @param type the requested <code>CertStore</code> type
  210. * @param params the initialization parameters (may be <code>null</code>)
  211. * @param provider the name of the provider
  212. * @return a <code>CertStore</code> object that implements the
  213. * specified type, as supplied by the specified provider
  214. * @throws NoSuchAlgorithmException if the requested type is not
  215. * available from the specified provider
  216. * @throws InvalidAlgorithmParameterException if the specified
  217. * initialization parameters are inappropriate for this
  218. * <code>CertStore</code>
  219. * @throws NoSuchProviderException if the provider has not been configured
  220. * @exception IllegalArgumentException if the <code>provider</code> is
  221. * null
  222. */
  223. public static CertStore getInstance(String type,
  224. CertStoreParameters params, String provider)
  225. throws InvalidAlgorithmParameterException,
  226. NoSuchAlgorithmException, NoSuchProviderException {
  227. try {
  228. Instance instance = GetInstance.getInstance("CertStore",
  229. CertStoreSpi.class, type, params, provider);
  230. return new CertStore((CertStoreSpi)instance.impl,
  231. instance.provider, type, params);
  232. } catch (NoSuchAlgorithmException e) {
  233. return handleException(e);
  234. }
  235. }
  236. /**
  237. * Returns a <code>CertStore</code> object that implements the specified
  238. * <code>CertStore</code> type, as supplied by the specified provider and
  239. * initialized with the specified parameters.
  240. * Note: the <code>provider</code> doesn't have to be registered.
  241. *
  242. * <p>The <code>CertStore</code> that is returned is initialized with the
  243. * specified <code>CertStoreParameters</code>. The type of parameters
  244. * needed may vary between different types of <code>CertStore</code>s.
  245. * Note that the specified <code>CertStoreParameters</code> object is
  246. * cloned.
  247. *
  248. * @param type the requested <code>CertStore</code> type
  249. * @param params the initialization parameters (may be <code>null</code>)
  250. * @param provider the provider
  251. * @return a <code>CertStore</code> object that implements the
  252. * specified type, as supplied by the specified provider
  253. * @exception NoSuchAlgorithmException if the requested type is not
  254. * available from the specified provider
  255. * @throws InvalidAlgorithmParameterException if the specified
  256. * initialization parameters are inappropriate for this
  257. * <code>CertStore</code>
  258. * @exception IllegalArgumentException if the <code>provider</code> is
  259. * null
  260. */
  261. public static CertStore getInstance(String type, CertStoreParameters params,
  262. Provider provider) throws NoSuchAlgorithmException,
  263. InvalidAlgorithmParameterException {
  264. try {
  265. Instance instance = GetInstance.getInstance("CertStore",
  266. CertStoreSpi.class, type, params, provider);
  267. return new CertStore((CertStoreSpi)instance.impl,
  268. instance.provider, type, params);
  269. } catch (NoSuchAlgorithmException e) {
  270. return handleException(e);
  271. }
  272. }
  273. /**
  274. * Returns the parameters used to initialize this <code>CertStore</code>.
  275. * Note that the <code>CertStoreParameters</code> object is cloned before
  276. * it is returned.
  277. *
  278. * @return the parameters used to initialize this <code>CertStore</code>
  279. * (may be <code>null</code>)
  280. */
  281. public final CertStoreParameters getCertStoreParameters() {
  282. return (params == null ? null : (CertStoreParameters) params.clone());
  283. }
  284. /**
  285. * Returns the type of this <code>CertStore</code>.
  286. *
  287. * @return the type of this <code>CertStore</code>
  288. */
  289. public final String getType() {
  290. return this.type;
  291. }
  292. /**
  293. * Returns the provider of this <code>CertStore</code>.
  294. *
  295. * @return the provider of this <code>CertStore</code>
  296. */
  297. public final Provider getProvider() {
  298. return this.provider;
  299. }
  300. /**
  301. * Returns the default <code>CertStore</code> type as specified in the
  302. * Java security properties file, or the string "LDAP" if no
  303. * such property exists. The Java security properties file is located in
  304. * the file named <JAVA_HOME>/lib/security/java.security, where
  305. * <JAVA_HOME> refers to the directory where the JDK was installed.
  306. *
  307. * <p>The default <code>CertStore</code> type can be used by applications
  308. * that do not want to use a hard-coded type when calling one of the
  309. * <code>getInstance</code> methods, and want to provide a default
  310. * <code>CertStore</code> type in case a user does not specify its own.
  311. *
  312. * <p>The default <code>CertStore</code> type can be changed by setting
  313. * the value of the "certstore.type" security property (in the Java
  314. * security properties file) to the desired type.
  315. *
  316. * @return the default <code>CertStore</code> type as specified in the
  317. * Java security properties file, or the string "LDAP"
  318. * if no such property exists.
  319. */
  320. public final static String getDefaultType() {
  321. String cstype;
  322. cstype = (String)AccessController.doPrivileged(new PrivilegedAction() {
  323. public Object run() {
  324. return Security.getProperty(CERTSTORE_TYPE);
  325. }
  326. });
  327. if (cstype == null) {
  328. cstype = "LDAP";
  329. }
  330. return cstype;
  331. }
  332. }