Frames | No Frames |
1: /* KeyStore.java --- Key Store Class 2: Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.security; 40: 41: import gnu.java.security.Engine; 42: 43: import java.io.IOException; 44: import java.io.InputStream; 45: import java.io.OutputStream; 46: import java.lang.reflect.InvocationTargetException; 47: import java.security.cert.CertificateException; 48: import java.util.Date; 49: import java.util.Enumeration; 50: 51: /** 52: * Keystore represents an in-memory collection of keys and 53: * certificates. There are two types of entries: 54: * 55: * <dl> 56: * <dt>Key Entry</dt> 57: * 58: * <dd><p>This type of keystore entry store sensitive crytographic key 59: * information in a protected format.Typically this is a secret 60: * key or a private key with a certificate chain.</p></dd> 61: * 62: * <dt>Trusted Ceritificate Entry</dt> 63: * 64: * <dd><p>This type of keystore entry contains a single public key 65: * certificate belonging to annother entity. It is called trusted 66: * because the keystore owner trusts that the certificates 67: * belongs to the subject (owner) of the certificate.</p></dd> 68: * </dl> 69: * 70: * <p>Entries in a key store are referred to by their "alias": a simple 71: * unique string. 72: * 73: * <p>The structure and persistentence of the key store is not 74: * specified. Any method could be used to protect sensitive 75: * (private or secret) keys. Smart cards or integrated 76: * cryptographic engines could be used or the keystore could 77: * be simply stored in a file.</p> 78: * 79: * @see java.security.cert.Certificate 80: * @see Key 81: */ 82: public class KeyStore 83: { 84: 85: // Constants and fields. 86: // ------------------------------------------------------------------------ 87: 88: /** Service name for key stores. */ 89: private static final String KEY_STORE = "KeyStore"; 90: 91: private KeyStoreSpi keyStoreSpi; 92: private Provider provider; 93: private String type; 94: 95: // Constructors. 96: // ------------------------------------------------------------------------ 97: 98: /** 99: 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 = AccessController.doPrivileged(new PrivilegedAction<String> () { 218: public String run() 219: { 220: return Security.getProperty("keystore.type"); 221: } 222: }); 223: 224: if (tmp == null) 225: tmp = "gkr"; 226: 227: return tmp; 228: } 229: 230: // Instance methods. 231: // ------------------------------------------------------------------------ 232: 233: /** 234: Gets the provider that the class is from. 235: 236: @return the provider of this class 237: */ 238: public final Provider getProvider() 239: { 240: return provider; 241: } 242: 243: /** 244: Returns the type of the KeyStore supported 245: 246: @return A string with the type of KeyStore 247: */ 248: public final String getType() 249: { 250: return type; 251: } 252: 253: /** 254: Returns the key associated with given alias using the 255: supplied password. 256: 257: @param alias an alias for the key to get 258: @param password password to access key with 259: 260: @return the requested key, or null otherwise 261: 262: @throws NoSuchAlgorithmException if there is no algorithm 263: for recovering the key 264: @throws UnrecoverableKeyException key cannot be reocovered 265: (wrong password). 266: */ 267: public final Key getKey(String alias, char[]password) 268: throws KeyStoreException, NoSuchAlgorithmException, 269: UnrecoverableKeyException 270: { 271: return keyStoreSpi.engineGetKey(alias, password); 272: } 273: 274: /** 275: Gets a Certificate chain for the specified alias. 276: 277: @param alias the alias name 278: 279: @return a chain of Certificates ( ordered from the user's 280: certificate to the Certificate Authority's ) or 281: null if the alias does not exist or there is no 282: certificate chain for the alias ( the alias refers 283: to a trusted certificate entry or there is no entry). 284: */ 285: public final java.security.cert. 286: Certificate[] getCertificateChain(String alias) throws KeyStoreException 287: { 288: return keyStoreSpi.engineGetCertificateChain(alias); 289: } 290: 291: /** 292: Gets a Certificate for the specified alias. 293: 294: If there is a trusted certificate entry then that is returned. 295: it there is a key entry with a certificate chain then the 296: first certificate is return or else null. 297: 298: @param alias the alias name 299: 300: @return a Certificate or null if the alias does not exist 301: or there is no certificate for the alias 302: */ 303: public final java.security.cert.Certificate getCertificate(String alias) 304: throws KeyStoreException 305: { 306: return keyStoreSpi.engineGetCertificate(alias); 307: } 308: 309: /** 310: Gets entry creation date for the specified alias. 311: 312: @param alias the alias name 313: 314: @returns the entry creation date or null 315: */ 316: public final Date getCreationDate(String alias) throws KeyStoreException 317: { 318: return keyStoreSpi.engineGetCreationDate(alias); 319: } 320: 321: /** 322: Assign the key to the alias in the keystore, protecting it 323: with the given password. It will overwrite an existing 324: entry and if the key is a PrivateKey, also add the 325: certificate chain representing the corresponding public key. 326: 327: @param alias the alias name 328: @param key the key to add 329: @password the password to protect with 330: @param chain the certificate chain for the corresponding 331: public key 332: 333: @throws KeyStoreException if it fails 334: */ 335: public final void setKeyEntry(String alias, Key key, char[]password, 336: java.security.cert. 337: Certificate[]chain) throws KeyStoreException 338: { 339: keyStoreSpi.engineSetKeyEntry(alias, key, password, chain); 340: } 341: 342: /** 343: Assign the key to the alias in the keystore. It will overwrite 344: an existing entry and if the key is a PrivateKey, also 345: add the certificate chain representing the corresponding 346: public key. 347: 348: @param alias the alias name 349: @param key the key to add 350: @param chain the certificate chain for the corresponding 351: public key 352: 353: @throws KeyStoreException if it fails 354: */ 355: public final void setKeyEntry(String alias, byte[]key, 356: java.security.cert. 357: Certificate[]chain) throws KeyStoreException 358: { 359: keyStoreSpi.engineSetKeyEntry(alias, key, chain); 360: } 361: 362: /** 363: Assign the certificate to the alias in the keystore. It 364: will overwrite an existing entry. 365: 366: @param alias the alias name 367: @param cert the certificate to add 368: 369: @throws KeyStoreException if it fails 370: */ 371: public final void setCertificateEntry(String alias, 372: java.security.cert. 373: Certificate cert) throws 374: KeyStoreException 375: { 376: keyStoreSpi.engineSetCertificateEntry(alias, cert); 377: } 378: 379: /** 380: Deletes the entry for the specified entry. 381: 382: @param alias the alias name 383: 384: @throws KeyStoreException if it fails 385: */ 386: public final void deleteEntry(String alias) throws KeyStoreException 387: { 388: keyStoreSpi.engineDeleteEntry(alias); 389: } 390: 391: /** 392: Generates a list of all the aliases in the keystore. 393: 394: @return an Enumeration of the aliases 395: */ 396: public final Enumeration<String> aliases() throws KeyStoreException 397: { 398: return keyStoreSpi.engineAliases(); 399: } 400: 401: /** 402: Determines if the keystore contains the specified alias. 403: 404: @param alias the alias name 405: 406: @return true if it contains the alias, false otherwise 407: */ 408: public final boolean containsAlias(String alias) throws KeyStoreException 409: { 410: return keyStoreSpi.engineContainsAlias(alias); 411: } 412: 413: /** 414: Returns the number of entries in the keystore. 415: 416: @returns the number of keystore entries. 417: */ 418: public final int size() throws KeyStoreException 419: { 420: return keyStoreSpi.engineSize(); 421: } 422: 423: /** 424: Determines if the keystore contains a key entry for 425: the specified alias. 426: 427: @param alias the alias name 428: 429: @return true if it is a key entry, false otherwise 430: */ 431: public final boolean isKeyEntry(String alias) throws KeyStoreException 432: { 433: return keyStoreSpi.engineIsKeyEntry(alias); 434: } 435: 436: 437: /** 438: Determines if the keystore contains a certificate entry for 439: the specified alias. 440: 441: @param alias the alias name 442: 443: @return true if it is a certificate entry, false otherwise 444: */ 445: public final boolean isCertificateEntry(String alias) 446: throws KeyStoreException 447: { 448: return keyStoreSpi.engineIsCertificateEntry(alias); 449: } 450: 451: /** 452: Determines if the keystore contains the specified certificate 453: entry and returns the alias. 454: 455: It checks every entry and for a key entry checks only the 456: first certificate in the chain. 457: 458: @param cert Certificate to look for 459: 460: @return alias of first matching certificate, null if it 461: does not exist. 462: */ 463: public final String getCertificateAlias(java.security.cert.Certificate cert) 464: throws KeyStoreException 465: { 466: return keyStoreSpi.engineGetCertificateAlias(cert); 467: } 468: 469: /** 470: Stores the keystore in the specified output stream and it 471: uses the specified key it keep it secure. 472: 473: @param stream the output stream to save the keystore to 474: @param password the password to protect the keystore integrity with 475: 476: @throws IOException if an I/O error occurs. 477: @throws NoSuchAlgorithmException the data integrity algorithm 478: used cannot be found. 479: @throws CertificateException if any certificates could not be 480: stored in the output stream. 481: */ 482: public final void store(OutputStream stream, char[]password) 483: throws KeyStoreException, IOException, NoSuchAlgorithmException, 484: CertificateException 485: { 486: keyStoreSpi.engineStore(stream, password); 487: } 488: 489: /** 490: Loads the keystore from the specified input stream and it 491: uses the specified password to check for integrity if supplied. 492: 493: @param stream the input stream to load the keystore from 494: @param password the password to check the keystore integrity with 495: 496: @throws IOException if an I/O error occurs. 497: @throws NoSuchAlgorithmException the data integrity algorithm 498: used cannot be found. 499: @throws CertificateException if any certificates could not be 500: stored in the output stream. 501: */ 502: public final void load(InputStream stream, char[]password) 503: throws IOException, NoSuchAlgorithmException, CertificateException 504: { 505: keyStoreSpi.engineLoad(stream, password); 506: } 507: 508: }