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(); |