< prev index next >

src/java.base/share/classes/javax/crypto/KeyAgreement.java

Print this page




  23  * questions.
  24  */
  25 
  26 package javax.crypto;
  27 
  28 import java.util.*;
  29 
  30 import java.security.*;
  31 import java.security.Provider.Service;
  32 import java.security.spec.*;
  33 
  34 import sun.security.util.Debug;
  35 import sun.security.jca.*;
  36 import sun.security.jca.GetInstance.Instance;
  37 
  38 /**
  39  * This class provides the functionality of a key agreement (or key
  40  * exchange) protocol.
  41  * <p>
  42  * The keys involved in establishing a shared secret are created by one of the
  43  * key generators (<code>KeyPairGenerator</code> or
  44  * <code>KeyGenerator</code>), a <code>KeyFactory</code>, or as a result from
  45  * an intermediate phase of the key agreement protocol.
  46  *
  47  * <p> For each of the correspondents in the key exchange, <code>doPhase</code>
  48  * needs to be called. For example, if this key exchange is with one other
  49  * party, <code>doPhase</code> needs to be called once, with the
  50  * <code>lastPhase</code> flag set to <code>true</code>.
  51  * If this key exchange is
  52  * with two other parties, <code>doPhase</code> needs to be called twice,
  53  * the first time setting the <code>lastPhase</code> flag to
  54  * <code>false</code>, and the second time setting it to <code>true</code>.
  55  * There may be any number of parties involved in a key exchange.
  56  *
  57  * <p> Every implementation of the Java platform is required to support the
  58  * following standard <code>KeyAgreement</code> algorithm:
  59  * <ul>
  60  * <li><tt>DiffieHellman</tt></li>
  61  * </ul>
  62  * This algorithm is described in the <a href=
  63  * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
  64  * KeyAgreement section</a> of the
  65  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  66  * Consult the release documentation for your implementation to see if any
  67  * other algorithms are supported.
  68  *
  69  * @author Jan Luehe
  70  *
  71  * @see KeyGenerator
  72  * @see SecretKey
  73  * @since 1.4
  74  */
  75 
  76 public class KeyAgreement {
  77 
  78     private static final Debug debug =
  79                         Debug.getInstance("jca", "KeyAgreement");
  80 


 108      * @param keyAgreeSpi the delegate
 109      * @param provider the provider
 110      * @param algorithm the algorithm
 111      */
 112     protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
 113                            String algorithm) {
 114         this.spi = keyAgreeSpi;
 115         this.provider = provider;
 116         this.algorithm = algorithm;
 117         lock = null;
 118     }
 119 
 120     private KeyAgreement(Service s, Iterator<Service> t, String algorithm) {
 121         firstService = s;
 122         serviceIterator = t;
 123         this.algorithm = algorithm;
 124         lock = new Object();
 125     }
 126 
 127     /**
 128      * Returns the algorithm name of this <code>KeyAgreement</code> object.
 129      *
 130      * <p>This is the same name that was specified in one of the
 131      * <code>getInstance</code> calls that created this
 132      * <code>KeyAgreement</code> object.
 133      *
 134      * @return the algorithm name of this <code>KeyAgreement</code> object.
 135      */
 136     public final String getAlgorithm() {
 137         return this.algorithm;
 138     }
 139 
 140     /**
 141      * Returns a <code>KeyAgreement</code> object that implements the
 142      * specified key agreement algorithm.
 143      *
 144      * <p> This method traverses the list of registered security Providers,
 145      * starting with the most preferred Provider.
 146      * A new KeyAgreement object encapsulating the
 147      * KeyAgreementSpi implementation from the first
 148      * Provider that supports the specified algorithm is returned.
 149      *
 150      * <p> Note that the list of registered providers may be retrieved via
 151      * the {@link Security#getProviders() Security.getProviders()} method.
 152      *
 153      * @param algorithm the standard name of the requested key agreement
 154      * algorithm.
 155      * See the KeyAgreement section in the <a href=
 156      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
 157      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 158      * for information about standard algorithm names.
 159      *
 160      * @return the new <code>KeyAgreement</code> object.
 161      *
 162      * @exception NullPointerException if the specified algorithm
 163      *          is null.
 164      *
 165      * @exception NoSuchAlgorithmException if no Provider supports a
 166      *          KeyAgreementSpi implementation for the
 167      *          specified algorithm.
 168      *
 169      * @see java.security.Provider
 170      */
 171     public static final KeyAgreement getInstance(String algorithm)
 172             throws NoSuchAlgorithmException {
 173         List<Service> services =
 174                 GetInstance.getServices("KeyAgreement", algorithm);
 175         // make sure there is at least one service from a signed provider
 176         Iterator<Service> t = services.iterator();
 177         while (t.hasNext()) {
 178             Service s = t.next();
 179             if (JceSecurity.canUseProvider(s.getProvider()) == false) {
 180                 continue;
 181             }
 182             return new KeyAgreement(s, t, algorithm);
 183         }
 184         throw new NoSuchAlgorithmException
 185                                 ("Algorithm " + algorithm + " not available");
 186     }
 187 
 188     /**
 189      * Returns a <code>KeyAgreement</code> object that implements the
 190      * specified key agreement algorithm.
 191      *
 192      * <p> A new KeyAgreement object encapsulating the
 193      * KeyAgreementSpi implementation from the specified provider
 194      * is returned.  The specified provider must be registered
 195      * in the security provider list.
 196      *
 197      * <p> Note that the list of registered providers may be retrieved via
 198      * the {@link Security#getProviders() Security.getProviders()} method.
 199      *
 200      * @param algorithm the standard name of the requested key agreement
 201      * algorithm.
 202      * See the KeyAgreement section in the <a href=
 203      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
 204      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 205      * for information about standard algorithm names.
 206      *
 207      * @param provider the name of the provider.
 208      *
 209      * @return the new <code>KeyAgreement</code> object.
 210      *
 211      * @exception NullPointerException if the specified algorithm
 212      *          is null.
 213      *
 214      * @exception NoSuchAlgorithmException if a KeyAgreementSpi
 215      *          implementation for the specified algorithm is not
 216      *          available from the specified provider.
 217      *
 218      * @exception NoSuchProviderException if the specified provider is not
 219      *          registered in the security provider list.
 220      *
 221      * @exception IllegalArgumentException if the <code>provider</code>
 222      *          is null or empty.
 223      *
 224      * @see java.security.Provider
 225      */
 226     public static final KeyAgreement getInstance(String algorithm,
 227             String provider) throws NoSuchAlgorithmException,
 228             NoSuchProviderException {
 229         Instance instance = JceSecurity.getInstance
 230                 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
 231         return new KeyAgreement((KeyAgreementSpi)instance.impl,
 232                 instance.provider, algorithm);
 233     }
 234 
 235     /**
 236      * Returns a <code>KeyAgreement</code> object that implements the
 237      * specified key agreement algorithm.
 238      *
 239      * <p> A new KeyAgreement object encapsulating the
 240      * KeyAgreementSpi implementation from the specified Provider
 241      * object is returned.  Note that the specified Provider object
 242      * does not have to be registered in the provider list.
 243      *
 244      * @param algorithm the standard name of the requested key agreement
 245      * algorithm.
 246      * See the KeyAgreement section in the <a href=
 247      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
 248      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 249      * for information about standard algorithm names.
 250      *
 251      * @param provider the provider.
 252      *
 253      * @return the new <code>KeyAgreement</code> object.
 254      *
 255      * @exception NullPointerException if the specified algorithm
 256      *          is null.
 257      *
 258      * @exception NoSuchAlgorithmException if a KeyAgreementSpi
 259      *          implementation for the specified algorithm is not available
 260      *          from the specified Provider object.
 261      *
 262      * @exception IllegalArgumentException if the <code>provider</code>
 263      *          is null.
 264      *
 265      * @see java.security.Provider
 266      */
 267     public static final KeyAgreement getInstance(String algorithm,
 268             Provider provider) throws NoSuchAlgorithmException {
 269         Instance instance = JceSecurity.getInstance
 270                 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
 271         return new KeyAgreement((KeyAgreementSpi)instance.impl,
 272                 instance.provider, algorithm);
 273     }
 274 
 275     // max number of debug warnings to print from chooseFirstProvider()
 276     private static int warnCount = 10;
 277 
 278     /**
 279      * Choose the Spi from the first provider available. Used if
 280      * delayed provider selection is not possible because init()
 281      * is not the first method called.
 282      */


 391                 }
 392             }
 393             // no working provider found, fail
 394             if (lastException instanceof InvalidKeyException) {
 395                 throw (InvalidKeyException)lastException;
 396             }
 397             if (lastException instanceof InvalidAlgorithmParameterException) {
 398                 throw (InvalidAlgorithmParameterException)lastException;
 399             }
 400             if (lastException instanceof RuntimeException) {
 401                 throw (RuntimeException)lastException;
 402             }
 403             String kName = (key != null) ? key.getClass().getName() : "(null)";
 404             throw new InvalidKeyException
 405                 ("No installed provider supports this key: "
 406                 + kName, lastException);
 407         }
 408     }
 409 
 410     /**
 411      * Returns the provider of this <code>KeyAgreement</code> object.
 412      *
 413      * @return the provider of this <code>KeyAgreement</code> object
 414      */
 415     public final Provider getProvider() {
 416         chooseFirstProvider();
 417         return this.provider;
 418     }
 419 
 420     /**
 421      * Initializes this key agreement with the given key, which is required to
 422      * contain all the algorithm parameters required for this key agreement.
 423      *
 424      * <p> If this key agreement requires any random bytes, it will get
 425      * them using the
 426      * {@link java.security.SecureRandom}
 427      * implementation of the highest-priority
 428      * installed provider as the source of randomness.
 429      * (If none of the installed providers supply an implementation of
 430      * SecureRandom, a system-provided source of randomness will be used.)
 431      *
 432      * @param key the party's private information. For example, in the case
 433      * of the Diffie-Hellman key agreement, this would be the party's own
 434      * Diffie-Hellman private key.
 435      *
 436      * @exception InvalidKeyException if the given key is
 437      * inappropriate for this key agreement, e.g., is of the wrong type or
 438      * has an incompatible algorithm type.
 439      */
 440     public final void init(Key key) throws InvalidKeyException {
 441         init(key, JceSecurity.RANDOM);
 442     }
 443 
 444     /**
 445      * Initializes this key agreement with the given key and source of
 446      * randomness. The given key is required to contain all the algorithm
 447      * parameters required for this key agreement.
 448      *
 449      * <p> If the key agreement algorithm requires random bytes, it gets them
 450      * from the given source of randomness, <code>random</code>.
 451      * However, if the underlying
 452      * algorithm implementation does not require any random bytes,
 453      * <code>random</code> is ignored.
 454      *
 455      * @param key the party's private information. For example, in the case
 456      * of the Diffie-Hellman key agreement, this would be the party's own
 457      * Diffie-Hellman private key.
 458      * @param random the source of randomness
 459      *
 460      * @exception InvalidKeyException if the given key is
 461      * inappropriate for this key agreement, e.g., is of the wrong type or
 462      * has an incompatible algorithm type.
 463      */
 464     public final void init(Key key, SecureRandom random)
 465             throws InvalidKeyException {
 466         if (spi != null) {
 467             spi.engineInit(key, random);
 468         } else {
 469             try {
 470                 chooseProvider(I_NO_PARAMS, key, null, random);
 471             } catch (InvalidAlgorithmParameterException e) {
 472                 // should never occur
 473                 throw new InvalidKeyException(e);


 553      * phase of this key agreement.
 554      *
 555      * @return the (intermediate) key resulting from this phase, or null
 556      * if this phase does not yield a key
 557      *
 558      * @exception InvalidKeyException if the given key is inappropriate for
 559      * this phase.
 560      * @exception IllegalStateException if this key agreement has not been
 561      * initialized.
 562      */
 563     public final Key doPhase(Key key, boolean lastPhase)
 564         throws InvalidKeyException, IllegalStateException
 565     {
 566         chooseFirstProvider();
 567         return spi.engineDoPhase(key, lastPhase);
 568     }
 569 
 570     /**
 571      * Generates the shared secret and returns it in a new buffer.
 572      *
 573      * <p>This method resets this <code>KeyAgreement</code> object, so that it
 574      * can be reused for further key agreements. Unless this key agreement is
 575      * reinitialized with one of the <code>init</code> methods, the same
 576      * private information and algorithm parameters will be used for
 577      * subsequent key agreements.
 578      *
 579      * @return the new buffer with the shared secret
 580      *
 581      * @exception IllegalStateException if this key agreement has not been
 582      * completed yet
 583      */
 584     public final byte[] generateSecret() throws IllegalStateException {
 585         chooseFirstProvider();
 586         return spi.engineGenerateSecret();
 587     }
 588 
 589     /**
 590      * Generates the shared secret, and places it into the buffer
 591      * <code>sharedSecret</code>, beginning at <code>offset</code> inclusive.
 592      *
 593      * <p>If the <code>sharedSecret</code> buffer is too small to hold the
 594      * result, a <code>ShortBufferException</code> is thrown.
 595      * In this case, this call should be repeated with a larger output buffer.
 596      *
 597      * <p>This method resets this <code>KeyAgreement</code> object, so that it
 598      * can be reused for further key agreements. Unless this key agreement is
 599      * reinitialized with one of the <code>init</code> methods, the same
 600      * private information and algorithm parameters will be used for
 601      * subsequent key agreements.
 602      *
 603      * @param sharedSecret the buffer for the shared secret
 604      * @param offset the offset in <code>sharedSecret</code> where the
 605      * shared secret will be stored
 606      *
 607      * @return the number of bytes placed into <code>sharedSecret</code>
 608      *
 609      * @exception IllegalStateException if this key agreement has not been
 610      * completed yet
 611      * @exception ShortBufferException if the given output buffer is too small
 612      * to hold the secret
 613      */
 614     public final int generateSecret(byte[] sharedSecret, int offset)
 615         throws IllegalStateException, ShortBufferException
 616     {
 617         chooseFirstProvider();
 618         return spi.engineGenerateSecret(sharedSecret, offset);
 619     }
 620 
 621     /**
 622      * Creates the shared secret and returns it as a <code>SecretKey</code>
 623      * object of the specified algorithm.
 624      *
 625      * <p>This method resets this <code>KeyAgreement</code> object, so that it
 626      * can be reused for further key agreements. Unless this key agreement is
 627      * reinitialized with one of the <code>init</code> methods, the same
 628      * private information and algorithm parameters will be used for
 629      * subsequent key agreements.
 630      *
 631      * @param algorithm the requested secret-key algorithm
 632      *
 633      * @return the shared secret key
 634      *
 635      * @exception IllegalStateException if this key agreement has not been
 636      * completed yet
 637      * @exception NoSuchAlgorithmException if the specified secret-key
 638      * algorithm is not available
 639      * @exception InvalidKeyException if the shared secret-key material cannot
 640      * be used to generate a secret key of the specified algorithm (e.g.,
 641      * the key material is too short)
 642      */
 643     public final SecretKey generateSecret(String algorithm)
 644         throws IllegalStateException, NoSuchAlgorithmException,
 645             InvalidKeyException
 646     {
 647         chooseFirstProvider();


  23  * questions.
  24  */
  25 
  26 package javax.crypto;
  27 
  28 import java.util.*;
  29 
  30 import java.security.*;
  31 import java.security.Provider.Service;
  32 import java.security.spec.*;
  33 
  34 import sun.security.util.Debug;
  35 import sun.security.jca.*;
  36 import sun.security.jca.GetInstance.Instance;
  37 
  38 /**
  39  * This class provides the functionality of a key agreement (or key
  40  * exchange) protocol.
  41  * <p>
  42  * The keys involved in establishing a shared secret are created by one of the
  43  * key generators ({@code KeyPairGenerator} or
  44  * {@code KeyGenerator}), a {@code KeyFactory}, or as a result from
  45  * an intermediate phase of the key agreement protocol.
  46  *
  47  * <p> For each of the correspondents in the key exchange, {@code doPhase}
  48  * needs to be called. For example, if this key exchange is with one other
  49  * party, {@code doPhase} needs to be called once, with the
  50  * {@code lastPhase} flag set to {@code true}.
  51  * If this key exchange is
  52  * with two other parties, {@code doPhase} needs to be called twice,
  53  * the first time setting the {@code lastPhase} flag to
  54  * {@code false}, and the second time setting it to {@code true}.
  55  * There may be any number of parties involved in a key exchange.
  56  *
  57  * <p> Every implementation of the Java platform is required to support the
  58  * following standard {@code KeyAgreement} algorithm:
  59  * <ul>
  60  * <li>{@code DiffieHellman}</li>
  61  * </ul>
  62  * This algorithm is described in the <a href=
  63  * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
  64  * KeyAgreement section</a> of the
  65  * Java Cryptography Architecture Standard Algorithm Name Documentation.
  66  * Consult the release documentation for your implementation to see if any
  67  * other algorithms are supported.
  68  *
  69  * @author Jan Luehe
  70  *
  71  * @see KeyGenerator
  72  * @see SecretKey
  73  * @since 1.4
  74  */
  75 
  76 public class KeyAgreement {
  77 
  78     private static final Debug debug =
  79                         Debug.getInstance("jca", "KeyAgreement");
  80 


 108      * @param keyAgreeSpi the delegate
 109      * @param provider the provider
 110      * @param algorithm the algorithm
 111      */
 112     protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
 113                            String algorithm) {
 114         this.spi = keyAgreeSpi;
 115         this.provider = provider;
 116         this.algorithm = algorithm;
 117         lock = null;
 118     }
 119 
 120     private KeyAgreement(Service s, Iterator<Service> t, String algorithm) {
 121         firstService = s;
 122         serviceIterator = t;
 123         this.algorithm = algorithm;
 124         lock = new Object();
 125     }
 126 
 127     /**
 128      * Returns the algorithm name of this {@code KeyAgreement} object.
 129      *
 130      * <p>This is the same name that was specified in one of the
 131      * {@code getInstance} calls that created this
 132      * {@code KeyAgreement} object.
 133      *
 134      * @return the algorithm name of this {@code KeyAgreement} object.
 135      */
 136     public final String getAlgorithm() {
 137         return this.algorithm;
 138     }
 139 
 140     /**
 141      * Returns a {@code KeyAgreement} object that implements the
 142      * specified key agreement algorithm.
 143      *
 144      * <p> This method traverses the list of registered security Providers,
 145      * starting with the most preferred Provider.
 146      * A new KeyAgreement object encapsulating the
 147      * KeyAgreementSpi implementation from the first
 148      * Provider that supports the specified algorithm is returned.
 149      *
 150      * <p> Note that the list of registered providers may be retrieved via
 151      * the {@link Security#getProviders() Security.getProviders()} method.
 152      *
 153      * @param algorithm the standard name of the requested key agreement
 154      * algorithm.
 155      * See the KeyAgreement section in the <a href=
 156      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
 157      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 158      * for information about standard algorithm names.
 159      *
 160      * @return the new {@code KeyAgreement} object.
 161      *
 162      * @exception NullPointerException if the specified algorithm
 163      *          is null.
 164      *
 165      * @exception NoSuchAlgorithmException if no Provider supports a
 166      *          KeyAgreementSpi implementation for the
 167      *          specified algorithm.
 168      *
 169      * @see java.security.Provider
 170      */
 171     public static final KeyAgreement getInstance(String algorithm)
 172             throws NoSuchAlgorithmException {
 173         List<Service> services =
 174                 GetInstance.getServices("KeyAgreement", algorithm);
 175         // make sure there is at least one service from a signed provider
 176         Iterator<Service> t = services.iterator();
 177         while (t.hasNext()) {
 178             Service s = t.next();
 179             if (JceSecurity.canUseProvider(s.getProvider()) == false) {
 180                 continue;
 181             }
 182             return new KeyAgreement(s, t, algorithm);
 183         }
 184         throw new NoSuchAlgorithmException
 185                                 ("Algorithm " + algorithm + " not available");
 186     }
 187 
 188     /**
 189      * Returns a {@code KeyAgreement} object that implements the
 190      * specified key agreement algorithm.
 191      *
 192      * <p> A new KeyAgreement object encapsulating the
 193      * KeyAgreementSpi implementation from the specified provider
 194      * is returned.  The specified provider must be registered
 195      * in the security provider list.
 196      *
 197      * <p> Note that the list of registered providers may be retrieved via
 198      * the {@link Security#getProviders() Security.getProviders()} method.
 199      *
 200      * @param algorithm the standard name of the requested key agreement
 201      * algorithm.
 202      * See the KeyAgreement section in the <a href=
 203      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
 204      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 205      * for information about standard algorithm names.
 206      *
 207      * @param provider the name of the provider.
 208      *
 209      * @return the new {@code KeyAgreement} object.
 210      *
 211      * @exception NullPointerException if the specified algorithm
 212      *          is null.
 213      *
 214      * @exception NoSuchAlgorithmException if a KeyAgreementSpi
 215      *          implementation for the specified algorithm is not
 216      *          available from the specified provider.
 217      *
 218      * @exception NoSuchProviderException if the specified provider is not
 219      *          registered in the security provider list.
 220      *
 221      * @exception IllegalArgumentException if the {@code provider}
 222      *          is null or empty.
 223      *
 224      * @see java.security.Provider
 225      */
 226     public static final KeyAgreement getInstance(String algorithm,
 227             String provider) throws NoSuchAlgorithmException,
 228             NoSuchProviderException {
 229         Instance instance = JceSecurity.getInstance
 230                 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
 231         return new KeyAgreement((KeyAgreementSpi)instance.impl,
 232                 instance.provider, algorithm);
 233     }
 234 
 235     /**
 236      * Returns a {@code KeyAgreement} object that implements the
 237      * specified key agreement algorithm.
 238      *
 239      * <p> A new KeyAgreement object encapsulating the
 240      * KeyAgreementSpi implementation from the specified Provider
 241      * object is returned.  Note that the specified Provider object
 242      * does not have to be registered in the provider list.
 243      *
 244      * @param algorithm the standard name of the requested key agreement
 245      * algorithm.
 246      * See the KeyAgreement section in the <a href=
 247      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
 248      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
 249      * for information about standard algorithm names.
 250      *
 251      * @param provider the provider.
 252      *
 253      * @return the new {@code KeyAgreement} object.
 254      *
 255      * @exception NullPointerException if the specified algorithm
 256      *          is null.
 257      *
 258      * @exception NoSuchAlgorithmException if a KeyAgreementSpi
 259      *          implementation for the specified algorithm is not available
 260      *          from the specified Provider object.
 261      *
 262      * @exception IllegalArgumentException if the {@code provider}
 263      *          is null.
 264      *
 265      * @see java.security.Provider
 266      */
 267     public static final KeyAgreement getInstance(String algorithm,
 268             Provider provider) throws NoSuchAlgorithmException {
 269         Instance instance = JceSecurity.getInstance
 270                 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
 271         return new KeyAgreement((KeyAgreementSpi)instance.impl,
 272                 instance.provider, algorithm);
 273     }
 274 
 275     // max number of debug warnings to print from chooseFirstProvider()
 276     private static int warnCount = 10;
 277 
 278     /**
 279      * Choose the Spi from the first provider available. Used if
 280      * delayed provider selection is not possible because init()
 281      * is not the first method called.
 282      */


 391                 }
 392             }
 393             // no working provider found, fail
 394             if (lastException instanceof InvalidKeyException) {
 395                 throw (InvalidKeyException)lastException;
 396             }
 397             if (lastException instanceof InvalidAlgorithmParameterException) {
 398                 throw (InvalidAlgorithmParameterException)lastException;
 399             }
 400             if (lastException instanceof RuntimeException) {
 401                 throw (RuntimeException)lastException;
 402             }
 403             String kName = (key != null) ? key.getClass().getName() : "(null)";
 404             throw new InvalidKeyException
 405                 ("No installed provider supports this key: "
 406                 + kName, lastException);
 407         }
 408     }
 409 
 410     /**
 411      * Returns the provider of this {@code KeyAgreement} object.
 412      *
 413      * @return the provider of this {@code KeyAgreement} object
 414      */
 415     public final Provider getProvider() {
 416         chooseFirstProvider();
 417         return this.provider;
 418     }
 419 
 420     /**
 421      * Initializes this key agreement with the given key, which is required to
 422      * contain all the algorithm parameters required for this key agreement.
 423      *
 424      * <p> If this key agreement requires any random bytes, it will get
 425      * them using the
 426      * {@link java.security.SecureRandom}
 427      * implementation of the highest-priority
 428      * installed provider as the source of randomness.
 429      * (If none of the installed providers supply an implementation of
 430      * SecureRandom, a system-provided source of randomness will be used.)
 431      *
 432      * @param key the party's private information. For example, in the case
 433      * of the Diffie-Hellman key agreement, this would be the party's own
 434      * Diffie-Hellman private key.
 435      *
 436      * @exception InvalidKeyException if the given key is
 437      * inappropriate for this key agreement, e.g., is of the wrong type or
 438      * has an incompatible algorithm type.
 439      */
 440     public final void init(Key key) throws InvalidKeyException {
 441         init(key, JceSecurity.RANDOM);
 442     }
 443 
 444     /**
 445      * Initializes this key agreement with the given key and source of
 446      * randomness. The given key is required to contain all the algorithm
 447      * parameters required for this key agreement.
 448      *
 449      * <p> If the key agreement algorithm requires random bytes, it gets them
 450      * from the given source of randomness, {@code random}.
 451      * However, if the underlying
 452      * algorithm implementation does not require any random bytes,
 453      * {@code random} is ignored.
 454      *
 455      * @param key the party's private information. For example, in the case
 456      * of the Diffie-Hellman key agreement, this would be the party's own
 457      * Diffie-Hellman private key.
 458      * @param random the source of randomness
 459      *
 460      * @exception InvalidKeyException if the given key is
 461      * inappropriate for this key agreement, e.g., is of the wrong type or
 462      * has an incompatible algorithm type.
 463      */
 464     public final void init(Key key, SecureRandom random)
 465             throws InvalidKeyException {
 466         if (spi != null) {
 467             spi.engineInit(key, random);
 468         } else {
 469             try {
 470                 chooseProvider(I_NO_PARAMS, key, null, random);
 471             } catch (InvalidAlgorithmParameterException e) {
 472                 // should never occur
 473                 throw new InvalidKeyException(e);


 553      * phase of this key agreement.
 554      *
 555      * @return the (intermediate) key resulting from this phase, or null
 556      * if this phase does not yield a key
 557      *
 558      * @exception InvalidKeyException if the given key is inappropriate for
 559      * this phase.
 560      * @exception IllegalStateException if this key agreement has not been
 561      * initialized.
 562      */
 563     public final Key doPhase(Key key, boolean lastPhase)
 564         throws InvalidKeyException, IllegalStateException
 565     {
 566         chooseFirstProvider();
 567         return spi.engineDoPhase(key, lastPhase);
 568     }
 569 
 570     /**
 571      * Generates the shared secret and returns it in a new buffer.
 572      *
 573      * <p>This method resets this {@code KeyAgreement} object, so that it
 574      * can be reused for further key agreements. Unless this key agreement is
 575      * reinitialized with one of the {@code init} methods, the same
 576      * private information and algorithm parameters will be used for
 577      * subsequent key agreements.
 578      *
 579      * @return the new buffer with the shared secret
 580      *
 581      * @exception IllegalStateException if this key agreement has not been
 582      * completed yet
 583      */
 584     public final byte[] generateSecret() throws IllegalStateException {
 585         chooseFirstProvider();
 586         return spi.engineGenerateSecret();
 587     }
 588 
 589     /**
 590      * Generates the shared secret, and places it into the buffer
 591      * {@code sharedSecret}, beginning at {@code offset} inclusive.
 592      *
 593      * <p>If the {@code sharedSecret} buffer is too small to hold the
 594      * result, a {@code ShortBufferException} is thrown.
 595      * In this case, this call should be repeated with a larger output buffer.
 596      *
 597      * <p>This method resets this {@code KeyAgreement} object, so that it
 598      * can be reused for further key agreements. Unless this key agreement is
 599      * reinitialized with one of the {@code init} methods, the same
 600      * private information and algorithm parameters will be used for
 601      * subsequent key agreements.
 602      *
 603      * @param sharedSecret the buffer for the shared secret
 604      * @param offset the offset in {@code sharedSecret} where the
 605      * shared secret will be stored
 606      *
 607      * @return the number of bytes placed into {@code sharedSecret}
 608      *
 609      * @exception IllegalStateException if this key agreement has not been
 610      * completed yet
 611      * @exception ShortBufferException if the given output buffer is too small
 612      * to hold the secret
 613      */
 614     public final int generateSecret(byte[] sharedSecret, int offset)
 615         throws IllegalStateException, ShortBufferException
 616     {
 617         chooseFirstProvider();
 618         return spi.engineGenerateSecret(sharedSecret, offset);
 619     }
 620 
 621     /**
 622      * Creates the shared secret and returns it as a {@code SecretKey}
 623      * object of the specified algorithm.
 624      *
 625      * <p>This method resets this {@code KeyAgreement} object, so that it
 626      * can be reused for further key agreements. Unless this key agreement is
 627      * reinitialized with one of the {@code init} methods, the same
 628      * private information and algorithm parameters will be used for
 629      * subsequent key agreements.
 630      *
 631      * @param algorithm the requested secret-key algorithm
 632      *
 633      * @return the shared secret key
 634      *
 635      * @exception IllegalStateException if this key agreement has not been
 636      * completed yet
 637      * @exception NoSuchAlgorithmException if the specified secret-key
 638      * algorithm is not available
 639      * @exception InvalidKeyException if the shared secret-key material cannot
 640      * be used to generate a secret key of the specified algorithm (e.g.,
 641      * the key material is too short)
 642      */
 643     public final SecretKey generateSecret(String algorithm)
 644         throws IllegalStateException, NoSuchAlgorithmException,
 645             InvalidKeyException
 646     {
 647         chooseFirstProvider();
< prev index next >