001/* KeyStore.java --- Key Store Class 002 Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package java.security; 040 041import gnu.java.security.Engine; 042 043import java.io.IOException; 044import java.io.InputStream; 045import java.io.OutputStream; 046import java.lang.reflect.InvocationTargetException; 047import java.security.cert.CertificateException; 048import java.util.Date; 049import 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 */ 082public 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}