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