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+
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</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+
128+public 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+}