1 /* 2 * Copyright (c) 1997, 2016, 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 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 81 private static final Debug pdebug = 82 Debug.getInstance("provider", "Provider"); 83 private static final boolean skipDebug = 84 Debug.isOn("engine=") && !Debug.isOn("keyagreement"); 85 86 // The provider 87 private Provider provider; 88 89 // The provider implementation (delegate) 90 private KeyAgreementSpi spi; 91 92 // The name of the key agreement algorithm. 93 private final String algorithm; 94 95 // next service to try in provider selection 96 // null once provider is selected 97 private Service firstService; 98 99 // remaining services to try in provider selection 100 // null once provider is selected 101 private Iterator<Service> serviceIterator; 102 103 private final Object lock; 104 105 /** 106 * Creates a KeyAgreement object. 107 * 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 * @implNote 154 * The JDK Reference Implementation additionally uses the 155 * {@code jdk.security.provider.preferred} 156 * {@link Security#getProperty(String) Security} property to determine 157 * the preferred provider order for the specified algorithm. This 158 * may be different than the order of providers returned by 159 * {@link Security#getProviders() Security.getProviders()}. 160 * 161 * @param algorithm the standard name of the requested key agreement 162 * algorithm. 163 * See the KeyAgreement section in the <a href= 164 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement"> 165 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 166 * for information about standard algorithm names. 167 * 168 * @return the new {@code KeyAgreement} object. 169 * 170 * @exception NullPointerException if the specified algorithm 171 * is null. 172 * 173 * @exception NoSuchAlgorithmException if no Provider supports a 174 * KeyAgreementSpi implementation for the 175 * specified algorithm. 176 * 177 * @see java.security.Provider 178 */ 179 public static final KeyAgreement getInstance(String algorithm) 180 throws NoSuchAlgorithmException { 181 List<Service> services = 182 GetInstance.getServices("KeyAgreement", algorithm); 183 // make sure there is at least one service from a signed provider 184 Iterator<Service> t = services.iterator(); 185 while (t.hasNext()) { 186 Service s = t.next(); 187 if (JceSecurity.canUseProvider(s.getProvider()) == false) { 188 continue; 189 } 190 return new KeyAgreement(s, t, algorithm); 191 } 192 throw new NoSuchAlgorithmException 193 ("Algorithm " + algorithm + " not available"); 194 } 195 196 /** 197 * Returns a {@code KeyAgreement} object that implements the 198 * specified key agreement algorithm. 199 * 200 * <p> A new KeyAgreement object encapsulating the 201 * KeyAgreementSpi implementation from the specified provider 202 * is returned. The specified provider must be registered 203 * in the security provider list. 204 * 205 * <p> Note that the list of registered providers may be retrieved via 206 * the {@link Security#getProviders() Security.getProviders()} method. 207 * 208 * @param algorithm the standard name of the requested key agreement 209 * algorithm. 210 * See the KeyAgreement section in the <a href= 211 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement"> 212 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 213 * for information about standard algorithm names. 214 * 215 * @param provider the name of the provider. 216 * 217 * @return the new {@code KeyAgreement} object. 218 * 219 * @exception NullPointerException if the specified algorithm 220 * is null. 221 * 222 * @exception NoSuchAlgorithmException if a KeyAgreementSpi 223 * implementation for the specified algorithm is not 224 * available from the specified provider. 225 * 226 * @exception NoSuchProviderException if the specified provider is not 227 * registered in the security provider list. 228 * 229 * @exception IllegalArgumentException if the {@code provider} 230 * is null or empty. 231 * 232 * @see java.security.Provider 233 */ 234 public static final KeyAgreement getInstance(String algorithm, 235 String provider) throws NoSuchAlgorithmException, 236 NoSuchProviderException { 237 Instance instance = JceSecurity.getInstance 238 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider); 239 return new KeyAgreement((KeyAgreementSpi)instance.impl, 240 instance.provider, algorithm); 241 } 242 243 /** 244 * Returns a {@code KeyAgreement} object that implements the 245 * specified key agreement algorithm. 246 * 247 * <p> A new KeyAgreement object encapsulating the 248 * KeyAgreementSpi implementation from the specified Provider 249 * object is returned. Note that the specified Provider object 250 * does not have to be registered in the provider list. 251 * 252 * @param algorithm the standard name of the requested key agreement 253 * algorithm. 254 * See the KeyAgreement section in the <a href= 255 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement"> 256 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 257 * for information about standard algorithm names. 258 * 259 * @param provider the provider. 260 * 261 * @return the new {@code KeyAgreement} object. 262 * 263 * @exception NullPointerException if the specified algorithm 264 * is null. 265 * 266 * @exception NoSuchAlgorithmException if a KeyAgreementSpi 267 * implementation for the specified algorithm is not available 268 * from the specified Provider object. 269 * 270 * @exception IllegalArgumentException if the {@code provider} 271 * is null. 272 * 273 * @see java.security.Provider 274 */ 275 public static final KeyAgreement getInstance(String algorithm, 276 Provider provider) throws NoSuchAlgorithmException { 277 Instance instance = JceSecurity.getInstance 278 ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider); 279 return new KeyAgreement((KeyAgreementSpi)instance.impl, 280 instance.provider, algorithm); 281 } 282 283 // max number of debug warnings to print from chooseFirstProvider() 284 private static int warnCount = 10; 285 286 /** 287 * Choose the Spi from the first provider available. Used if 288 * delayed provider selection is not possible because init() 289 * is not the first method called. 290 */ 291 void chooseFirstProvider() { 292 if (spi != null) { 293 return; 294 } 295 synchronized (lock) { 296 if (spi != null) { 297 return; 298 } 299 if (debug != null) { 300 int w = --warnCount; 301 if (w >= 0) { 302 debug.println("KeyAgreement.init() not first method " 303 + "called, disabling delayed provider selection"); 304 if (w == 0) { 305 debug.println("Further warnings of this type will " 306 + "be suppressed"); 307 } 308 new Exception("Call trace").printStackTrace(); 309 } 310 } 311 Exception lastException = null; 312 while ((firstService != null) || serviceIterator.hasNext()) { 313 Service s; 314 if (firstService != null) { 315 s = firstService; 316 firstService = null; 317 } else { 318 s = serviceIterator.next(); 319 } 320 if (JceSecurity.canUseProvider(s.getProvider()) == false) { 321 continue; 322 } 323 try { 324 Object obj = s.newInstance(null); 325 if (obj instanceof KeyAgreementSpi == false) { 326 continue; 327 } 328 spi = (KeyAgreementSpi)obj; 329 provider = s.getProvider(); 330 // not needed any more 331 firstService = null; 332 serviceIterator = null; 333 return; 334 } catch (Exception e) { 335 lastException = e; 336 } 337 } 338 ProviderException e = new ProviderException 339 ("Could not construct KeyAgreementSpi instance"); 340 if (lastException != null) { 341 e.initCause(lastException); 342 } 343 throw e; 344 } 345 } 346 347 private static final int I_NO_PARAMS = 1; 348 private static final int I_PARAMS = 2; 349 350 private void implInit(KeyAgreementSpi spi, int type, Key key, 351 AlgorithmParameterSpec params, SecureRandom random) 352 throws InvalidKeyException, InvalidAlgorithmParameterException { 353 if (type == I_NO_PARAMS) { 354 spi.engineInit(key, random); 355 } else { // I_PARAMS 356 spi.engineInit(key, params, random); 357 } 358 } 359 360 private void chooseProvider(int initType, Key key, 361 AlgorithmParameterSpec params, SecureRandom random) 362 throws InvalidKeyException, InvalidAlgorithmParameterException { 363 synchronized (lock) { 364 if (spi != null) { 365 implInit(spi, initType, key, params, random); 366 return; 367 } 368 Exception lastException = null; 369 while ((firstService != null) || serviceIterator.hasNext()) { 370 Service s; 371 if (firstService != null) { 372 s = firstService; 373 firstService = null; 374 } else { 375 s = serviceIterator.next(); 376 } 377 // if provider says it does not support this key, ignore it 378 if (s.supportsParameter(key) == false) { 379 continue; 380 } 381 if (JceSecurity.canUseProvider(s.getProvider()) == false) { 382 continue; 383 } 384 try { 385 KeyAgreementSpi spi = (KeyAgreementSpi)s.newInstance(null); 386 implInit(spi, initType, key, params, random); 387 provider = s.getProvider(); 388 this.spi = spi; 389 firstService = null; 390 serviceIterator = null; 391 return; 392 } catch (Exception e) { 393 // NoSuchAlgorithmException from newInstance() 394 // InvalidKeyException from init() 395 // RuntimeException (ProviderException) from init() 396 if (lastException == null) { 397 lastException = e; 398 } 399 } 400 } 401 // no working provider found, fail 402 if (lastException instanceof InvalidKeyException) { 403 throw (InvalidKeyException)lastException; 404 } 405 if (lastException instanceof InvalidAlgorithmParameterException) { 406 throw (InvalidAlgorithmParameterException)lastException; 407 } 408 if (lastException instanceof RuntimeException) { 409 throw (RuntimeException)lastException; 410 } 411 String kName = (key != null) ? key.getClass().getName() : "(null)"; 412 throw new InvalidKeyException 413 ("No installed provider supports this key: " 414 + kName, lastException); 415 } 416 } 417 418 /** 419 * Returns the provider of this {@code KeyAgreement} object. 420 * 421 * @return the provider of this {@code KeyAgreement} object 422 */ 423 public final Provider getProvider() { 424 chooseFirstProvider(); 425 return this.provider; 426 } 427 428 /** 429 * Initializes this key agreement with the given key, which is required to 430 * contain all the algorithm parameters required for this key agreement. 431 * 432 * <p> If this key agreement requires any random bytes, it will get 433 * them using the 434 * {@link java.security.SecureRandom} 435 * implementation of the highest-priority 436 * installed provider as the source of randomness. 437 * (If none of the installed providers supply an implementation of 438 * SecureRandom, a system-provided source of randomness will be used.) 439 * 440 * @param key the party's private information. For example, in the case 441 * of the Diffie-Hellman key agreement, this would be the party's own 442 * Diffie-Hellman private key. 443 * 444 * @exception InvalidKeyException if the given key is 445 * inappropriate for this key agreement, e.g., is of the wrong type or 446 * has an incompatible algorithm type. 447 */ 448 public final void init(Key key) throws InvalidKeyException { 449 init(key, JceSecurity.RANDOM); 450 } 451 452 /** 453 * Initializes this key agreement with the given key and source of 454 * randomness. The given key is required to contain all the algorithm 455 * parameters required for this key agreement. 456 * 457 * <p> If the key agreement algorithm requires random bytes, it gets them 458 * from the given source of randomness, {@code random}. 459 * However, if the underlying 460 * algorithm implementation does not require any random bytes, 461 * {@code random} is ignored. 462 * 463 * @param key the party's private information. For example, in the case 464 * of the Diffie-Hellman key agreement, this would be the party's own 465 * Diffie-Hellman private key. 466 * @param random the source of randomness 467 * 468 * @exception InvalidKeyException if the given key is 469 * inappropriate for this key agreement, e.g., is of the wrong type or 470 * has an incompatible algorithm type. 471 */ 472 public final void init(Key key, SecureRandom random) 473 throws InvalidKeyException { 474 if (spi != null) { 475 spi.engineInit(key, random); 476 } else { 477 try { 478 chooseProvider(I_NO_PARAMS, key, null, random); 479 } catch (InvalidAlgorithmParameterException e) { 480 // should never occur 481 throw new InvalidKeyException(e); 482 } 483 } 484 485 if (!skipDebug && pdebug != null) { 486 pdebug.println("KeyAgreement." + algorithm + " algorithm from: " + 487 this.provider.getName()); 488 } 489 } 490 491 /** 492 * Initializes this key agreement with the given key and set of 493 * algorithm parameters. 494 * 495 * <p> If this key agreement requires any random bytes, it will get 496 * them using the 497 * {@link java.security.SecureRandom} 498 * implementation of the highest-priority 499 * installed provider as the source of randomness. 500 * (If none of the installed providers supply an implementation of 501 * SecureRandom, a system-provided source of randomness will be used.) 502 * 503 * @param key the party's private information. For example, in the case 504 * of the Diffie-Hellman key agreement, this would be the party's own 505 * Diffie-Hellman private key. 506 * @param params the key agreement parameters 507 * 508 * @exception InvalidKeyException if the given key is 509 * inappropriate for this key agreement, e.g., is of the wrong type or 510 * has an incompatible algorithm type. 511 * @exception InvalidAlgorithmParameterException if the given parameters 512 * are inappropriate for this key agreement. 513 */ 514 public final void init(Key key, AlgorithmParameterSpec params) 515 throws InvalidKeyException, InvalidAlgorithmParameterException 516 { 517 init(key, params, JceSecurity.RANDOM); 518 } 519 520 /** 521 * Initializes this key agreement with the given key, set of 522 * algorithm parameters, and source of randomness. 523 * 524 * @param key the party's private information. For example, in the case 525 * of the Diffie-Hellman key agreement, this would be the party's own 526 * Diffie-Hellman private key. 527 * @param params the key agreement parameters 528 * @param random the source of randomness 529 * 530 * @exception InvalidKeyException if the given key is 531 * inappropriate for this key agreement, e.g., is of the wrong type or 532 * has an incompatible algorithm type. 533 * @exception InvalidAlgorithmParameterException if the given parameters 534 * are inappropriate for this key agreement. 535 */ 536 public final void init(Key key, AlgorithmParameterSpec params, 537 SecureRandom random) 538 throws InvalidKeyException, InvalidAlgorithmParameterException 539 { 540 if (spi != null) { 541 spi.engineInit(key, params, random); 542 } else { 543 chooseProvider(I_PARAMS, key, params, random); 544 } 545 546 if (!skipDebug && pdebug != null) { 547 pdebug.println("KeyAgreement." + algorithm + " algorithm from: " + 548 this.provider.getName()); 549 } 550 } 551 552 /** 553 * Executes the next phase of this key agreement with the given 554 * key that was received from one of the other parties involved in this key 555 * agreement. 556 * 557 * @param key the key for this phase. For example, in the case of 558 * Diffie-Hellman between 2 parties, this would be the other party's 559 * Diffie-Hellman public key. 560 * @param lastPhase flag which indicates whether or not this is the last 561 * phase of this key agreement. 562 * 563 * @return the (intermediate) key resulting from this phase, or null 564 * if this phase does not yield a key 565 * 566 * @exception InvalidKeyException if the given key is inappropriate for 567 * this phase. 568 * @exception IllegalStateException if this key agreement has not been 569 * initialized. 570 */ 571 public final Key doPhase(Key key, boolean lastPhase) 572 throws InvalidKeyException, IllegalStateException 573 { 574 chooseFirstProvider(); 575 return spi.engineDoPhase(key, lastPhase); 576 } 577 578 /** 579 * Generates the shared secret and returns it in a new buffer. 580 * 581 * <p>This method resets this {@code KeyAgreement} object, so that it 582 * can be reused for further key agreements. Unless this key agreement is 583 * reinitialized with one of the {@code init} methods, the same 584 * private information and algorithm parameters will be used for 585 * subsequent key agreements. 586 * 587 * @return the new buffer with the shared secret 588 * 589 * @exception IllegalStateException if this key agreement has not been 590 * completed yet 591 */ 592 public final byte[] generateSecret() throws IllegalStateException { 593 chooseFirstProvider(); 594 return spi.engineGenerateSecret(); 595 } 596 597 /** 598 * Generates the shared secret, and places it into the buffer 599 * {@code sharedSecret}, beginning at {@code offset} inclusive. 600 * 601 * <p>If the {@code sharedSecret} buffer is too small to hold the 602 * result, a {@code ShortBufferException} is thrown. 603 * In this case, this call should be repeated with a larger output buffer. 604 * 605 * <p>This method resets this {@code KeyAgreement} object, so that it 606 * can be reused for further key agreements. Unless this key agreement is 607 * reinitialized with one of the {@code init} methods, the same 608 * private information and algorithm parameters will be used for 609 * subsequent key agreements. 610 * 611 * @param sharedSecret the buffer for the shared secret 612 * @param offset the offset in {@code sharedSecret} where the 613 * shared secret will be stored 614 * 615 * @return the number of bytes placed into {@code sharedSecret} 616 * 617 * @exception IllegalStateException if this key agreement has not been 618 * completed yet 619 * @exception ShortBufferException if the given output buffer is too small 620 * to hold the secret 621 */ 622 public final int generateSecret(byte[] sharedSecret, int offset) 623 throws IllegalStateException, ShortBufferException 624 { 625 chooseFirstProvider(); 626 return spi.engineGenerateSecret(sharedSecret, offset); 627 } 628 629 /** 630 * Creates the shared secret and returns it as a {@code SecretKey} 631 * object of the specified algorithm. 632 * 633 * <p>This method resets this {@code KeyAgreement} object, so that it 634 * can be reused for further key agreements. Unless this key agreement is 635 * reinitialized with one of the {@code init} methods, the same 636 * private information and algorithm parameters will be used for 637 * subsequent key agreements. 638 * 639 * @param algorithm the requested secret-key algorithm 640 * 641 * @return the shared secret key 642 * 643 * @exception IllegalStateException if this key agreement has not been 644 * completed yet 645 * @exception NoSuchAlgorithmException if the specified secret-key 646 * algorithm is not available 647 * @exception InvalidKeyException if the shared secret-key material cannot 648 * be used to generate a secret key of the specified algorithm (e.g., 649 * the key material is too short) 650 */ 651 public final SecretKey generateSecret(String algorithm) 652 throws IllegalStateException, NoSuchAlgorithmException, 653 InvalidKeyException 654 { 655 chooseFirstProvider(); 656 return spi.engineGenerateSecret(algorithm); 657 } 658 }