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.security.cert.CertificateException;
  47: import java.util.Date;
  48: import java.util.Enumeration;
  49: 
  50: /**
  51:  * Keystore represents an in-memory collection of keys and 
  52:  * certificates. There are two types of entries:
  53:  *
  54:  * <dl>
  55:  * <dt>Key Entry</dt>
  56:  *
  57:  * <dd><p>This type of keystore entry store sensitive crytographic key
  58:  * information in a protected format.Typically this is a secret 
  59:  * key or a private key with a certificate chain.</p></dd>
  60:  *
  61:  * <dt>Trusted Ceritificate Entry</dt>
  62:  *
  63:  * <dd><p>This type of keystore entry contains a single public key 
  64:  * certificate belonging to annother entity. It is called trusted
  65:  * because the keystore owner trusts that the certificates
  66:  * belongs to the subject (owner) of the certificate.</p></dd>
  67:  * </dl>
  68:  *
  69:  * <p>Entries in a key store are referred to by their "alias": a simple
  70:  * unique string.
  71:  *
  72:  * <p>The structure and persistentence of the key store is not 
  73:  * specified. Any method could be used to protect sensitive 
  74:  * (private or secret) keys. Smart cards or integrated 
  75:  * cryptographic engines could be used or the keystore could 
  76:  * be simply stored in a file.</p>
  77:  *
  78:  * @see java.security.cert.Certificate
  79:  * @see Key
  80:  */
  81: public class KeyStore
  82: {
  83: 
  84:   // Constants and fields.
  85:   // ------------------------------------------------------------------------
  86: 
  87:   /** Service name for key stores. */
  88:   private static final String KEY_STORE = "KeyStore";
  89: 
  90:   private KeyStoreSpi keyStoreSpi;
  91:   private Provider provider;
  92:   private String type;
  93: 
  94:   // Constructors.
  95:   // ------------------------------------------------------------------------
  96: 
  97:   /**
  98:      Creates an instance of KeyStore
  99: 
 100:      @param keyStoreSpi A KeyStore engine to use
 101:      @param provider A provider to use
 102:      @param type The type of KeyStore
 103:    */
 104:   protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type)
 105:   {
 106:     this.keyStoreSpi = keyStoreSpi;
 107:     this.provider = provider;
 108:     this.type = type;
 109:   }
 110: 
 111:   // Class methods.
 112:   // ------------------------------------------------------------------------
 113: 
 114:   /** 
 115:    * Gets an instance of the KeyStore class representing
 116:    * the specified keystore. If the type is not 
 117:    * found then, it throws KeyStoreException.
 118:    *
 119:    * @param type the type of keystore to choose
 120:    * @return a KeyStore repesenting the desired type
 121:    * @throws KeyStoreException if the type of keystore is not implemented
 122:    *         by providers or the implementation cannot be instantiated.
 123:    */
 124:   public static KeyStore getInstance(String type) throws KeyStoreException
 125:   {
 126:     Provider[] p = Security.getProviders();
 127: 
 128:     for (int i = 0; i < p.length; i++)
 129:       {
 130:         try
 131:           {
 132:             return getInstance(type, p[i]);
 133:           }
 134:         catch (KeyStoreException e)
 135:           {
 136:         // Ignore.
 137:           }
 138:       }
 139: 
 140:     throw new KeyStoreException(type);
 141:   }
 142: 
 143:   /** 
 144:    * Gets an instance of the KeyStore class representing
 145:    * the specified key store from the specified provider. 
 146:    * If the type is not found then, it throws KeyStoreException. 
 147:    * If the provider is not found, then it throws 
 148:    * NoSuchProviderException.
 149:    *
 150:    * @param type the type of keystore to choose
 151:    * @param provider the provider name
 152:    * @return a KeyStore repesenting the desired type
 153:    * @throws KeyStoreException if the type of keystore is not 
 154:    *          implemented by the given provider
 155:    * @throws NoSuchProviderException if the provider is not found
 156:    * @throws IllegalArgumentException if the provider string is 
 157:    *           null or empty
 158:    */
 159:   public static KeyStore getInstance(String type, String provider)
 160:     throws KeyStoreException, NoSuchProviderException
 161:   {
 162:     if (provider == null || provider.length() == 0)
 163:       throw new IllegalArgumentException("Illegal provider");
 164: 
 165:     Provider p = Security.getProvider(provider);
 166:     if (p == null)
 167:       throw new NoSuchProviderException(provider);
 168: 
 169:     return getInstance(type, p);
 170:   }
 171: 
 172:   /** 
 173:    * Gets an instance of the KeyStore class representing
 174:    * the specified key store from the specified provider. 
 175:    * If the type is not found then, it throws KeyStoreException. 
 176:    * If the provider is not found, then it throws 
 177:    * NoSuchProviderException.
 178:    *
 179:    * @param type the type of keystore to choose
 180:    * @param provider the keystore provider
 181:    * @return a KeyStore repesenting the desired type
 182:    * @throws KeyStoreException if the type of keystore is not 
 183:    *          implemented by the given provider
 184:    * @throws IllegalArgumentException if the provider object is null
 185:    * @since 1.4
 186:    */
 187:   public static KeyStore getInstance(String type, Provider provider)
 188:     throws KeyStoreException 
 189:   {
 190:     if (provider == null)
 191:       throw new IllegalArgumentException("Illegal provider");
 192:     try
 193:       {
 194:         return new KeyStore(
 195:           (KeyStoreSpi) Engine.getInstance(KEY_STORE, type, provider),
 196:           provider, type);
 197:       }
 198:     catch (NoSuchAlgorithmException nsae)
 199:       {
 200:         throw new KeyStoreException(type);
 201:       }
 202:     catch (java.lang.reflect.InvocationTargetException ite)
 203:       {
 204:     throw new KeyStoreException(type);
 205:       }
 206:     catch (ClassCastException cce)
 207:       {
 208:         throw new KeyStoreException(type);
 209:       }
 210:   }
 211: 
 212:   /**
 213:    * Returns the default KeyStore type. This method looks up the
 214:    * type in &lt;JAVA_HOME&gt;/lib/security/java.security with the 
 215:    * property "keystore.type" or if that fails then "gkr" .
 216:    */
 217:   public static final String getDefaultType()
 218:   {
 219:     // Security reads every property in java.security so it 
 220:     // will return this property if it exists. 
 221:     String tmp = Security.getProperty("keystore.type");
 222: 
 223:     if (tmp == null)
 224:       tmp = "gkr";
 225: 
 226:     return tmp;
 227:   }
 228: 
 229:   // Instance methods.
 230:   // ------------------------------------------------------------------------
 231: 
 232:   /**
 233:      Gets the provider that the class is from.
 234: 
 235:      @return the provider of this class
 236:    */
 237:   public final Provider getProvider()
 238:   {
 239:     return provider;
 240:   }
 241: 
 242:   /**
 243:      Returns the type of the KeyStore supported
 244: 
 245:      @return A string with the type of KeyStore
 246:    */
 247:   public final String getType()
 248:   {
 249:     return type;
 250:   }
 251: 
 252:   /**
 253:      Returns the key associated with given alias using the 
 254:      supplied password.
 255: 
 256:      @param alias an alias for the key to get
 257:      @param password password to access key with
 258: 
 259:      @return the requested key, or null otherwise
 260: 
 261:      @throws NoSuchAlgorithmException if there is no algorithm
 262:      for recovering the key
 263:      @throws UnrecoverableKeyException key cannot be reocovered
 264:      (wrong password).
 265:    */
 266:   public final Key getKey(String alias, char[]password)
 267:     throws KeyStoreException, NoSuchAlgorithmException,
 268:     UnrecoverableKeyException
 269:   {
 270:     return keyStoreSpi.engineGetKey(alias, password);
 271:   }
 272: 
 273:   /**
 274:      Gets a Certificate chain for the specified alias.
 275: 
 276:      @param alias the alias name
 277: 
 278:      @return a chain of Certificates ( ordered from the user's 
 279:      certificate to the Certificate Authority's ) or 
 280:      null if the alias does not exist or there is no
 281:      certificate chain for the alias ( the alias refers
 282:      to a trusted certificate entry or there is no entry).
 283:    */
 284:   public final java.security.cert.
 285:     Certificate[] getCertificateChain(String alias) throws KeyStoreException
 286:   {
 287:     return keyStoreSpi.engineGetCertificateChain(alias);
 288:   }
 289: 
 290:   /**
 291:      Gets a Certificate for the specified alias.
 292: 
 293:      If there is a trusted certificate entry then that is returned.
 294:      it there is a key entry with a certificate chain then the
 295:      first certificate is return or else null.
 296: 
 297:      @param alias the alias name
 298: 
 299:      @return a Certificate or null if the alias does not exist 
 300:      or there is no certificate for the alias
 301:    */
 302:   public final java.security.cert.Certificate getCertificate(String alias)
 303:     throws KeyStoreException
 304:   {
 305:     return keyStoreSpi.engineGetCertificate(alias);
 306:   }
 307: 
 308:   /**
 309:      Gets entry creation date for the specified alias.
 310: 
 311:      @param alias the alias name
 312: 
 313:      @returns the entry creation date or null
 314:    */
 315:   public final Date getCreationDate(String alias) throws KeyStoreException
 316:   {
 317:     return keyStoreSpi.engineGetCreationDate(alias);
 318:   }
 319: 
 320:   /**
 321:      Assign the key to the alias in the keystore, protecting it
 322:      with the given password. It will overwrite an existing 
 323:      entry and if the key is a PrivateKey, also add the 
 324:      certificate chain representing the corresponding public key.
 325: 
 326:      @param alias the alias name
 327:      @param key the key to add
 328:      @password the password to protect with
 329:      @param chain the certificate chain for the corresponding
 330:      public key
 331: 
 332:      @throws KeyStoreException if it fails
 333:    */
 334:   public final void setKeyEntry(String alias, Key key, char[]password,
 335:                 java.security.cert.
 336:                 Certificate[]chain) throws KeyStoreException
 337:   {
 338:     keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
 339:   }
 340: 
 341:   /**
 342:      Assign the key to the alias in the keystore. It will overwrite
 343:      an existing entry and if the key is a PrivateKey, also 
 344:      add the certificate chain representing the corresponding 
 345:      public key.
 346: 
 347:      @param alias the alias name
 348:      @param key the key to add
 349:      @param chain the certificate chain for the corresponding
 350:      public key
 351: 
 352:      @throws KeyStoreException if it fails
 353:    */
 354:   public final void setKeyEntry(String alias, byte[]key,
 355:                 java.security.cert.
 356:                 Certificate[]chain) throws KeyStoreException
 357:   {
 358:     keyStoreSpi.engineSetKeyEntry(alias, key, chain);
 359:   }
 360: 
 361:   /**
 362:      Assign the certificate to the alias in the keystore. It 
 363:      will overwrite an existing entry.
 364: 
 365:      @param alias the alias name
 366:      @param cert the certificate to add
 367: 
 368:      @throws KeyStoreException if it fails
 369:    */
 370:   public final void setCertificateEntry(String alias,
 371:                     java.security.cert.
 372:                     Certificate cert) throws
 373:     KeyStoreException
 374:   {
 375:     keyStoreSpi.engineSetCertificateEntry(alias, cert);
 376:   }
 377: 
 378:   /**
 379:      Deletes the entry for the specified entry.
 380: 
 381:      @param alias the alias name
 382: 
 383:      @throws KeyStoreException if it fails
 384:    */
 385:   public final void deleteEntry(String alias) throws KeyStoreException
 386:   {
 387:     keyStoreSpi.engineDeleteEntry(alias);
 388:   }
 389: 
 390:   /**
 391:      Generates a list of all the aliases in the keystore.
 392: 
 393:      @return an Enumeration of the aliases
 394:    */
 395:   public final Enumeration aliases() throws KeyStoreException
 396:   {
 397:     return keyStoreSpi.engineAliases();
 398:   }
 399: 
 400:   /**
 401:      Determines if the keystore contains the specified alias.
 402: 
 403:      @param alias the alias name
 404: 
 405:      @return true if it contains the alias, false otherwise
 406:    */
 407:   public final boolean containsAlias(String alias) throws KeyStoreException
 408:   {
 409:     return keyStoreSpi.engineContainsAlias(alias);
 410:   }
 411: 
 412:   /**
 413:      Returns the number of entries in the keystore.
 414: 
 415:      @returns the number of keystore entries.
 416:    */
 417:   public final int size() throws KeyStoreException
 418:   {
 419:     return keyStoreSpi.engineSize();
 420:   }
 421: 
 422:   /**
 423:      Determines if the keystore contains a key entry for 
 424:      the specified alias.
 425: 
 426:      @param alias the alias name
 427: 
 428:      @return true if it is a key entry, false otherwise
 429:    */
 430:   public final boolean isKeyEntry(String alias) throws KeyStoreException
 431:   {
 432:     return keyStoreSpi.engineIsKeyEntry(alias);
 433:   }
 434: 
 435: 
 436:   /**
 437:      Determines if the keystore contains a certificate entry for 
 438:      the specified alias.
 439: 
 440:      @param alias the alias name
 441: 
 442:      @return true if it is a certificate entry, false otherwise
 443:    */
 444:   public final boolean isCertificateEntry(String alias)
 445:     throws KeyStoreException
 446:   {
 447:     return keyStoreSpi.engineIsCertificateEntry(alias);
 448:   }
 449: 
 450:   /**
 451:      Determines if the keystore contains the specified certificate 
 452:      entry and returns the alias.
 453: 
 454:      It checks every entry and for a key entry checks only the
 455:      first certificate in the chain.
 456: 
 457:      @param cert Certificate to look for
 458: 
 459:      @return alias of first matching certificate, null if it 
 460:      does not exist.
 461:    */
 462:   public final String getCertificateAlias(java.security.cert.Certificate cert)
 463:     throws KeyStoreException
 464:   {
 465:     return keyStoreSpi.engineGetCertificateAlias(cert);
 466:   }
 467: 
 468:   /**
 469:      Stores the keystore in the specified output stream and it
 470:      uses the specified key it keep it secure.
 471: 
 472:      @param stream the output stream to save the keystore to
 473:      @param password the password to protect the keystore integrity with
 474: 
 475:      @throws IOException if an I/O error occurs.
 476:      @throws NoSuchAlgorithmException the data integrity algorithm 
 477:      used cannot be found.
 478:      @throws CertificateException if any certificates could not be
 479:      stored in the output stream.
 480:    */
 481:   public final void store(OutputStream stream, char[]password)
 482:     throws KeyStoreException, IOException, NoSuchAlgorithmException,
 483:     CertificateException
 484:   {
 485:     keyStoreSpi.engineStore(stream, password);
 486:   }
 487: 
 488:   /**
 489:      Loads the keystore from the specified input stream and it
 490:      uses the specified password to check for integrity if supplied.
 491: 
 492:      @param stream the input stream to load the keystore from
 493:      @param password the password to check the keystore integrity with
 494: 
 495:      @throws IOException if an I/O error occurs.
 496:      @throws NoSuchAlgorithmException the data integrity algorithm 
 497:      used cannot be found.
 498:      @throws CertificateException if any certificates could not be
 499:      stored in the output stream.
 500:    */
 501:   public final void load(InputStream stream, char[]password)
 502:     throws IOException, NoSuchAlgorithmException, CertificateException
 503:   {
 504:     keyStoreSpi.engineLoad(stream, password);
 505:   }
 506: 
 507: }