1 /* 2 * Copyright (c) 1997, 2014, 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.util.*; 29 30 import java.security.spec.AlgorithmParameterSpec; 31 32 import java.security.Provider.Service; 33 34 import sun.security.jca.*; 35 import sun.security.jca.GetInstance.Instance; 36 37 /* 38 Android-removed: this debugging mechanism is not supported in Android. 39 import sun.security.util.Debug; 40 */ 41 42 /** 43 * The KeyPairGenerator class is used to generate pairs of 44 * public and private keys. Key pair generators are constructed using the 45 * {@code getInstance} factory methods (static methods that 46 * return instances of a given class). 47 * 48 * <p>A Key pair generator for a particular algorithm creates a public/private 49 * key pair that can be used with this algorithm. It also associates 50 * algorithm-specific parameters with each of the generated keys. 51 * 52 * <p>There are two ways to generate a key pair: in an algorithm-independent 53 * manner, and in an algorithm-specific manner. 54 * The only difference between the two is the initialization of the object: 55 * 56 * <ul> 57 * <li><b>Algorithm-Independent Initialization</b> 58 * <p>All key pair generators share the concepts of a keysize and a 59 * source of randomness. The keysize is interpreted differently for different 60 * algorithms (e.g., in the case of the <i>DSA</i> algorithm, the keysize 61 * corresponds to the length of the modulus). 62 * There is an 63 * {@link #initialize(int, java.security.SecureRandom) initialize} 64 * method in this KeyPairGenerator class that takes these two universally 65 * shared types of arguments. There is also one that takes just a 66 * {@code keysize} argument, and uses the {@code SecureRandom} 67 * implementation of the highest-priority installed provider as the source 68 * of randomness. (If none of the installed providers supply an implementation 69 * of {@code SecureRandom}, a system-provided source of randomness is 70 * used.) 71 * 72 * <p>Since no other parameters are specified when you call the above 73 * algorithm-independent {@code initialize} methods, it is up to the 74 * provider what to do about the algorithm-specific parameters (if any) to be 75 * associated with each of the keys. 76 * 77 * <p>If the algorithm is the <i>DSA</i> algorithm, and the keysize (modulus 78 * size) is 512, 768, or 1024, then the <i>Sun</i> provider uses a set of 79 * precomputed values for the {@code p}, {@code q}, and 80 * {@code g} parameters. If the modulus size is not one of the above 81 * values, the <i>Sun</i> provider creates a new set of parameters. Other 82 * providers might have precomputed parameter sets for more than just the 83 * three modulus sizes mentioned above. Still others might not have a list of 84 * precomputed parameters at all and instead always create new parameter sets. 85 * 86 * <li><b>Algorithm-Specific Initialization</b> 87 * <p>For situations where a set of algorithm-specific parameters already 88 * exists (e.g., so-called <i>community parameters</i> in DSA), there are two 89 * {@link #initialize(java.security.spec.AlgorithmParameterSpec) 90 * initialize} methods that have an {@code AlgorithmParameterSpec} 91 * argument. One also has a {@code SecureRandom} argument, while the 92 * the other uses the {@code SecureRandom} 93 * implementation of the highest-priority installed provider as the source 94 * of randomness. (If none of the installed providers supply an implementation 95 * of {@code SecureRandom}, a system-provided source of randomness is 96 * used.) 97 * </ul> 98 * 99 * <p>In case the client does not explicitly initialize the KeyPairGenerator 100 * (via a call to an {@code initialize} method), each provider must 101 * supply (and document) a default initialization. 102 * For example, the <i>Sun</i> provider uses a default modulus size (keysize) 103 * of 1024 bits. 104 * 105 * <p>Note that this class is abstract and extends from 106 * {@code KeyPairGeneratorSpi} for historical reasons. 107 * Application developers should only take notice of the methods defined in 108 * this {@code KeyPairGenerator} class; all the methods in 109 * the superclass are intended for cryptographic service providers who wish to 110 * supply their own implementations of key pair generators. 111 * 112 * <p> Android provides the following <code>KeyPairGenerator</code> algorithms: 113 * <table> 114 * <thead> 115 * <tr> 116 * <th>Algorithm</th> 117 * <th>Supported API Levels</th> 118 * </tr> 119 * </thead> 120 * <tbody> 121 * <tr> 122 * <td>DH</td> 123 * <td>1+</td> 124 * </tr> 125 * <tr> 126 * <td>DSA</td> 127 * <td>1+</td> 128 * </tr> 129 * <tr> 130 * <td>EC</td> 131 * <td>11+</td> 132 * </tr> 133 * <tr> 134 * <td>RSA</td> 135 * <td>1+</td> 136 * </tr> 137 * </tbody> 138 * </table> 139 * 140 * These algorithms are described in the <a href= 141 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator"> 142 * KeyPairGenerator section</a> of the 143 * Java Cryptography Architecture Standard Algorithm Name Documentation. 144 * 145 * @author Benjamin Renaud 146 * 147 * @see java.security.spec.AlgorithmParameterSpec 148 */ 149 150 public abstract class KeyPairGenerator extends KeyPairGeneratorSpi { 151 152 /* 153 Android-removed: this debugging mechanism is not supported in Android. 154 private static final Debug pdebug = 155 Debug.getInstance("provider", "Provider"); 156 private static final boolean skipDebug = 157 Debug.isOn("engine=") && !Debug.isOn("keypairgenerator"); 158 */ 159 160 private final String algorithm; 161 162 // The provider 163 Provider provider; 164 165 /** 166 * Creates a KeyPairGenerator object for the specified algorithm. 167 * 168 * @param algorithm the standard string name of the algorithm. 169 * See the KeyPairGenerator section in the <a href= 170 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator"> 171 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 172 * for information about standard algorithm names. 173 */ KeyPairGenerator(String algorithm)174 protected KeyPairGenerator(String algorithm) { 175 this.algorithm = algorithm; 176 } 177 178 /** 179 * Returns the standard name of the algorithm for this key pair generator. 180 * See the KeyPairGenerator section in the <a href= 181 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator"> 182 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 183 * for information about standard algorithm names. 184 * 185 * @return the standard string name of the algorithm. 186 */ getAlgorithm()187 public String getAlgorithm() { 188 return this.algorithm; 189 } 190 getInstance(Instance instance, String algorithm)191 private static KeyPairGenerator getInstance(Instance instance, 192 String algorithm) { 193 KeyPairGenerator kpg; 194 if (instance.impl instanceof KeyPairGenerator) { 195 kpg = (KeyPairGenerator)instance.impl; 196 } else { 197 KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)instance.impl; 198 kpg = new Delegate(spi, algorithm); 199 } 200 kpg.provider = instance.provider; 201 202 /* 203 Android-removed: this debugging mechanism is not supported in Android. 204 if (!skipDebug && pdebug != null) { 205 pdebug.println("KeyPairGenerator." + algorithm + 206 " algorithm from: " + kpg.provider.getName()); 207 } 208 */ 209 210 return kpg; 211 } 212 213 /** 214 * Returns a KeyPairGenerator object that generates public/private 215 * key pairs for the specified algorithm. 216 * 217 * <p> This method traverses the list of registered security Providers, 218 * starting with the most preferred Provider. 219 * A new KeyPairGenerator object encapsulating the 220 * KeyPairGeneratorSpi implementation from the first 221 * Provider that supports the specified algorithm is returned. 222 * 223 * <p> Note that the list of registered providers may be retrieved via 224 * the {@link Security#getProviders() Security.getProviders()} method. 225 * 226 * @param algorithm the standard string name of the algorithm. 227 * See the KeyPairGenerator section in the <a href= 228 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator"> 229 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 230 * for information about standard algorithm names. 231 * 232 * @return the new KeyPairGenerator object. 233 * 234 * @exception NoSuchAlgorithmException if no Provider supports a 235 * KeyPairGeneratorSpi implementation for the 236 * specified algorithm. 237 * 238 * @see Provider 239 */ getInstance(String algorithm)240 public static KeyPairGenerator getInstance(String algorithm) 241 throws NoSuchAlgorithmException { 242 List<Service> list = 243 GetInstance.getServices("KeyPairGenerator", algorithm); 244 Iterator<Service> t = list.iterator(); 245 if (t.hasNext() == false) { 246 throw new NoSuchAlgorithmException 247 (algorithm + " KeyPairGenerator not available"); 248 } 249 // find a working Spi or KeyPairGenerator subclass 250 NoSuchAlgorithmException failure = null; 251 do { 252 Service s = t.next(); 253 try { 254 Instance instance = 255 GetInstance.getInstance(s, KeyPairGeneratorSpi.class); 256 if (instance.impl instanceof KeyPairGenerator) { 257 return getInstance(instance, algorithm); 258 } else { 259 return new Delegate(instance, t, algorithm); 260 } 261 } catch (NoSuchAlgorithmException e) { 262 if (failure == null) { 263 failure = e; 264 } 265 } 266 } while (t.hasNext()); 267 throw failure; 268 } 269 270 /** 271 * Returns a KeyPairGenerator object that generates public/private 272 * key pairs for the specified algorithm. 273 * 274 * <p> A new KeyPairGenerator object encapsulating the 275 * KeyPairGeneratorSpi implementation from the specified provider 276 * is returned. The specified provider must be registered 277 * in the security provider list. 278 * 279 * <p> Note that the list of registered providers may be retrieved via 280 * the {@link Security#getProviders() Security.getProviders()} method. 281 * 282 * @param algorithm the standard string name of the algorithm. 283 * See the KeyPairGenerator section in the <a href= 284 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator"> 285 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 286 * for information about standard algorithm names. 287 * 288 * @param provider the string name of the provider. 289 * 290 * @return the new KeyPairGenerator object. 291 * 292 * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi 293 * implementation for the specified algorithm is not 294 * available from the specified provider. 295 * 296 * @exception NoSuchProviderException if the specified provider is not 297 * registered in the security provider list. 298 * 299 * @exception IllegalArgumentException if the provider name is null 300 * or empty. 301 * 302 * @see Provider 303 */ getInstance(String algorithm, String provider)304 public static KeyPairGenerator getInstance(String algorithm, 305 String provider) 306 throws NoSuchAlgorithmException, NoSuchProviderException { 307 Instance instance = GetInstance.getInstance("KeyPairGenerator", 308 KeyPairGeneratorSpi.class, algorithm, provider); 309 return getInstance(instance, algorithm); 310 } 311 312 /** 313 * Returns a KeyPairGenerator object that generates public/private 314 * key pairs for the specified algorithm. 315 * 316 * <p> A new KeyPairGenerator object encapsulating the 317 * KeyPairGeneratorSpi implementation from the specified Provider 318 * object is returned. Note that the specified Provider object 319 * does not have to be registered in the provider list. 320 * 321 * @param algorithm the standard string name of the algorithm. 322 * See the KeyPairGenerator section in the <a href= 323 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#KeyPairGenerator"> 324 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 325 * for information about standard algorithm names. 326 * 327 * @param provider the provider. 328 * 329 * @return the new KeyPairGenerator object. 330 * 331 * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi 332 * implementation for the specified algorithm is not available 333 * from the specified Provider object. 334 * 335 * @exception IllegalArgumentException if the specified provider is null. 336 * 337 * @see Provider 338 * 339 * @since 1.4 340 */ getInstance(String algorithm, Provider provider)341 public static KeyPairGenerator getInstance(String algorithm, 342 Provider provider) throws NoSuchAlgorithmException { 343 Instance instance = GetInstance.getInstance("KeyPairGenerator", 344 KeyPairGeneratorSpi.class, algorithm, provider); 345 return getInstance(instance, algorithm); 346 } 347 348 /** 349 * Returns the provider of this key pair generator object. 350 * 351 * @return the provider of this key pair generator object 352 */ getProvider()353 public final Provider getProvider() { 354 disableFailover(); 355 return this.provider; 356 } 357 disableFailover()358 void disableFailover() { 359 // empty, overridden in Delegate 360 } 361 362 /** 363 * Initializes the key pair generator for a certain keysize using 364 * a default parameter set and the {@code SecureRandom} 365 * implementation of the highest-priority installed provider as the source 366 * of randomness. 367 * (If none of the installed providers supply an implementation of 368 * {@code SecureRandom}, a system-provided source of randomness is 369 * used.) 370 * 371 * @param keysize the keysize. This is an 372 * algorithm-specific metric, such as modulus length, specified in 373 * number of bits. 374 * 375 * @exception InvalidParameterException if the {@code keysize} is not 376 * supported by this KeyPairGenerator object. 377 */ initialize(int keysize)378 public void initialize(int keysize) { 379 initialize(keysize, JCAUtil.getSecureRandom()); 380 } 381 382 /** 383 * Initializes the key pair generator for a certain keysize with 384 * the given source of randomness (and a default parameter set). 385 * 386 * @param keysize the keysize. This is an 387 * algorithm-specific metric, such as modulus length, specified in 388 * number of bits. 389 * @param random the source of randomness. 390 * 391 * @exception InvalidParameterException if the {@code keysize} is not 392 * supported by this KeyPairGenerator object. 393 * 394 * @since 1.2 395 */ initialize(int keysize, SecureRandom random)396 public void initialize(int keysize, SecureRandom random) { 397 // This does nothing, because either 398 // 1. the implementation object returned by getInstance() is an 399 // instance of KeyPairGenerator which has its own 400 // initialize(keysize, random) method, so the application would 401 // be calling that method directly, or 402 // 2. the implementation returned by getInstance() is an instance 403 // of Delegate, in which case initialize(keysize, random) is 404 // overridden to call the corresponding SPI method. 405 // (This is a special case, because the API and SPI method have the 406 // same name.) 407 } 408 409 /** 410 * Initializes the key pair generator using the specified parameter 411 * set and the {@code SecureRandom} 412 * implementation of the highest-priority installed provider as the source 413 * of randomness. 414 * (If none of the installed providers supply an implementation of 415 * {@code SecureRandom}, a system-provided source of randomness is 416 * used.). 417 * 418 * <p>This concrete method has been added to this previously-defined 419 * abstract class. 420 * This method calls the KeyPairGeneratorSpi 421 * {@link KeyPairGeneratorSpi#initialize( 422 * java.security.spec.AlgorithmParameterSpec, 423 * java.security.SecureRandom) initialize} method, 424 * passing it {@code params} and a source of randomness (obtained 425 * from the highest-priority installed provider or system-provided if none 426 * of the installed providers supply one). 427 * That {@code initialize} method always throws an 428 * UnsupportedOperationException if it is not overridden by the provider. 429 * 430 * @param params the parameter set used to generate the keys. 431 * 432 * @exception InvalidAlgorithmParameterException if the given parameters 433 * are inappropriate for this key pair generator. 434 * 435 * @since 1.2 436 */ initialize(AlgorithmParameterSpec params)437 public void initialize(AlgorithmParameterSpec params) 438 throws InvalidAlgorithmParameterException { 439 initialize(params, JCAUtil.getSecureRandom()); 440 } 441 442 /** 443 * Initializes the key pair generator with the given parameter 444 * set and source of randomness. 445 * 446 * <p>This concrete method has been added to this previously-defined 447 * abstract class. 448 * This method calls the KeyPairGeneratorSpi {@link 449 * KeyPairGeneratorSpi#initialize( 450 * java.security.spec.AlgorithmParameterSpec, 451 * java.security.SecureRandom) initialize} method, 452 * passing it {@code params} and {@code random}. 453 * That {@code initialize} 454 * method always throws an 455 * UnsupportedOperationException if it is not overridden by the provider. 456 * 457 * @param params the parameter set used to generate the keys. 458 * @param random the source of randomness. 459 * 460 * @exception InvalidAlgorithmParameterException if the given parameters 461 * are inappropriate for this key pair generator. 462 * 463 * @since 1.2 464 */ initialize(AlgorithmParameterSpec params, SecureRandom random)465 public void initialize(AlgorithmParameterSpec params, 466 SecureRandom random) 467 throws InvalidAlgorithmParameterException 468 { 469 // This does nothing, because either 470 // 1. the implementation object returned by getInstance() is an 471 // instance of KeyPairGenerator which has its own 472 // initialize(params, random) method, so the application would 473 // be calling that method directly, or 474 // 2. the implementation returned by getInstance() is an instance 475 // of Delegate, in which case initialize(params, random) is 476 // overridden to call the corresponding SPI method. 477 // (This is a special case, because the API and SPI method have the 478 // same name.) 479 } 480 481 /** 482 * Generates a key pair. 483 * 484 * <p>If this KeyPairGenerator has not been initialized explicitly, 485 * provider-specific defaults will be used for the size and other 486 * (algorithm-specific) values of the generated keys. 487 * 488 * <p>This will generate a new key pair every time it is called. 489 * 490 * <p>This method is functionally equivalent to 491 * {@link #generateKeyPair() generateKeyPair}. 492 * 493 * @return the generated key pair 494 * 495 * @since 1.2 496 */ genKeyPair()497 public final KeyPair genKeyPair() { 498 return generateKeyPair(); 499 } 500 501 /** 502 * Generates a key pair. 503 * 504 * <p>If this KeyPairGenerator has not been initialized explicitly, 505 * provider-specific defaults will be used for the size and other 506 * (algorithm-specific) values of the generated keys. 507 * 508 * <p>This will generate a new key pair every time it is called. 509 * 510 * <p>This method is functionally equivalent to 511 * {@link #genKeyPair() genKeyPair}. 512 * 513 * @return the generated key pair 514 */ generateKeyPair()515 public KeyPair generateKeyPair() { 516 // This does nothing (except returning null), because either: 517 // 518 // 1. the implementation object returned by getInstance() is an 519 // instance of KeyPairGenerator which has its own implementation 520 // of generateKeyPair (overriding this one), so the application 521 // would be calling that method directly, or 522 // 523 // 2. the implementation returned by getInstance() is an instance 524 // of Delegate, in which case generateKeyPair is 525 // overridden to invoke the corresponding SPI method. 526 // 527 // (This is a special case, because in JDK 1.1.x the generateKeyPair 528 // method was used both as an API and a SPI method.) 529 return null; 530 } 531 532 533 /* 534 * The following class allows providers to extend from KeyPairGeneratorSpi 535 * rather than from KeyPairGenerator. It represents a KeyPairGenerator 536 * with an encapsulated, provider-supplied SPI object (of type 537 * KeyPairGeneratorSpi). 538 * If the provider implementation is an instance of KeyPairGeneratorSpi, 539 * the getInstance() methods above return an instance of this class, with 540 * the SPI object encapsulated. 541 * 542 * Note: All SPI methods from the original KeyPairGenerator class have been 543 * moved up the hierarchy into a new class (KeyPairGeneratorSpi), which has 544 * been interposed in the hierarchy between the API (KeyPairGenerator) 545 * and its original parent (Object). 546 */ 547 548 // 549 // error failover notes: 550 // 551 // . we failover if the implementation throws an error during init 552 // by retrying the init on other providers 553 // 554 // . we also failover if the init succeeded but the subsequent call 555 // to generateKeyPair() fails. In order for this to work, we need 556 // to remember the parameters to the last successful call to init 557 // and initialize() the next spi using them. 558 // 559 // . although not specified, KeyPairGenerators could be thread safe, 560 // so we make sure we do not interfere with that 561 // 562 // . failover is not available, if: 563 // . getInstance(algorithm, provider) was used 564 // . a provider extends KeyPairGenerator rather than 565 // KeyPairGeneratorSpi (JDK 1.1 style) 566 // . once getProvider() is called 567 // 568 569 private static final class Delegate extends KeyPairGenerator { 570 571 // The provider implementation (delegate) 572 private volatile KeyPairGeneratorSpi spi; 573 574 private final Object lock = new Object(); 575 576 private Iterator<Service> serviceIterator; 577 578 private final static int I_NONE = 1; 579 private final static int I_SIZE = 2; 580 private final static int I_PARAMS = 3; 581 582 private int initType; 583 private int initKeySize; 584 private AlgorithmParameterSpec initParams; 585 private SecureRandom initRandom; 586 587 // constructor Delegate(KeyPairGeneratorSpi spi, String algorithm)588 Delegate(KeyPairGeneratorSpi spi, String algorithm) { 589 super(algorithm); 590 this.spi = spi; 591 } 592 Delegate(Instance instance, Iterator<Service> serviceIterator, String algorithm)593 Delegate(Instance instance, Iterator<Service> serviceIterator, 594 String algorithm) { 595 super(algorithm); 596 spi = (KeyPairGeneratorSpi)instance.impl; 597 provider = instance.provider; 598 this.serviceIterator = serviceIterator; 599 initType = I_NONE; 600 601 /* 602 Android-removed: this debugging mechanism is not supported in Android. 603 if (!skipDebug && pdebug != null) { 604 pdebug.println("KeyPairGenerator." + algorithm + 605 " algorithm from: " + provider.getName()); 606 } 607 */ 608 } 609 610 /** 611 * Update the active spi of this class and return the next 612 * implementation for failover. If no more implemenations are 613 * available, this method returns null. However, the active spi of 614 * this class is never set to null. 615 */ nextSpi(KeyPairGeneratorSpi oldSpi, boolean reinit)616 private KeyPairGeneratorSpi nextSpi(KeyPairGeneratorSpi oldSpi, 617 boolean reinit) { 618 synchronized (lock) { 619 // somebody else did a failover concurrently 620 // try that spi now 621 if ((oldSpi != null) && (oldSpi != spi)) { 622 return spi; 623 } 624 if (serviceIterator == null) { 625 return null; 626 } 627 while (serviceIterator.hasNext()) { 628 Service s = serviceIterator.next(); 629 try { 630 Object inst = s.newInstance(null); 631 // ignore non-spis 632 if (inst instanceof KeyPairGeneratorSpi == false) { 633 continue; 634 } 635 if (inst instanceof KeyPairGenerator) { 636 continue; 637 } 638 KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)inst; 639 if (reinit) { 640 if (initType == I_SIZE) { 641 spi.initialize(initKeySize, initRandom); 642 } else if (initType == I_PARAMS) { 643 spi.initialize(initParams, initRandom); 644 } else if (initType != I_NONE) { 645 throw new AssertionError 646 ("KeyPairGenerator initType: " + initType); 647 } 648 } 649 provider = s.getProvider(); 650 this.spi = spi; 651 return spi; 652 } catch (Exception e) { 653 // ignore 654 } 655 } 656 disableFailover(); 657 return null; 658 } 659 } 660 disableFailover()661 void disableFailover() { 662 serviceIterator = null; 663 initType = 0; 664 initParams = null; 665 initRandom = null; 666 } 667 668 // engine method initialize(int keysize, SecureRandom random)669 public void initialize(int keysize, SecureRandom random) { 670 if (serviceIterator == null) { 671 spi.initialize(keysize, random); 672 return; 673 } 674 RuntimeException failure = null; 675 KeyPairGeneratorSpi mySpi = spi; 676 do { 677 try { 678 mySpi.initialize(keysize, random); 679 initType = I_SIZE; 680 initKeySize = keysize; 681 initParams = null; 682 initRandom = random; 683 return; 684 } catch (RuntimeException e) { 685 if (failure == null) { 686 failure = e; 687 } 688 mySpi = nextSpi(mySpi, false); 689 } 690 } while (mySpi != null); 691 throw failure; 692 } 693 694 // engine method initialize(AlgorithmParameterSpec params, SecureRandom random)695 public void initialize(AlgorithmParameterSpec params, 696 SecureRandom random) throws InvalidAlgorithmParameterException { 697 if (serviceIterator == null) { 698 spi.initialize(params, random); 699 return; 700 } 701 Exception failure = null; 702 KeyPairGeneratorSpi mySpi = spi; 703 do { 704 try { 705 mySpi.initialize(params, random); 706 initType = I_PARAMS; 707 initKeySize = 0; 708 initParams = params; 709 initRandom = random; 710 return; 711 } catch (Exception e) { 712 if (failure == null) { 713 failure = e; 714 } 715 mySpi = nextSpi(mySpi, false); 716 } 717 } while (mySpi != null); 718 if (failure instanceof RuntimeException) { 719 throw (RuntimeException)failure; 720 } 721 // must be an InvalidAlgorithmParameterException 722 throw (InvalidAlgorithmParameterException)failure; 723 } 724 725 // engine method generateKeyPair()726 public KeyPair generateKeyPair() { 727 if (serviceIterator == null) { 728 return spi.generateKeyPair(); 729 } 730 RuntimeException failure = null; 731 KeyPairGeneratorSpi mySpi = spi; 732 do { 733 try { 734 return mySpi.generateKeyPair(); 735 } catch (RuntimeException e) { 736 if (failure == null) { 737 failure = e; 738 } 739 mySpi = nextSpi(mySpi, true); 740 } 741 } while (mySpi != null); 742 throw failure; 743 } 744 } 745 746 } 747