KeyStore.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /* KeyStore.java --- Key Store Class
  2. Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package java.security;
  32. import gnu.java.security.Engine;
  33. import java.io.IOException;
  34. import java.io.InputStream;
  35. import java.io.OutputStream;
  36. import java.lang.reflect.InvocationTargetException;
  37. import java.security.cert.CertificateException;
  38. import java.util.Date;
  39. import java.util.Enumeration;
  40. /**
  41. * Keystore represents an in-memory collection of keys and
  42. * certificates. There are two types of entries:
  43. *
  44. * <dl>
  45. * <dt>Key Entry</dt>
  46. *
  47. * <dd><p>This type of keystore entry store sensitive crytographic key
  48. * information in a protected format.Typically this is a secret
  49. * key or a private key with a certificate chain.</p></dd>
  50. *
  51. * <dt>Trusted Ceritificate Entry</dt>
  52. *
  53. * <dd><p>This type of keystore entry contains a single public key
  54. * certificate belonging to annother entity. It is called trusted
  55. * because the keystore owner trusts that the certificates
  56. * belongs to the subject (owner) of the certificate.</p></dd>
  57. * </dl>
  58. *
  59. * <p>Entries in a key store are referred to by their "alias": a simple
  60. * unique string.
  61. *
  62. * <p>The structure and persistentence of the key store is not
  63. * specified. Any method could be used to protect sensitive
  64. * (private or secret) keys. Smart cards or integrated
  65. * cryptographic engines could be used or the keystore could
  66. * be simply stored in a file.</p>
  67. *
  68. * @see java.security.cert.Certificate
  69. * @see Key
  70. */
  71. public class KeyStore
  72. {
  73. // Constants and fields.
  74. // ------------------------------------------------------------------------
  75. /** Service name for key stores. */
  76. private static final String KEY_STORE = "KeyStore";
  77. private KeyStoreSpi keyStoreSpi;
  78. private Provider provider;
  79. private String type;
  80. // Constructors.
  81. // ------------------------------------------------------------------------
  82. /**
  83. Creates an instance of KeyStore
  84. @param keyStoreSpi A KeyStore engine to use
  85. @param provider A provider to use
  86. @param type The type of KeyStore
  87. */
  88. protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)
  89. {
  90. this.keyStoreSpi = keyStoreSpi;
  91. this.provider = provider;
  92. this.type = type;
  93. }
  94. /**
  95. * Returns an instance of a <code>KeyStore</code> representing the specified
  96. * type, from the first provider that implements it.
  97. *
  98. * @param type the type of keystore to create.
  99. * @return a <code>KeyStore</code> repesenting the desired type.
  100. * @throws KeyStoreException if the designated type of is not implemented by
  101. * any provider, or the implementation could not be instantiated.
  102. * @throws IllegalArgumentException if <code>type</code> is
  103. * <code>null</code> or is an empty string.
  104. */
  105. public static KeyStore getInstance(String type) throws KeyStoreException
  106. {
  107. Provider[] p = Security.getProviders();
  108. KeyStoreException lastException = null;
  109. for (int i = 0; i < p.length; i++)
  110. try
  111. {
  112. return getInstance(type, p[i]);
  113. }
  114. catch (KeyStoreException x)
  115. {
  116. lastException = x;
  117. }
  118. if (lastException != null)
  119. throw lastException;
  120. throw new KeyStoreException(type);
  121. }
  122. /**
  123. * Returns an instance of a <code>KeyStore</code> representing the specified
  124. * type, from the named provider.
  125. *
  126. * @param type the type of keystore to create.
  127. * @param provider the name of the provider to use.
  128. * @return a <code>KeyStore</code> repesenting the desired type.
  129. * @throws KeyStoreException if the designated type is not implemented by the
  130. * given provider.
  131. * @throws NoSuchProviderException if the provider is not found.
  132. * @throws IllegalArgumentException if either <code>type</code> or
  133. * <code>provider</code> is <code>null</code> or empty.
  134. */
  135. public static KeyStore getInstance(String type, String provider)
  136. throws KeyStoreException, NoSuchProviderException
  137. {
  138. if (provider == null)
  139. throw new IllegalArgumentException("provider MUST NOT be null");
  140. provider = provider.trim();
  141. if (provider.length() == 0)
  142. throw new IllegalArgumentException("provider MUST NOT be empty");
  143. Provider p = Security.getProvider(provider);
  144. if (p == null)
  145. throw new NoSuchProviderException(provider);
  146. return getInstance(type, p);
  147. }
  148. /**
  149. * Returns an instance of a <code>KeyStore</code> representing the specified
  150. * type, from the specified provider.
  151. *
  152. * @param type the type of keystore to create.
  153. * @param provider the provider to use.
  154. * @return a <code>KeyStore</code> repesenting the desired type.
  155. * @throws KeyStoreException if the designated type is not implemented by the
  156. * given provider.
  157. * @throws IllegalArgumentException if either <code>type</code> or
  158. * <code>provider</code> is <code>null</code>, or if
  159. * <code>type</code> is an empty string.
  160. * @since 1.4
  161. */
  162. public static KeyStore getInstance(String type, Provider provider)
  163. throws KeyStoreException
  164. {
  165. Throwable cause;
  166. try
  167. {
  168. Object spi = Engine.getInstance(KEY_STORE, type, provider);
  169. return new KeyStore((KeyStoreSpi) spi, provider, type);
  170. }
  171. catch (NoSuchAlgorithmException x)
  172. {
  173. cause = x;
  174. }
  175. catch (InvocationTargetException x)
  176. {
  177. cause = x.getCause() != null ? x.getCause() : x;
  178. }
  179. catch (ClassCastException x)
  180. {
  181. cause = x;
  182. }
  183. KeyStoreException x = new KeyStoreException(type);
  184. x.initCause(cause);
  185. throw x;
  186. }
  187. /**
  188. * Returns the default KeyStore type. This method looks up the
  189. * type in &lt;JAVA_HOME&gt;/lib/security/java.security with the
  190. * property "keystore.type" or if that fails then "gkr" .
  191. */
  192. public static final String getDefaultType()
  193. {
  194. // Security reads every property in java.security so it
  195. // will return this property if it exists.
  196. String tmp = AccessController.doPrivileged(new PrivilegedAction<String> () {
  197. public String run()
  198. {
  199. return Security.getProperty("keystore.type");
  200. }
  201. });
  202. if (tmp == null)
  203. tmp = "gkr";
  204. return tmp;
  205. }
  206. // Instance methods.
  207. // ------------------------------------------------------------------------
  208. /**
  209. Gets the provider that the class is from.
  210. @return the provider of this class
  211. */
  212. public final Provider getProvider()
  213. {
  214. return provider;
  215. }
  216. /**
  217. Returns the type of the KeyStore supported
  218. @return A string with the type of KeyStore
  219. */
  220. public final String getType()
  221. {
  222. return type;
  223. }
  224. /**
  225. Returns the key associated with given alias using the
  226. supplied password.
  227. @param alias an alias for the key to get
  228. @param password password to access key with
  229. @return the requested key, or null otherwise
  230. @throws NoSuchAlgorithmException if there is no algorithm
  231. for recovering the key
  232. @throws UnrecoverableKeyException key cannot be reocovered
  233. (wrong password).
  234. */
  235. public final Key getKey(String alias, char[]password)
  236. throws KeyStoreException, NoSuchAlgorithmException,
  237. UnrecoverableKeyException
  238. {
  239. return keyStoreSpi.engineGetKey(alias, password);
  240. }
  241. /**
  242. Gets a Certificate chain for the specified alias.
  243. @param alias the alias name
  244. @return a chain of Certificates ( ordered from the user's
  245. certificate to the Certificate Authority's ) or
  246. null if the alias does not exist or there is no
  247. certificate chain for the alias ( the alias refers
  248. to a trusted certificate entry or there is no entry).
  249. */
  250. public final java.security.cert.
  251. Certificate[] getCertificateChain(String alias) throws KeyStoreException
  252. {
  253. return keyStoreSpi.engineGetCertificateChain(alias);
  254. }
  255. /**
  256. Gets a Certificate for the specified alias.
  257. If there is a trusted certificate entry then that is returned.
  258. it there is a key entry with a certificate chain then the
  259. first certificate is return or else null.
  260. @param alias the alias name
  261. @return a Certificate or null if the alias does not exist
  262. or there is no certificate for the alias
  263. */
  264. public final java.security.cert.Certificate getCertificate(String alias)
  265. throws KeyStoreException
  266. {
  267. return keyStoreSpi.engineGetCertificate(alias);
  268. }
  269. /**
  270. Gets entry creation date for the specified alias.
  271. @param alias the alias name
  272. @returns the entry creation date or null
  273. */
  274. public final Date getCreationDate(String alias) throws KeyStoreException
  275. {
  276. return keyStoreSpi.engineGetCreationDate(alias);
  277. }
  278. /**
  279. Assign the key to the alias in the keystore, protecting it
  280. with the given password. It will overwrite an existing
  281. entry and if the key is a PrivateKey, also add the
  282. certificate chain representing the corresponding public key.
  283. @param alias the alias name
  284. @param key the key to add
  285. @password the password to protect with
  286. @param chain the certificate chain for the corresponding
  287. public key
  288. @throws KeyStoreException if it fails
  289. */
  290. public final void setKeyEntry(String alias, Key key, char[]password,
  291. java.security.cert.
  292. Certificate[]chain) throws KeyStoreException
  293. {
  294. keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
  295. }
  296. /**
  297. Assign the key to the alias in the keystore. It will overwrite
  298. an existing entry and if the key is a PrivateKey, also
  299. add the certificate chain representing the corresponding
  300. public key.
  301. @param alias the alias name
  302. @param key the key to add
  303. @param chain the certificate chain for the corresponding
  304. public key
  305. @throws KeyStoreException if it fails
  306. */
  307. public final void setKeyEntry(String alias, byte[]key,
  308. java.security.cert.
  309. Certificate[]chain) throws KeyStoreException
  310. {
  311. keyStoreSpi.engineSetKeyEntry(alias, key, chain);
  312. }
  313. /**
  314. Assign the certificate to the alias in the keystore. It
  315. will overwrite an existing entry.
  316. @param alias the alias name
  317. @param cert the certificate to add
  318. @throws KeyStoreException if it fails
  319. */
  320. public final void setCertificateEntry(String alias,
  321. java.security.cert.
  322. Certificate cert) throws
  323. KeyStoreException
  324. {
  325. keyStoreSpi.engineSetCertificateEntry(alias, cert);
  326. }
  327. /**
  328. Deletes the entry for the specified entry.
  329. @param alias the alias name
  330. @throws KeyStoreException if it fails
  331. */
  332. public final void deleteEntry(String alias) throws KeyStoreException
  333. {
  334. keyStoreSpi.engineDeleteEntry(alias);
  335. }
  336. /**
  337. Generates a list of all the aliases in the keystore.
  338. @return an Enumeration of the aliases
  339. */
  340. public final Enumeration<String> aliases() throws KeyStoreException
  341. {
  342. return keyStoreSpi.engineAliases();
  343. }
  344. /**
  345. Determines if the keystore contains the specified alias.
  346. @param alias the alias name
  347. @return true if it contains the alias, false otherwise
  348. */
  349. public final boolean containsAlias(String alias) throws KeyStoreException
  350. {
  351. return keyStoreSpi.engineContainsAlias(alias);
  352. }
  353. /**
  354. Returns the number of entries in the keystore.
  355. @returns the number of keystore entries.
  356. */
  357. public final int size() throws KeyStoreException
  358. {
  359. return keyStoreSpi.engineSize();
  360. }
  361. /**
  362. Determines if the keystore contains a key entry for
  363. the specified alias.
  364. @param alias the alias name
  365. @return true if it is a key entry, false otherwise
  366. */
  367. public final boolean isKeyEntry(String alias) throws KeyStoreException
  368. {
  369. return keyStoreSpi.engineIsKeyEntry(alias);
  370. }
  371. /**
  372. Determines if the keystore contains a certificate entry for
  373. the specified alias.
  374. @param alias the alias name
  375. @return true if it is a certificate entry, false otherwise
  376. */
  377. public final boolean isCertificateEntry(String alias)
  378. throws KeyStoreException
  379. {
  380. return keyStoreSpi.engineIsCertificateEntry(alias);
  381. }
  382. /**
  383. Determines if the keystore contains the specified certificate
  384. entry and returns the alias.
  385. It checks every entry and for a key entry checks only the
  386. first certificate in the chain.
  387. @param cert Certificate to look for
  388. @return alias of first matching certificate, null if it
  389. does not exist.
  390. */
  391. public final String getCertificateAlias(java.security.cert.Certificate cert)
  392. throws KeyStoreException
  393. {
  394. return keyStoreSpi.engineGetCertificateAlias(cert);
  395. }
  396. /**
  397. Stores the keystore in the specified output stream and it
  398. uses the specified key it keep it secure.
  399. @param stream the output stream to save the keystore to
  400. @param password the password to protect the keystore integrity with
  401. @throws IOException if an I/O error occurs.
  402. @throws NoSuchAlgorithmException the data integrity algorithm
  403. used cannot be found.
  404. @throws CertificateException if any certificates could not be
  405. stored in the output stream.
  406. */
  407. public final void store(OutputStream stream, char[]password)
  408. throws KeyStoreException, IOException, NoSuchAlgorithmException,
  409. CertificateException
  410. {
  411. keyStoreSpi.engineStore(stream, password);
  412. }
  413. /**
  414. Loads the keystore from the specified input stream and it
  415. uses the specified password to check for integrity if supplied.
  416. @param stream the input stream to load the keystore from
  417. @param password the password to check the keystore integrity with
  418. @throws IOException if an I/O error occurs.
  419. @throws NoSuchAlgorithmException the data integrity algorithm
  420. used cannot be found.
  421. @throws CertificateException if any certificates could not be
  422. stored in the output stream.
  423. */
  424. public final void load(InputStream stream, char[]password)
  425. throws IOException, NoSuchAlgorithmException, CertificateException
  426. {
  427. keyStoreSpi.engineLoad(stream, password);
  428. }
  429. }