Source for java.security.KeyStore

   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 &lt;JAVA_HOME&gt;/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: }