KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > security > KeyStoreSpi


1 /*
2  * @(#)KeyStoreSpi.java 1.18 04/05/25
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.security;
9
10 import java.io.*;
11 import java.util.*;
12
13 import java.security.KeyStore JavaDoc.*;
14 import java.security.cert.Certificate JavaDoc;
15 import java.security.cert.CertificateException JavaDoc;
16
17 import javax.crypto.SecretKey;
18
19 import javax.security.auth.callback.*;
20
21 /**
22  * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
23  * for the <code>KeyStore</code> class.
24  * All the abstract methods in this class must be implemented by each
25  * cryptographic service provider who wishes to supply the implementation
26  * of a keystore for a particular keystore type.
27  *
28  * @author Jan Luehe
29  *
30  * @version 1.18, 05/25/04
31  *
32  * @see KeyStore
33  *
34  * @since 1.2
35  */

36
37 public abstract class KeyStoreSpi {
38
39     /**
40      * Returns the key associated with the given alias, using the given
41      * password to recover it. The key must have been associated with
42      * the alias by a call to <code>setKeyEntry</code>,
43      * or by a call to <code>setEntry</code> with a
44      * <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>.
45      *
46      * @param alias the alias name
47      * @param password the password for recovering the key
48      *
49      * @return the requested key, or null if the given alias does not exist
50      * or does not identify a key-related entry.
51      *
52      * @exception NoSuchAlgorithmException if the algorithm for recovering the
53      * key cannot be found
54      * @exception UnrecoverableKeyException if the key cannot be recovered
55      * (e.g., the given password is wrong).
56      */

57     public abstract Key JavaDoc engineGetKey(String JavaDoc alias, char[] password)
58     throws NoSuchAlgorithmException JavaDoc, UnrecoverableKeyException JavaDoc;
59
60     /**
61      * Returns the certificate chain associated with the given alias.
62      * The certificate chain must have been associated with the alias
63      * by a call to <code>setKeyEntry</code>,
64      * or by a call to <code>setEntry</code> with a
65      * <code>PrivateKeyEntry</code>.
66      *
67      * @param alias the alias name
68      *
69      * @return the certificate chain (ordered with the user's certificate first
70      * and the root certificate authority last), or null if the given alias
71      * does not exist or does not contain a certificate chain
72      */

73     public abstract Certificate JavaDoc[] engineGetCertificateChain(String JavaDoc alias);
74
75     /**
76      * Returns the certificate associated with the given alias.
77      *
78      * <p> If the given alias name identifies an entry
79      * created by a call to <code>setCertificateEntry</code>,
80      * or created by a call to <code>setEntry</code> with a
81      * <code>TrustedCertificateEntry</code>,
82      * then the trusted certificate contained in that entry is returned.
83      *
84      * <p> If the given alias name identifies an entry
85      * created by a call to <code>setKeyEntry</code>,
86      * or created by a call to <code>setEntry</code> with a
87      * <code>PrivateKeyEntry</code>,
88      * then the first element of the certificate chain in that entry
89      * (if a chain exists) is returned.
90      *
91      * @param alias the alias name
92      *
93      * @return the certificate, or null if the given alias does not exist or
94      * does not contain a certificate.
95      */

96     public abstract Certificate JavaDoc engineGetCertificate(String JavaDoc alias);
97
98     /**
99      * Returns the creation date of the entry identified by the given alias.
100      *
101      * @param alias the alias name
102      *
103      * @return the creation date of this entry, or null if the given alias does
104      * not exist
105      */

106     public abstract Date engineGetCreationDate(String JavaDoc alias);
107
108     /**
109      * Assigns the given key to the given alias, protecting it with the given
110      * password.
111      *
112      * <p>If the given key is of type <code>java.security.PrivateKey</code>,
113      * it must be accompanied by a certificate chain certifying the
114      * corresponding public key.
115      *
116      * <p>If the given alias already exists, the keystore information
117      * associated with it is overridden by the given key (and possibly
118      * certificate chain).
119      *
120      * @param alias the alias name
121      * @param key the key to be associated with the alias
122      * @param password the password to protect the key
123      * @param chain the certificate chain for the corresponding public
124      * key (only required if the given key is of type
125      * <code>java.security.PrivateKey</code>).
126      *
127      * @exception KeyStoreException if the given key cannot be protected, or
128      * this operation fails for some other reason
129      */

130     public abstract void engineSetKeyEntry(String JavaDoc alias, Key JavaDoc key,
131                        char[] password,
132                        Certificate JavaDoc[] chain)
133     throws KeyStoreException JavaDoc;
134
135     /**
136      * Assigns the given key (that has already been protected) to the given
137      * alias.
138      *
139      * <p>If the protected key is of type
140      * <code>java.security.PrivateKey</code>,
141      * it must be accompanied by a certificate chain certifying the
142      * corresponding public key.
143      *
144      * <p>If the given alias already exists, the keystore information
145      * associated with it is overridden by the given key (and possibly
146      * certificate chain).
147      *
148      * @param alias the alias name
149      * @param key the key (in protected format) to be associated with the alias
150      * @param chain the certificate chain for the corresponding public
151      * key (only useful if the protected key is of type
152      * <code>java.security.PrivateKey</code>).
153      *
154      * @exception KeyStoreException if this operation fails.
155      */

156     public abstract void engineSetKeyEntry(String JavaDoc alias, byte[] key,
157                        Certificate JavaDoc[] chain)
158     throws KeyStoreException JavaDoc;
159
160     /**
161      * Assigns the given certificate to the given alias.
162      *
163      * <p> If the given alias identifies an existing entry
164      * created by a call to <code>setCertificateEntry</code>,
165      * or created by a call to <code>setEntry</code> with a
166      * <code>TrustedCertificateEntry</code>,
167      * the trusted certificate in the existing entry
168      * is overridden by the given certificate.
169      *
170      * @param alias the alias name
171      * @param cert the certificate
172      *
173      * @exception KeyStoreException if the given alias already exists and does
174      * not identify an entry containing a trusted certificate,
175      * or this operation fails for some other reason.
176      */

177     public abstract void engineSetCertificateEntry(String JavaDoc alias,
178                            Certificate JavaDoc cert)
179     throws KeyStoreException JavaDoc;
180
181     /**
182      * Deletes the entry identified by the given alias from this keystore.
183      *
184      * @param alias the alias name
185      *
186      * @exception KeyStoreException if the entry cannot be removed.
187      */

188     public abstract void engineDeleteEntry(String JavaDoc alias)
189     throws KeyStoreException JavaDoc;
190
191     /**
192      * Lists all the alias names of this keystore.
193      *
194      * @return enumeration of the alias names
195      */

196     public abstract Enumeration<String JavaDoc> engineAliases();
197
198     /**
199      * Checks if the given alias exists in this keystore.
200      *
201      * @param alias the alias name
202      *
203      * @return true if the alias exists, false otherwise
204      */

205     public abstract boolean engineContainsAlias(String JavaDoc alias);
206
207     /**
208      * Retrieves the number of entries in this keystore.
209      *
210      * @return the number of entries in this keystore
211      */

212     public abstract int engineSize();
213
214     /**
215      * Returns true if the entry identified by the given alias
216      * was created by a call to <code>setKeyEntry</code>,
217      * or created by a call to <code>setEntry</code> with a
218      * <code>PrivateKeyEntry</code> or a <code>SecretKeyEntry</code>.
219      *
220      * @param alias the alias for the keystore entry to be checked
221      *
222      * @return true if the entry identified by the given alias is a
223      * key-related, false otherwise.
224      */

225     public abstract boolean engineIsKeyEntry(String JavaDoc alias);
226
227     /**
228      * Returns true if the entry identified by the given alias
229      * was created by a call to <code>setCertificateEntry</code>,
230      * or created by a call to <code>setEntry</code> with a
231      * <code>TrustedCertificateEntry</code>.
232      *
233      * @param alias the alias for the keystore entry to be checked
234      *
235      * @return true if the entry identified by the given alias contains a
236      * trusted certificate, false otherwise.
237      */

238     public abstract boolean engineIsCertificateEntry(String JavaDoc alias);
239
240     /**
241      * Returns the (alias) name of the first keystore entry whose certificate
242      * matches the given certificate.
243      *
244      * <p>This method attempts to match the given certificate with each
245      * keystore entry. If the entry being considered was
246      * created by a call to <code>setCertificateEntry</code>,
247      * or created by a call to <code>setEntry</code> with a
248      * <code>TrustedCertificateEntry</code>,
249      * then the given certificate is compared to that entry's certificate.
250      *
251      * <p> If the entry being considered was
252      * created by a call to <code>setKeyEntry</code>,
253      * or created by a call to <code>setEntry</code> with a
254      * <code>PrivateKeyEntry</code>,
255      * then the given certificate is compared to the first
256      * element of that entry's certificate chain.
257      *
258      * @param cert the certificate to match with.
259      *
260      * @return the alias name of the first entry with matching certificate,
261      * or null if no such entry exists in this keystore.
262      */

263     public abstract String JavaDoc engineGetCertificateAlias(Certificate JavaDoc cert);
264
265     /**
266      * Stores this keystore to the given output stream, and protects its
267      * integrity with the given password.
268      *
269      * @param stream the output stream to which this keystore is written.
270      * @param password the password to generate the keystore integrity check
271      *
272      * @exception IOException if there was an I/O problem with data
273      * @exception NoSuchAlgorithmException if the appropriate data integrity
274      * algorithm could not be found
275      * @exception CertificateException if any of the certificates included in
276      * the keystore data could not be stored
277      */

278     public abstract void engineStore(OutputStream stream, char[] password)
279     throws IOException, NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc;
280
281     /**
282      * Stores this keystore using the given
283      * <code>KeyStore.LoadStoreParmeter</code>.
284      *
285      * @param param the <code>KeyStore.LoadStoreParmeter</code>
286      * that specifies how to store the keystore,
287      * which may be <code>null</code>
288      *
289      * @exception IllegalArgumentException if the given
290      * <code>KeyStore.LoadStoreParmeter</code>
291      * input is not recognized
292      * @exception IOException if there was an I/O problem with data
293      * @exception NoSuchAlgorithmException if the appropriate data integrity
294      * algorithm could not be found
295      * @exception CertificateException if any of the certificates included in
296      * the keystore data could not be stored
297      *
298      * @since 1.5
299      */

300     public void engineStore(KeyStore.LoadStoreParameter JavaDoc param)
301         throws IOException, NoSuchAlgorithmException JavaDoc,
302         CertificateException JavaDoc {
303     throw new UnsupportedOperationException JavaDoc();
304     }
305
306     /**
307      * Loads the keystore from the given input stream.
308      *
309      * <p>A password may be given to unlock the keystore
310      * (e.g. the keystore resides on a hardware token device),
311      * or to check the integrity of the keystore data.
312      * If a password is not given for integrity checking,
313      * then integrity checking is not performed.
314      *
315      * @param stream the input stream from which the keystore is loaded,
316      * or <code>null</code>
317      * @param password the password used to check the integrity of
318      * the keystore, the password used to unlock the keystore,
319      * or <code>null</code>
320      *
321      * @exception IOException if there is an I/O or format problem with the
322      * keystore data, if a password is required but not given,
323      * or if the given password was incorrect
324      * @exception NoSuchAlgorithmException if the algorithm used to check
325      * the integrity of the keystore cannot be found
326      * @exception CertificateException if any of the certificates in the
327      * keystore could not be loaded
328      */

329     public abstract void engineLoad(InputStream stream, char[] password)
330     throws IOException, NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc;
331
332     /**
333      * Loads the keystore using the given
334      * <code>KeyStore.LoadStoreParameter</code>.
335      *
336      * <p> Note that if this KeyStore has already been loaded, it is
337      * reinitialized and loaded again from the given parameter.
338      *
339      * @param param the <code>KeyStore.LoadStoreParameter</code>
340      * that specifies how to load the keystore,
341      * which may be <code>null</code>
342      *
343      * @exception IllegalArgumentException if the given
344      * <code>KeyStore.LoadStoreParameter</code>
345      * input is not recognized
346      * @exception IOException if there is an I/O or format problem with the
347      * keystore data
348      * @exception NoSuchAlgorithmException if the algorithm used to check
349      * the integrity of the keystore cannot be found
350      * @exception CertificateException if any of the certificates in the
351      * keystore could not be loaded
352      *
353      * @since 1.5
354      */

355     public void engineLoad(KeyStore.LoadStoreParameter JavaDoc param)
356         throws IOException, NoSuchAlgorithmException JavaDoc,
357         CertificateException JavaDoc {
358
359     if (param == null) {
360         engineLoad((InputStream)null, (char[])null);
361         return;
362     }
363     
364     if (param instanceof KeyStore.SimpleLoadStoreParameter JavaDoc) {
365         ProtectionParameter protection = param.getProtectionParameter();
366         char[] password;
367         if (protection instanceof PasswordProtection) {
368         password = ((PasswordProtection)param).getPassword();
369         } else if (protection instanceof CallbackHandlerProtection) {
370         CallbackHandler handler =
371             ((CallbackHandlerProtection)param).getCallbackHandler();
372         PasswordCallback callback =
373             new PasswordCallback("Password: ", false);
374         try {
375             handler.handle(new Callback[] {callback});
376         } catch (UnsupportedCallbackException e) {
377             throw new NoSuchAlgorithmException JavaDoc
378             ("Could not obtain password", e);
379         }
380         password = callback.getPassword();
381         callback.clearPassword();
382         if (password == null) {
383             throw new NoSuchAlgorithmException JavaDoc
384             ("No password provided");
385         }
386         } else {
387         throw new NoSuchAlgorithmException JavaDoc("ProtectionParameter must"
388             + " be PasswordProtection or CallbackHandlerProtection");
389         }
390         engineLoad(null, password);
391         return;
392     }
393
394     throw new UnsupportedOperationException JavaDoc();
395     }
396
397     /**
398      * Gets a <code>KeyStore.Entry</code> for the specified alias
399      * with the specified protection parameter.
400      *
401      * @param alias get the <code>KeyStore.Entry</code> for this alias
402      * @param protParam the <code>ProtectionParameter</code>
403      * used to protect the <code>Entry</code>,
404      * which may be <code>null</code>
405      *
406      * @return the <code>KeyStore.Entry</code> for the specified alias,
407      * or <code>null</code> if there is no such entry
408      *
409      * @exception KeyStoreException if the operation failed
410      * @exception NoSuchAlgorithmException if the algorithm for recovering the
411      * entry cannot be found
412      * @exception UnrecoverableEntryException if the specified
413      * <code>protParam</code> were insufficient or invalid
414      *
415      * @since 1.5
416      */

417     public KeyStore.Entry JavaDoc engineGetEntry(String JavaDoc alias,
418             KeyStore.ProtectionParameter JavaDoc protParam)
419         throws KeyStoreException JavaDoc, NoSuchAlgorithmException JavaDoc,
420         UnrecoverableEntryException JavaDoc {
421
422     if (!engineContainsAlias(alias)) {
423         return null;
424     }
425
426     if (protParam == null) {
427         if (engineIsCertificateEntry(alias)) {
428         return new KeyStore.TrustedCertificateEntry JavaDoc
429                 (engineGetCertificate(alias));
430         } else {
431         throw new UnrecoverableEntryException JavaDoc
432             ("requested entry requires a password");
433         }
434     }
435
436     if (protParam instanceof KeyStore.PasswordProtection JavaDoc) {
437         if (engineIsCertificateEntry(alias)) {
438         throw new UnsupportedOperationException JavaDoc
439             ("trusted certificate entries are not password-protected");
440         } else if (engineIsKeyEntry(alias)) {
441         KeyStore.PasswordProtection JavaDoc pp =
442             (KeyStore.PasswordProtection JavaDoc)protParam;
443         char[] password = pp.getPassword();
444         
445         try {
446             Key JavaDoc key = engineGetKey(alias, password);
447             if (key instanceof PrivateKey JavaDoc) {
448             Certificate JavaDoc[] chain = engineGetCertificateChain(alias);
449             return new KeyStore.PrivateKeyEntry JavaDoc
450                         ((PrivateKey JavaDoc)key, chain);
451             } else if (key instanceof SecretKey) {
452             return new KeyStore.SecretKeyEntry JavaDoc((SecretKey)key);
453             }
454         } catch (UnrecoverableKeyException JavaDoc uke) {
455             UnrecoverableEntryException JavaDoc uee =
456             new UnrecoverableEntryException JavaDoc();
457             uee.initCause(uke);
458             throw uee;
459         }
460         }
461     }
462
463     throw new UnsupportedOperationException JavaDoc();
464     }
465
466     /**
467      * Saves a <code>KeyStore.Entry</code> under the specified alias.
468      * The specified protection parameter is used to protect the
469      * <code>Entry</code>.
470      *
471      * <p> If an entry already exists for the specified alias,
472      * it is overridden.
473      *
474      * @param alias save the <code>KeyStore.Entry</code> under this alias
475      * @param entry the <code>Entry</code> to save
476      * @param protParam the <code>ProtectionParameter</code>
477      * used to protect the <code>Entry</code>,
478      * which may be <code>null</code>
479      *
480      * @exception KeyStoreException if this operation fails
481      *
482      * @since 1.5
483      */

484     public void engineSetEntry(String JavaDoc alias, KeyStore.Entry JavaDoc entry,
485             KeyStore.ProtectionParameter JavaDoc protParam)
486         throws KeyStoreException JavaDoc {
487
488     // get password
489
if (protParam != null &&
490         !(protParam instanceof KeyStore.PasswordProtection JavaDoc)) {
491         throw new KeyStoreException JavaDoc("unsupported protection parameter");
492     }
493     KeyStore.PasswordProtection JavaDoc pProtect = null;
494     if (protParam != null) {
495         pProtect = (KeyStore.PasswordProtection JavaDoc)protParam;
496     }
497
498     // set entry
499
if (entry instanceof KeyStore.TrustedCertificateEntry JavaDoc) {
500         if (protParam != null && pProtect.getPassword() != null) {
501         // pre-1.5 style setCertificateEntry did not allow password
502
throw new KeyStoreException JavaDoc
503             ("trusted certificate entries are not password-protected");
504         } else {
505         KeyStore.TrustedCertificateEntry JavaDoc tce =
506             (KeyStore.TrustedCertificateEntry JavaDoc)entry;
507         engineSetCertificateEntry(alias, tce.getTrustedCertificate());
508         return;
509         }
510     } else if (entry instanceof KeyStore.PrivateKeyEntry JavaDoc) {
511         if (pProtect == null || pProtect.getPassword() == null) {
512         // pre-1.5 style setKeyEntry required password
513
throw new KeyStoreException JavaDoc
514             ("non-null password required to create PrivateKeyEntry");
515         } else {
516         engineSetKeyEntry
517             (alias,
518             ((KeyStore.PrivateKeyEntry JavaDoc)entry).getPrivateKey(),
519             pProtect.getPassword(),
520             ((KeyStore.PrivateKeyEntry JavaDoc)entry).getCertificateChain());
521         return;
522         }
523     } else if (entry instanceof KeyStore.SecretKeyEntry JavaDoc) {
524         if (pProtect == null || pProtect.getPassword() == null) {
525         // pre-1.5 style setKeyEntry required password
526
throw new KeyStoreException JavaDoc
527             ("non-null password required to create SecretKeyEntry");
528         } else {
529         engineSetKeyEntry
530             (alias,
531             ((KeyStore.SecretKeyEntry JavaDoc)entry).getSecretKey(),
532             pProtect.getPassword(),
533             (Certificate JavaDoc[])null);
534         return;
535         }
536     }
537
538     throw new KeyStoreException JavaDoc
539         ("unsupported entry type: " + entry.getClass().getName());
540     }
541
542     /**
543      * Determines if the keystore <code>Entry</code> for the specified
544      * <code>alias</code> is an instance or subclass of the specified
545      * <code>entryClass</code>.
546      *
547      * @param alias the alias name
548      * @param entryClass the entry class
549      *
550      * @return true if the keystore <code>Entry</code> for the specified
551      * <code>alias</code> is an instance or subclass of the
552      * specified <code>entryClass</code>, false otherwise
553      *
554      * @since 1.5
555      */

556     public boolean
557     engineEntryInstanceOf(String JavaDoc alias,
558                   Class JavaDoc<? extends KeyStore.Entry JavaDoc> entryClass)
559     {
560     if (entryClass == KeyStore.TrustedCertificateEntry JavaDoc.class) {
561         return engineIsCertificateEntry(alias);
562     }
563     if (entryClass == KeyStore.PrivateKeyEntry JavaDoc.class) {
564         return engineIsKeyEntry(alias) &&
565             engineGetCertificate(alias) != null;
566     }
567     if (entryClass == KeyStore.SecretKeyEntry JavaDoc.class) {
568         return engineIsKeyEntry(alias) &&
569             engineGetCertificate(alias) == null;
570     }
571     return false;
572     }
573 }
574
Popular Tags