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 = 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: }