History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/security/KeyPairGenerator.java (1 of 18352 files). Show all

Unified · Split

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