001 /* KeyStore.java --- Key Store Class
002 Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package java.security;
040
041 import gnu.java.security.Engine;
042
043 import java.io.IOException;
044 import java.io.InputStream;
045 import java.io.OutputStream;
046 import java.lang.reflect.InvocationTargetException;
047 import java.security.cert.CertificateException;
048 import java.util.Date;
049 import java.util.Enumeration;
050
051 /**
052 * Keystore represents an in-memory collection of keys and
053 * certificates. There are two types of entries:
054 *
055 * <dl>
056 * <dt>Key Entry</dt>
057 *
058 * <dd><p>This type of keystore entry store sensitive crytographic key
059 * information in a protected format.Typically this is a secret
060 * key or a private key with a certificate chain.</p></dd>
061 *
062 * <dt>Trusted Ceritificate Entry</dt>
063 *
064 * <dd><p>This type of keystore entry contains a single public key
065 * certificate belonging to annother entity. It is called trusted
066 * because the keystore owner trusts that the certificates
067 * belongs to the subject (owner) of the certificate.</p></dd>
068 * </dl>
069 *
070 * <p>Entries in a key store are referred to by their "alias": a simple
071 * unique string.
072 *
073 * <p>The structure and persistentence of the key store is not
074 * specified. Any method could be used to protect sensitive
075 * (private or secret) keys. Smart cards or integrated
076 * cryptographic engines could be used or the keystore could
077 * be simply stored in a file.</p>
078 *
079 * @see java.security.cert.Certificate
080 * @see Key
081 */
082 public class KeyStore
083 {
084
085 // Constants and fields.
086 // ------------------------------------------------------------------------
087
088 /** Service name for key stores. */
089 private static final String KEY_STORE = "KeyStore";
090
091 private KeyStoreSpi keyStoreSpi;
092 private Provider provider;
093 private String type;
094
095 // Constructors.
096 // ------------------------------------------------------------------------
097
098 /**
099 Creates an instance of KeyStore
100
101 @param keyStoreSpi A KeyStore engine to use
102 @param provider A provider to use
103 @param type The type of KeyStore
104 */
105 protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)
106 {
107 this.keyStoreSpi = keyStoreSpi;
108 this.provider = provider;
109 this.type = type;
110 }
111
112 /**
113 * Returns an instance of a <code>KeyStore</code> representing the specified
114 * type, from the first provider that implements it.
115 *
116 * @param type the type of keystore to create.
117 * @return a <code>KeyStore</code> repesenting the desired type.
118 * @throws KeyStoreException if the designated type of is not implemented by
119 * any provider, or the implementation could not be instantiated.
120 * @throws IllegalArgumentException if <code>type</code> is
121 * <code>null</code> or is an empty string.
122 */
123 public static KeyStore getInstance(String type) throws KeyStoreException
124 {
125 Provider[] p = Security.getProviders();
126 KeyStoreException lastException = null;
127 for (int i = 0; i < p.length; i++)
128 try
129 {
130 return getInstance(type, p[i]);
131 }
132 catch (KeyStoreException x)
133 {
134 lastException = x;
135 }
136 if (lastException != null)
137 throw lastException;
138 throw new KeyStoreException(type);
139 }
140
141 /**
142 * Returns an instance of a <code>KeyStore</code> representing the specified
143 * type, from the named provider.
144 *
145 * @param type the type of keystore to create.
146 * @param provider the name of the provider to use.
147 * @return a <code>KeyStore</code> repesenting the desired type.
148 * @throws KeyStoreException if the designated type is not implemented by the
149 * given provider.
150 * @throws NoSuchProviderException if the provider is not found.
151 * @throws IllegalArgumentException if either <code>type</code> or
152 * <code>provider</code> is <code>null</code> or empty.
153 */
154 public static KeyStore getInstance(String type, String provider)
155 throws KeyStoreException, NoSuchProviderException
156 {
157 if (provider == null)
158 throw new IllegalArgumentException("provider MUST NOT be null");
159 provider = provider.trim();
160 if (provider.length() == 0)
161 throw new IllegalArgumentException("provider MUST NOT be empty");
162 Provider p = Security.getProvider(provider);
163 if (p == null)
164 throw new NoSuchProviderException(provider);
165 return getInstance(type, p);
166 }
167
168 /**
169 * Returns an instance of a <code>KeyStore</code> representing the specified
170 * type, from the specified provider.
171 *
172 * @param type the type of keystore to create.
173 * @param provider the provider to use.
174 * @return a <code>KeyStore</code> repesenting the desired type.
175 * @throws KeyStoreException if the designated type is not implemented by the
176 * given provider.
177 * @throws IllegalArgumentException if either <code>type</code> or
178 * <code>provider</code> is <code>null</code>, or if
179 * <code>type</code> is an empty string.
180 * @since 1.4
181 */
182 public static KeyStore getInstance(String type, Provider provider)
183 throws KeyStoreException
184 {
185 Throwable cause;
186 try
187 {
188 Object spi = Engine.getInstance(KEY_STORE, type, provider);
189 return new KeyStore((KeyStoreSpi) spi, provider, type);
190 }
191 catch (NoSuchAlgorithmException x)
192 {
193 cause = x;
194 }
195 catch (InvocationTargetException x)
196 {
197 cause = x.getCause() != null ? x.getCause() : x;
198 }
199 catch (ClassCastException x)
200 {
201 cause = x;
202 }
203 KeyStoreException x = new KeyStoreException(type);
204 x.initCause(cause);
205 throw x;
206 }
207
208 /**
209 * Returns the default KeyStore type. This method looks up the
210 * type in <JAVA_HOME>/lib/security/java.security with the
211 * property "keystore.type" or if that fails then "gkr" .
212 */
213 public static final String getDefaultType()
214 {
215 // Security reads every property in java.security so it
216 // will return this property if it exists.
217 String tmp = Security.getProperty("keystore.type");
218
219 if (tmp == null)
220 tmp = "gkr";
221
222 return tmp;
223 }
224
225 // Instance methods.
226 // ------------------------------------------------------------------------
227
228 /**
229 Gets the provider that the class is from.
230
231 @return the provider of this class
232 */
233 public final Provider getProvider()
234 {
235 return provider;
236 }
237
238 /**
239 Returns the type of the KeyStore supported
240
241 @return A string with the type of KeyStore
242 */
243 public final String getType()
244 {
245 return type;
246 }
247
248 /**
249 Returns the key associated with given alias using the
250 supplied password.
251
252 @param alias an alias for the key to get
253 @param password password to access key with
254
255 @return the requested key, or null otherwise
256
257 @throws NoSuchAlgorithmException if there is no algorithm
258 for recovering the key
259 @throws UnrecoverableKeyException key cannot be reocovered
260 (wrong password).
261 */
262 public final Key getKey(String alias, char[]password)
263 throws KeyStoreException, NoSuchAlgorithmException,
264 UnrecoverableKeyException
265 {
266 return keyStoreSpi.engineGetKey(alias, password);
267 }
268
269 /**
270 Gets a Certificate chain for the specified alias.
271
272 @param alias the alias name
273
274 @return a chain of Certificates ( ordered from the user's
275 certificate to the Certificate Authority's ) or
276 null if the alias does not exist or there is no
277 certificate chain for the alias ( the alias refers
278 to a trusted certificate entry or there is no entry).
279 */
280 public final java.security.cert.
281 Certificate[] getCertificateChain(String alias) throws KeyStoreException
282 {
283 return keyStoreSpi.engineGetCertificateChain(alias);
284 }
285
286 /**
287 Gets a Certificate for the specified alias.
288
289 If there is a trusted certificate entry then that is returned.
290 it there is a key entry with a certificate chain then the
291 first certificate is return or else null.
292
293 @param alias the alias name
294
295 @return a Certificate or null if the alias does not exist
296 or there is no certificate for the alias
297 */
298 public final java.security.cert.Certificate getCertificate(String alias)
299 throws KeyStoreException
300 {
301 return keyStoreSpi.engineGetCertificate(alias);
302 }
303
304 /**
305 Gets entry creation date for the specified alias.
306
307 @param alias the alias name
308
309 @returns the entry creation date or null
310 */
311 public final Date getCreationDate(String alias) throws KeyStoreException
312 {
313 return keyStoreSpi.engineGetCreationDate(alias);
314 }
315
316 /**
317 Assign the key to the alias in the keystore, protecting it
318 with the given password. It will overwrite an existing
319 entry and if the key is a PrivateKey, also add the
320 certificate chain representing the corresponding public key.
321
322 @param alias the alias name
323 @param key the key to add
324 @password the password to protect with
325 @param chain the certificate chain for the corresponding
326 public key
327
328 @throws KeyStoreException if it fails
329 */
330 public final void setKeyEntry(String alias, Key key, char[]password,
331 java.security.cert.
332 Certificate[]chain) throws KeyStoreException
333 {
334 keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
335 }
336
337 /**
338 Assign the key to the alias in the keystore. It will overwrite
339 an existing entry and if the key is a PrivateKey, also
340 add the certificate chain representing the corresponding
341 public key.
342
343 @param alias the alias name
344 @param key the key to add
345 @param chain the certificate chain for the corresponding
346 public key
347
348 @throws KeyStoreException if it fails
349 */
350 public final void setKeyEntry(String alias, byte[]key,
351 java.security.cert.
352 Certificate[]chain) throws KeyStoreException
353 {
354 keyStoreSpi.engineSetKeyEntry(alias, key, chain);
355 }
356
357 /**
358 Assign the certificate to the alias in the keystore. It
359 will overwrite an existing entry.
360
361 @param alias the alias name
362 @param cert the certificate to add
363
364 @throws KeyStoreException if it fails
365 */
366 public final void setCertificateEntry(String alias,
367 java.security.cert.
368 Certificate cert) throws
369 KeyStoreException
370 {
371 keyStoreSpi.engineSetCertificateEntry(alias, cert);
372 }
373
374 /**
375 Deletes the entry for the specified entry.
376
377 @param alias the alias name
378
379 @throws KeyStoreException if it fails
380 */
381 public final void deleteEntry(String alias) throws KeyStoreException
382 {
383 keyStoreSpi.engineDeleteEntry(alias);
384 }
385
386 /**
387 Generates a list of all the aliases in the keystore.
388
389 @return an Enumeration of the aliases
390 */
391 public final Enumeration<String> aliases() throws KeyStoreException
392 {
393 return keyStoreSpi.engineAliases();
394 }
395
396 /**
397 Determines if the keystore contains the specified alias.
398
399 @param alias the alias name
400
401 @return true if it contains the alias, false otherwise
402 */
403 public final boolean containsAlias(String alias) throws KeyStoreException
404 {
405 return keyStoreSpi.engineContainsAlias(alias);
406 }
407
408 /**
409 Returns the number of entries in the keystore.
410
411 @returns the number of keystore entries.
412 */
413 public final int size() throws KeyStoreException
414 {
415 return keyStoreSpi.engineSize();
416 }
417
418 /**
419 Determines if the keystore contains a key entry for
420 the specified alias.
421
422 @param alias the alias name
423
424 @return true if it is a key entry, false otherwise
425 */
426 public final boolean isKeyEntry(String alias) throws KeyStoreException
427 {
428 return keyStoreSpi.engineIsKeyEntry(alias);
429 }
430
431
432 /**
433 Determines if the keystore contains a certificate entry for
434 the specified alias.
435
436 @param alias the alias name
437
438 @return true if it is a certificate entry, false otherwise
439 */
440 public final boolean isCertificateEntry(String alias)
441 throws KeyStoreException
442 {
443 return keyStoreSpi.engineIsCertificateEntry(alias);
444 }
445
446 /**
447 Determines if the keystore contains the specified certificate
448 entry and returns the alias.
449
450 It checks every entry and for a key entry checks only the
451 first certificate in the chain.
452
453 @param cert Certificate to look for
454
455 @return alias of first matching certificate, null if it
456 does not exist.
457 */
458 public final String getCertificateAlias(java.security.cert.Certificate cert)
459 throws KeyStoreException
460 {
461 return keyStoreSpi.engineGetCertificateAlias(cert);
462 }
463
464 /**
465 Stores the keystore in the specified output stream and it
466 uses the specified key it keep it secure.
467
468 @param stream the output stream to save the keystore to
469 @param password the password to protect the keystore integrity with
470
471 @throws IOException if an I/O error occurs.
472 @throws NoSuchAlgorithmException the data integrity algorithm
473 used cannot be found.
474 @throws CertificateException if any certificates could not be
475 stored in the output stream.
476 */
477 public final void store(OutputStream stream, char[]password)
478 throws KeyStoreException, IOException, NoSuchAlgorithmException,
479 CertificateException
480 {
481 keyStoreSpi.engineStore(stream, password);
482 }
483
484 /**
485 Loads the keystore from the specified input stream and it
486 uses the specified password to check for integrity if supplied.
487
488 @param stream the input stream to load the keystore from
489 @param password the password to check the keystore integrity with
490
491 @throws IOException if an I/O error occurs.
492 @throws NoSuchAlgorithmException the data integrity algorithm
493 used cannot be found.
494 @throws CertificateException if any certificates could not be
495 stored in the output stream.
496 */
497 public final void load(InputStream stream, char[]password)
498 throws IOException, NoSuchAlgorithmException, CertificateException
499 {
500 keyStoreSpi.engineLoad(stream, password);
501 }
502
503 }