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 */ KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)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 */ getInstance(String type)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 */ getInstance(String type, String provider)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 */ getInstance(String type, Provider provider)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 */ getDefaultType()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 */ getProvider()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 */ getType()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 */ getKey(String alias, char[]password)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. getCertificateChain(String alias)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 */ getCertificate(String alias)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 */ getCreationDate(String alias)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 */ setKeyEntry(String alias, Key key, char[]password, java.security.cert. Certificate[]chain)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 */ setKeyEntry(String alias, byte[]key, java.security.cert. Certificate[]chain)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 */ setCertificateEntry(String alias, java.security.cert. Certificate cert)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 */ deleteEntry(String alias)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 */ aliases()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 */ containsAlias(String alias)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 */ size()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 */ isKeyEntry(String alias)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 */ isCertificateEntry(String alias)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 */ getCertificateAlias(java.security.cert.Certificate cert)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 */ store(OutputStream stream, char[]password)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 */ load(InputStream stream, char[]password)502 public final void load(InputStream stream, char[]password) 503 throws IOException, NoSuchAlgorithmException, CertificateException 504 { 505 keyStoreSpi.engineLoad(stream, password); 506 } 507 508 } 509