Save This Page
Home » openjdk-7 » java » security » [javadoc | source]
    1   /*
    2    * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.security;
   27   
   28   import java.io;
   29   import java.util;
   30   
   31   import java.security.KeyStore;
   32   import java.security.cert.Certificate;
   33   import java.security.cert.CertificateException;
   34   
   35   import javax.crypto.SecretKey;
   36   
   37   import javax.security.auth.callback;
   38   
   39   /**
   40    * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
   41    * for the <code>KeyStore</code> class.
   42    * All the abstract methods in this class must be implemented by each
   43    * cryptographic service provider who wishes to supply the implementation
   44    * of a keystore for a particular keystore type.
   45    *
   46    * @author Jan Luehe
   47    *
   48    *
   49    * @see KeyStore
   50    *
   51    * @since 1.2
   52    */
   53   
   54   public abstract class KeyStoreSpi {
   55   
   56       /**
   57        * Returns the key associated with the given alias, using the given
   58        * password to recover it.  The key must have been associated with
   59        * the alias by a call to <code>setKeyEntry</code>,
   60        * or by a call to <code>setEntry</code> with a
   61        * <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>.
   62        *
   63        * @param alias the alias name
   64        * @param password the password for recovering the key
   65        *
   66        * @return the requested key, or null if the given alias does not exist
   67        * or does not identify a key-related entry.
   68        *
   69        * @exception NoSuchAlgorithmException if the algorithm for recovering the
   70        * key cannot be found
   71        * @exception UnrecoverableKeyException if the key cannot be recovered
   72        * (e.g., the given password is wrong).
   73        */
   74       public abstract Key engineGetKey(String alias, char[] password)
   75           throws NoSuchAlgorithmException, UnrecoverableKeyException;
   76   
   77       /**
   78        * Returns the certificate chain associated with the given alias.
   79        * The certificate chain must have been associated with the alias
   80        * by a call to <code>setKeyEntry</code>,
   81        * or by a call to <code>setEntry</code> with a
   82        * <code>PrivateKeyEntry</code>.
   83        *
   84        * @param alias the alias name
   85        *
   86        * @return the certificate chain (ordered with the user's certificate first
   87        * and the root certificate authority last), or null if the given alias
   88        * does not exist or does not contain a certificate chain
   89        */
   90       public abstract Certificate[] engineGetCertificateChain(String alias);
   91   
   92       /**
   93        * Returns the certificate associated with the given alias.
   94        *
   95        * <p> If the given alias name identifies an entry
   96        * created by a call to <code>setCertificateEntry</code>,
   97        * or created by a call to <code>setEntry</code> with a
   98        * <code>TrustedCertificateEntry</code>,
   99        * then the trusted certificate contained in that entry is returned.
  100        *
  101        * <p> If the given alias name identifies an entry
  102        * created by a call to <code>setKeyEntry</code>,
  103        * or created by a call to <code>setEntry</code> with a
  104        * <code>PrivateKeyEntry</code>,
  105        * then the first element of the certificate chain in that entry
  106        * (if a chain exists) is returned.
  107        *
  108        * @param alias the alias name
  109        *
  110        * @return the certificate, or null if the given alias does not exist or
  111        * does not contain a certificate.
  112        */
  113       public abstract Certificate engineGetCertificate(String alias);
  114   
  115       /**
  116        * Returns the creation date of the entry identified by the given alias.
  117        *
  118        * @param alias the alias name
  119        *
  120        * @return the creation date of this entry, or null if the given alias does
  121        * not exist
  122        */
  123       public abstract Date engineGetCreationDate(String alias);
  124   
  125       /**
  126        * Assigns the given key to the given alias, protecting it with the given
  127        * password.
  128        *
  129        * <p>If the given key is of type <code>java.security.PrivateKey</code>,
  130        * it must be accompanied by a certificate chain certifying the
  131        * corresponding public key.
  132        *
  133        * <p>If the given alias already exists, the keystore information
  134        * associated with it is overridden by the given key (and possibly
  135        * certificate chain).
  136        *
  137        * @param alias the alias name
  138        * @param key the key to be associated with the alias
  139        * @param password the password to protect the key
  140        * @param chain the certificate chain for the corresponding public
  141        * key (only required if the given key is of type
  142        * <code>java.security.PrivateKey</code>).
  143        *
  144        * @exception KeyStoreException if the given key cannot be protected, or
  145        * this operation fails for some other reason
  146        */
  147       public abstract void engineSetKeyEntry(String alias, Key key,
  148                                              char[] password,
  149                                              Certificate[] chain)
  150           throws KeyStoreException;
  151   
  152       /**
  153        * Assigns the given key (that has already been protected) to the given
  154        * alias.
  155        *
  156        * <p>If the protected key is of type
  157        * <code>java.security.PrivateKey</code>,
  158        * it must be accompanied by a certificate chain certifying the
  159        * corresponding public key.
  160        *
  161        * <p>If the given alias already exists, the keystore information
  162        * associated with it is overridden by the given key (and possibly
  163        * certificate chain).
  164        *
  165        * @param alias the alias name
  166        * @param key the key (in protected format) to be associated with the alias
  167        * @param chain the certificate chain for the corresponding public
  168        * key (only useful if the protected key is of type
  169        * <code>java.security.PrivateKey</code>).
  170        *
  171        * @exception KeyStoreException if this operation fails.
  172        */
  173       public abstract void engineSetKeyEntry(String alias, byte[] key,
  174                                              Certificate[] chain)
  175           throws KeyStoreException;
  176   
  177       /**
  178        * Assigns the given certificate to the given alias.
  179        *
  180        * <p> If the given alias identifies an existing entry
  181        * created by a call to <code>setCertificateEntry</code>,
  182        * or created by a call to <code>setEntry</code> with a
  183        * <code>TrustedCertificateEntry</code>,
  184        * the trusted certificate in the existing entry
  185        * is overridden by the given certificate.
  186        *
  187        * @param alias the alias name
  188        * @param cert the certificate
  189        *
  190        * @exception KeyStoreException if the given alias already exists and does
  191        * not identify an entry containing a trusted certificate,
  192        * or this operation fails for some other reason.
  193        */
  194       public abstract void engineSetCertificateEntry(String alias,
  195                                                      Certificate cert)
  196           throws KeyStoreException;
  197   
  198       /**
  199        * Deletes the entry identified by the given alias from this keystore.
  200        *
  201        * @param alias the alias name
  202        *
  203        * @exception KeyStoreException if the entry cannot be removed.
  204        */
  205       public abstract void engineDeleteEntry(String alias)
  206           throws KeyStoreException;
  207   
  208       /**
  209        * Lists all the alias names of this keystore.
  210        *
  211        * @return enumeration of the alias names
  212        */
  213       public abstract Enumeration<String> engineAliases();
  214   
  215       /**
  216        * Checks if the given alias exists in this keystore.
  217        *
  218        * @param alias the alias name
  219        *
  220        * @return true if the alias exists, false otherwise
  221        */
  222       public abstract boolean engineContainsAlias(String alias);
  223   
  224       /**
  225        * Retrieves the number of entries in this keystore.
  226        *
  227        * @return the number of entries in this keystore
  228        */
  229       public abstract int engineSize();
  230   
  231       /**
  232        * Returns true if the entry identified by the given alias
  233        * was created by a call to <code>setKeyEntry</code>,
  234        * or created by a call to <code>setEntry</code> with a
  235        * <code>PrivateKeyEntry</code> or a <code>SecretKeyEntry</code>.
  236        *
  237        * @param alias the alias for the keystore entry to be checked
  238        *
  239        * @return true if the entry identified by the given alias is a
  240        * key-related, false otherwise.
  241        */
  242       public abstract boolean engineIsKeyEntry(String alias);
  243   
  244       /**
  245        * Returns true if the entry identified by the given alias
  246        * was created by a call to <code>setCertificateEntry</code>,
  247        * or created by a call to <code>setEntry</code> with a
  248        * <code>TrustedCertificateEntry</code>.
  249        *
  250        * @param alias the alias for the keystore entry to be checked
  251        *
  252        * @return true if the entry identified by the given alias contains a
  253        * trusted certificate, false otherwise.
  254        */
  255       public abstract boolean engineIsCertificateEntry(String alias);
  256   
  257       /**
  258        * Returns the (alias) name of the first keystore entry whose certificate
  259        * matches the given certificate.
  260        *
  261        * <p>This method attempts to match the given certificate with each
  262        * keystore entry. If the entry being considered was
  263        * created by a call to <code>setCertificateEntry</code>,
  264        * or created by a call to <code>setEntry</code> with a
  265        * <code>TrustedCertificateEntry</code>,
  266        * then the given certificate is compared to that entry's certificate.
  267        *
  268        * <p> If the entry being considered was
  269        * created by a call to <code>setKeyEntry</code>,
  270        * or created by a call to <code>setEntry</code> with a
  271        * <code>PrivateKeyEntry</code>,
  272        * then the given certificate is compared to the first
  273        * element of that entry's certificate chain.
  274        *
  275        * @param cert the certificate to match with.
  276        *
  277        * @return the alias name of the first entry with matching certificate,
  278        * or null if no such entry exists in this keystore.
  279        */
  280       public abstract String engineGetCertificateAlias(Certificate cert);
  281   
  282       /**
  283        * Stores this keystore to the given output stream, and protects its
  284        * integrity with the given password.
  285        *
  286        * @param stream the output stream to which this keystore is written.
  287        * @param password the password to generate the keystore integrity check
  288        *
  289        * @exception IOException if there was an I/O problem with data
  290        * @exception NoSuchAlgorithmException if the appropriate data integrity
  291        * algorithm could not be found
  292        * @exception CertificateException if any of the certificates included in
  293        * the keystore data could not be stored
  294        */
  295       public abstract void engineStore(OutputStream stream, char[] password)
  296           throws IOException, NoSuchAlgorithmException, CertificateException;
  297   
  298       /**
  299        * Stores this keystore using the given
  300        * <code>KeyStore.LoadStoreParmeter</code>.
  301        *
  302        * @param param the <code>KeyStore.LoadStoreParmeter</code>
  303        *          that specifies how to store the keystore,
  304        *          which may be <code>null</code>
  305        *
  306        * @exception IllegalArgumentException if the given
  307        *          <code>KeyStore.LoadStoreParmeter</code>
  308        *          input is not recognized
  309        * @exception IOException if there was an I/O problem with data
  310        * @exception NoSuchAlgorithmException if the appropriate data integrity
  311        *          algorithm could not be found
  312        * @exception CertificateException if any of the certificates included in
  313        *          the keystore data could not be stored
  314        *
  315        * @since 1.5
  316        */
  317       public void engineStore(KeyStore.LoadStoreParameter param)
  318                   throws IOException, NoSuchAlgorithmException,
  319                   CertificateException {
  320           throw new UnsupportedOperationException();
  321       }
  322   
  323       /**
  324        * Loads the keystore from the given input stream.
  325        *
  326        * <p>A password may be given to unlock the keystore
  327        * (e.g. the keystore resides on a hardware token device),
  328        * or to check the integrity of the keystore data.
  329        * If a password is not given for integrity checking,
  330        * then integrity checking is not performed.
  331        *
  332        * @param stream the input stream from which the keystore is loaded,
  333        * or <code>null</code>
  334        * @param password the password used to check the integrity of
  335        * the keystore, the password used to unlock the keystore,
  336        * or <code>null</code>
  337        *
  338        * @exception IOException if there is an I/O or format problem with the
  339        * keystore data, if a password is required but not given,
  340        * or if the given password was incorrect. If the error is due to a
  341        * wrong password, the {@link Throwable#getCause cause} of the
  342        * <code>IOException</code> should be an
  343        * <code>UnrecoverableKeyException</code>
  344        * @exception NoSuchAlgorithmException if the algorithm used to check
  345        * the integrity of the keystore cannot be found
  346        * @exception CertificateException if any of the certificates in the
  347        * keystore could not be loaded
  348        */
  349       public abstract void engineLoad(InputStream stream, char[] password)
  350           throws IOException, NoSuchAlgorithmException, CertificateException;
  351   
  352       /**
  353        * Loads the keystore using the given
  354        * <code>KeyStore.LoadStoreParameter</code>.
  355        *
  356        * <p> Note that if this KeyStore has already been loaded, it is
  357        * reinitialized and loaded again from the given parameter.
  358        *
  359        * @param param the <code>KeyStore.LoadStoreParameter</code>
  360        *          that specifies how to load the keystore,
  361        *          which may be <code>null</code>
  362        *
  363        * @exception IllegalArgumentException if the given
  364        *          <code>KeyStore.LoadStoreParameter</code>
  365        *          input is not recognized
  366        * @exception IOException if there is an I/O or format problem with the
  367        *          keystore data. If the error is due to an incorrect
  368        *         <code>ProtectionParameter</code> (e.g. wrong password)
  369        *         the {@link Throwable#getCause cause} of the
  370        *         <code>IOException</code> should be an
  371        *         <code>UnrecoverableKeyException</code>
  372        * @exception NoSuchAlgorithmException if the algorithm used to check
  373        *          the integrity of the keystore cannot be found
  374        * @exception CertificateException if any of the certificates in the
  375        *          keystore could not be loaded
  376        *
  377        * @since 1.5
  378        */
  379       public void engineLoad(KeyStore.LoadStoreParameter param)
  380                   throws IOException, NoSuchAlgorithmException,
  381                   CertificateException {
  382   
  383           if (param == null) {
  384               engineLoad((InputStream)null, (char[])null);
  385               return;
  386           }
  387   
  388           if (param instanceof KeyStore.SimpleLoadStoreParameter) {
  389               ProtectionParameter protection = param.getProtectionParameter();
  390               char[] password;
  391               if (protection instanceof PasswordProtection) {
  392                   password = ((PasswordProtection)protection).getPassword();
  393               } else if (protection instanceof CallbackHandlerProtection) {
  394                   CallbackHandler handler =
  395                       ((CallbackHandlerProtection)protection).getCallbackHandler();
  396                   PasswordCallback callback =
  397                       new PasswordCallback("Password: ", false);
  398                   try {
  399                       handler.handle(new Callback[] {callback});
  400                   } catch (UnsupportedCallbackException e) {
  401                       throw new NoSuchAlgorithmException
  402                           ("Could not obtain password", e);
  403                   }
  404                   password = callback.getPassword();
  405                   callback.clearPassword();
  406                   if (password == null) {
  407                       throw new NoSuchAlgorithmException
  408                           ("No password provided");
  409                   }
  410               } else {
  411                   throw new NoSuchAlgorithmException("ProtectionParameter must"
  412                       + " be PasswordProtection or CallbackHandlerProtection");
  413               }
  414               engineLoad(null, password);
  415               return;
  416           }
  417   
  418           throw new UnsupportedOperationException();
  419       }
  420   
  421       /**
  422        * Gets a <code>KeyStore.Entry</code> for the specified alias
  423        * with the specified protection parameter.
  424        *
  425        * @param alias get the <code>KeyStore.Entry</code> for this alias
  426        * @param protParam the <code>ProtectionParameter</code>
  427        *          used to protect the <code>Entry</code>,
  428        *          which may be <code>null</code>
  429        *
  430        * @return the <code>KeyStore.Entry</code> for the specified alias,
  431        *          or <code>null</code> if there is no such entry
  432        *
  433        * @exception KeyStoreException if the operation failed
  434        * @exception NoSuchAlgorithmException if the algorithm for recovering the
  435        *          entry cannot be found
  436        * @exception UnrecoverableEntryException if the specified
  437        *          <code>protParam</code> were insufficient or invalid
  438        * @exception UnrecoverableKeyException if the entry is a
  439        *          <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>
  440        *          and the specified <code>protParam</code> does not contain
  441        *          the information needed to recover the key (e.g. wrong password)
  442        *
  443        * @since 1.5
  444        */
  445       public KeyStore.Entry engineGetEntry(String alias,
  446                           KeyStore.ProtectionParameter protParam)
  447                   throws KeyStoreException, NoSuchAlgorithmException,
  448                   UnrecoverableEntryException {
  449   
  450           if (!engineContainsAlias(alias)) {
  451               return null;
  452           }
  453   
  454           if (protParam == null) {
  455               if (engineIsCertificateEntry(alias)) {
  456                   return new KeyStore.TrustedCertificateEntry
  457                                   (engineGetCertificate(alias));
  458               } else {
  459                   throw new UnrecoverableKeyException
  460                           ("requested entry requires a password");
  461               }
  462           }
  463   
  464           if (protParam instanceof KeyStore.PasswordProtection) {
  465               if (engineIsCertificateEntry(alias)) {
  466                   throw new UnsupportedOperationException
  467                       ("trusted certificate entries are not password-protected");
  468               } else if (engineIsKeyEntry(alias)) {
  469                   KeyStore.PasswordProtection pp =
  470                           (KeyStore.PasswordProtection)protParam;
  471                   char[] password = pp.getPassword();
  472   
  473                   Key key = engineGetKey(alias, password);
  474                   if (key instanceof PrivateKey) {
  475                       Certificate[] chain = engineGetCertificateChain(alias);
  476                       return new KeyStore.PrivateKeyEntry((PrivateKey)key, chain);
  477                   } else if (key instanceof SecretKey) {
  478                       return new KeyStore.SecretKeyEntry((SecretKey)key);
  479                   }
  480               }
  481           }
  482   
  483           throw new UnsupportedOperationException();
  484       }
  485   
  486       /**
  487        * Saves a <code>KeyStore.Entry</code> under the specified alias.
  488        * The specified protection parameter is used to protect the
  489        * <code>Entry</code>.
  490        *
  491        * <p> If an entry already exists for the specified alias,
  492        * it is overridden.
  493        *
  494        * @param alias save the <code>KeyStore.Entry</code> under this alias
  495        * @param entry the <code>Entry</code> to save
  496        * @param protParam the <code>ProtectionParameter</code>
  497        *          used to protect the <code>Entry</code>,
  498        *          which may be <code>null</code>
  499        *
  500        * @exception KeyStoreException if this operation fails
  501        *
  502        * @since 1.5
  503        */
  504       public void engineSetEntry(String alias, KeyStore.Entry entry,
  505                           KeyStore.ProtectionParameter protParam)
  506                   throws KeyStoreException {
  507   
  508           // get password
  509           if (protParam != null &&
  510               !(protParam instanceof KeyStore.PasswordProtection)) {
  511               throw new KeyStoreException("unsupported protection parameter");
  512           }
  513           KeyStore.PasswordProtection pProtect = null;
  514           if (protParam != null) {
  515               pProtect = (KeyStore.PasswordProtection)protParam;
  516           }
  517   
  518           // set entry
  519           if (entry instanceof KeyStore.TrustedCertificateEntry) {
  520               if (protParam != null && pProtect.getPassword() != null) {
  521                   // pre-1.5 style setCertificateEntry did not allow password
  522                   throw new KeyStoreException
  523                       ("trusted certificate entries are not password-protected");
  524               } else {
  525                   KeyStore.TrustedCertificateEntry tce =
  526                           (KeyStore.TrustedCertificateEntry)entry;
  527                   engineSetCertificateEntry(alias, tce.getTrustedCertificate());
  528                   return;
  529               }
  530           } else if (entry instanceof KeyStore.PrivateKeyEntry) {
  531               if (pProtect == null || pProtect.getPassword() == null) {
  532                   // pre-1.5 style setKeyEntry required password
  533                   throw new KeyStoreException
  534                       ("non-null password required to create PrivateKeyEntry");
  535               } else {
  536                   engineSetKeyEntry
  537                       (alias,
  538                       ((KeyStore.PrivateKeyEntry)entry).getPrivateKey(),
  539                       pProtect.getPassword(),
  540                       ((KeyStore.PrivateKeyEntry)entry).getCertificateChain());
  541                   return;
  542               }
  543           } else if (entry instanceof KeyStore.SecretKeyEntry) {
  544               if (pProtect == null || pProtect.getPassword() == null) {
  545                   // pre-1.5 style setKeyEntry required password
  546                   throw new KeyStoreException
  547                       ("non-null password required to create SecretKeyEntry");
  548               } else {
  549                   engineSetKeyEntry
  550                       (alias,
  551                       ((KeyStore.SecretKeyEntry)entry).getSecretKey(),
  552                       pProtect.getPassword(),
  553                       (Certificate[])null);
  554                   return;
  555               }
  556           }
  557   
  558           throw new KeyStoreException
  559                   ("unsupported entry type: " + entry.getClass().getName());
  560       }
  561   
  562       /**
  563        * Determines if the keystore <code>Entry</code> for the specified
  564        * <code>alias</code> is an instance or subclass of the specified
  565        * <code>entryClass</code>.
  566        *
  567        * @param alias the alias name
  568        * @param entryClass the entry class
  569        *
  570        * @return true if the keystore <code>Entry</code> for the specified
  571        *          <code>alias</code> is an instance or subclass of the
  572        *          specified <code>entryClass</code>, false otherwise
  573        *
  574        * @since 1.5
  575        */
  576       public boolean
  577           engineEntryInstanceOf(String alias,
  578                                 Class<? extends KeyStore.Entry> entryClass)
  579       {
  580           if (entryClass == KeyStore.TrustedCertificateEntry.class) {
  581               return engineIsCertificateEntry(alias);
  582           }
  583           if (entryClass == KeyStore.PrivateKeyEntry.class) {
  584               return engineIsKeyEntry(alias) &&
  585                           engineGetCertificate(alias) != null;
  586           }
  587           if (entryClass == KeyStore.SecretKeyEntry.class) {
  588               return engineIsKeyEntry(alias) &&
  589                           engineGetCertificate(alias) == null;
  590           }
  591           return false;
  592       }
  593   }

Save This Page
Home » openjdk-7 » java » security » [javadoc | source]