1package org.bouncycastle.jce.provider;
2
3import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
4import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
5import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator;
6import org.bouncycastle.crypto.generators.DHParametersGenerator;
7import org.bouncycastle.crypto.generators.DSAKeyPairGenerator;
8import org.bouncycastle.crypto.generators.DSAParametersGenerator;
9// BEGIN android-removed
10// import org.bouncycastle.crypto.generators.ElGamalKeyPairGenerator;
11// import org.bouncycastle.crypto.generators.ElGamalParametersGenerator;
12// import org.bouncycastle.crypto.generators.GOST3410KeyPairGenerator;
13// END android-removed
14import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
15import org.bouncycastle.crypto.params.DHKeyGenerationParameters;
16import org.bouncycastle.crypto.params.DHParameters;
17import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
18import org.bouncycastle.crypto.params.DHPublicKeyParameters;
19import org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
20import org.bouncycastle.crypto.params.DSAParameters;
21import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
22import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
23// BEGIN android-removed
24// import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters;
25// import org.bouncycastle.crypto.params.ElGamalParameters;
26// import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
27// import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters;
28// import org.bouncycastle.crypto.params.GOST3410KeyGenerationParameters;
29// import org.bouncycastle.crypto.params.GOST3410Parameters;
30// import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters;
31// import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters;
32// END android-removed
33import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
34import org.bouncycastle.crypto.params.RSAKeyParameters;
35import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
36// BEGIN android-removed
37// import org.bouncycastle.jce.spec.ElGamalParameterSpec;
38// import org.bouncycastle.jce.spec.GOST3410ParameterSpec;
39// import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec;
40// END android-removed
41
42import java.math.BigInteger;
43import java.security.InvalidAlgorithmParameterException;
44import java.security.InvalidParameterException;
45import java.security.KeyPair;
46import java.security.KeyPairGenerator;
47import java.security.SecureRandom;
48import java.security.spec.AlgorithmParameterSpec;
49import java.security.spec.DSAParameterSpec;
50import java.security.spec.RSAKeyGenParameterSpec;
51import java.util.Hashtable;
52
53import javax.crypto.spec.DHParameterSpec;
54
55public abstract class JDKKeyPairGenerator
56    extends KeyPairGenerator
57{
58    public JDKKeyPairGenerator(
59        String              algorithmName)
60    {
61        super(algorithmName);
62    }
63
64    public abstract void initialize(int strength, SecureRandom random);
65
66    public abstract KeyPair generateKeyPair();
67
68    public static class RSA
69        extends JDKKeyPairGenerator
70    {
71        final static BigInteger defaultPublicExponent = BigInteger.valueOf(0x10001);
72        final static int defaultTests = 12;
73
74        RSAKeyGenerationParameters  param;
75        RSAKeyPairGenerator         engine;
76
77        public RSA()
78        {
79            super("RSA");
80
81            engine = new RSAKeyPairGenerator();
82            param = new RSAKeyGenerationParameters(defaultPublicExponent,
83                            new SecureRandom(), 2048, defaultTests);
84            engine.init(param);
85        }
86
87        public void initialize(
88            int             strength,
89            SecureRandom    random)
90        {
91            param = new RSAKeyGenerationParameters(defaultPublicExponent,
92                            random, strength, defaultTests);
93
94            engine.init(param);
95        }
96
97        public void initialize(
98            AlgorithmParameterSpec  params,
99            SecureRandom            random)
100            throws InvalidAlgorithmParameterException
101        {
102            if (!(params instanceof RSAKeyGenParameterSpec))
103            {
104                throw new InvalidAlgorithmParameterException("parameter object not a RSAKeyGenParameterSpec");
105            }
106            RSAKeyGenParameterSpec     rsaParams = (RSAKeyGenParameterSpec)params;
107
108            param = new RSAKeyGenerationParameters(
109                            rsaParams.getPublicExponent(),
110                            random, rsaParams.getKeysize(), defaultTests);
111
112            engine.init(param);
113        }
114
115        public KeyPair generateKeyPair()
116        {
117            AsymmetricCipherKeyPair     pair = engine.generateKeyPair();
118            RSAKeyParameters            pub = (RSAKeyParameters)pair.getPublic();
119            RSAPrivateCrtKeyParameters  priv = (RSAPrivateCrtKeyParameters)pair.getPrivate();
120
121            return new KeyPair(new JCERSAPublicKey(pub),
122                               new JCERSAPrivateCrtKey(priv));
123        }
124    }
125
126    public static class DH
127        extends JDKKeyPairGenerator
128    {
129        private static Hashtable   params = new Hashtable();
130
131        DHKeyGenerationParameters  param;
132        DHBasicKeyPairGenerator    engine = new DHBasicKeyPairGenerator();
133        int                        strength = 1024;
134        int                        certainty = 20;
135        SecureRandom               random = new SecureRandom();
136        boolean                    initialised = false;
137
138        public DH()
139        {
140            super("DH");
141        }
142
143        public void initialize(
144            int             strength,
145            SecureRandom    random)
146        {
147            this.strength = strength;
148            this.random = random;
149        }
150
151        public void initialize(
152            AlgorithmParameterSpec  params,
153            SecureRandom            random)
154            throws InvalidAlgorithmParameterException
155        {
156            if (!(params instanceof DHParameterSpec))
157            {
158                throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec");
159            }
160            DHParameterSpec     dhParams = (DHParameterSpec)params;
161
162            param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL()));
163
164            engine.init(param);
165            initialised = true;
166        }
167
168        public KeyPair generateKeyPair()
169        {
170            if (!initialised)
171            {
172                // BEGIN android-changed
173                Integer paramStrength = Integer.valueOf(strength);
174                // END android-changed
175
176                if (params.containsKey(paramStrength))
177                {
178                    param = (DHKeyGenerationParameters)params.get(paramStrength);
179                }
180                else
181                {
182                    DHParametersGenerator   pGen = new DHParametersGenerator();
183
184                    pGen.init(strength, certainty, random);
185
186                    param = new DHKeyGenerationParameters(random, pGen.generateParameters());
187
188                    params.put(paramStrength, param);
189                }
190
191                engine.init(param);
192
193                initialised = true;
194            }
195
196            AsymmetricCipherKeyPair pair = engine.generateKeyPair();
197            DHPublicKeyParameters   pub = (DHPublicKeyParameters)pair.getPublic();
198            DHPrivateKeyParameters  priv = (DHPrivateKeyParameters)pair.getPrivate();
199
200            return new KeyPair(new JCEDHPublicKey(pub),
201                               new JCEDHPrivateKey(priv));
202        }
203    }
204
205    public static class DSA
206        extends JDKKeyPairGenerator
207    {
208        DSAKeyGenerationParameters param;
209        DSAKeyPairGenerator        engine = new DSAKeyPairGenerator();
210        int                        strength = 1024;
211        int                        certainty = 20;
212        SecureRandom               random = new SecureRandom();
213        boolean                    initialised = false;
214
215        public DSA()
216        {
217            super("DSA");
218        }
219
220        public void initialize(
221            int             strength,
222            SecureRandom    random)
223        {
224            if (strength < 512 || strength > 1024 || strength % 64 != 0)
225            {
226                throw new InvalidParameterException("strength must be from 512 - 1024 and a multiple of 64");
227            }
228
229            this.strength = strength;
230            this.random = random;
231        }
232
233        public void initialize(
234            AlgorithmParameterSpec  params,
235            SecureRandom            random)
236            throws InvalidAlgorithmParameterException
237        {
238            if (!(params instanceof DSAParameterSpec))
239            {
240                throw new InvalidAlgorithmParameterException("parameter object not a DSAParameterSpec");
241            }
242            DSAParameterSpec     dsaParams = (DSAParameterSpec)params;
243
244            param = new DSAKeyGenerationParameters(random, new DSAParameters(dsaParams.getP(), dsaParams.getQ(), dsaParams.getG()));
245
246            engine.init(param);
247            initialised = true;
248        }
249
250        public KeyPair generateKeyPair()
251        {
252            if (!initialised)
253            {
254                DSAParametersGenerator   pGen = new DSAParametersGenerator();
255
256                pGen.init(strength, certainty, random);
257                param = new DSAKeyGenerationParameters(random, pGen.generateParameters());
258                engine.init(param);
259                initialised = true;
260            }
261
262            AsymmetricCipherKeyPair   pair = engine.generateKeyPair();
263            DSAPublicKeyParameters     pub = (DSAPublicKeyParameters)pair.getPublic();
264            DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)pair.getPrivate();
265
266            return new KeyPair(new JDKDSAPublicKey(pub),
267                               new JDKDSAPrivateKey(priv));
268        }
269    }
270
271    // BEGIN android-removed
272    // public static class ElGamal
273    //     extends JDKKeyPairGenerator
274    // {
275    //     ElGamalKeyGenerationParameters  param;
276    //     ElGamalKeyPairGenerator         engine = new ElGamalKeyPairGenerator();
277    //     int                             strength = 1024;
278    //     int                             certainty = 20;
279    //     SecureRandom                    random = new SecureRandom();
280    //     boolean                         initialised = false;
281    //
282    //     public ElGamal()
283    //     {
284    //         super("ElGamal");
285    //     }
286    //
287    //     public void initialize(
288    //         int             strength,
289    //         SecureRandom    random)
290    //     {
291    //         this.strength = strength;
292    //         this.random = random;
293    //     }
294    //
295    //     public void initialize(
296    //         AlgorithmParameterSpec  params,
297    //         SecureRandom            random)
298    //         throws InvalidAlgorithmParameterException
299    //     {
300    //         if (!(params instanceof ElGamalParameterSpec) && !(params instanceof DHParameterSpec))
301    //         {
302    //             throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec or an ElGamalParameterSpec");
303    //         }
304    //
305    //         if (params instanceof ElGamalParameterSpec)
306    //         {
307    //             ElGamalParameterSpec     elParams = (ElGamalParameterSpec)params;
308
309    //             param = new ElGamalKeyGenerationParameters(random, new ElGamalParameters(elParams.getP(), elParams.getG()));
310    //         }
311    //         else
312    //         {
313    //             DHParameterSpec     dhParams = (DHParameterSpec)params;
314    //
315    //             param = new ElGamalKeyGenerationParameters(random, new ElGamalParameters(dhParams.getP(), dhParams.getG(), dhParams.getL()));
316    //         }
317    //
318    //         engine.init(param);
319    //         initialised = true;
320    //     }
321    //
322    //     public KeyPair generateKeyPair()
323    //     {
324    //         if (!initialised)
325    //         {
326    //             ElGamalParametersGenerator   pGen = new ElGamalParametersGenerator();
327    //
328    //             pGen.init(strength, certainty, random);
329    //             param = new ElGamalKeyGenerationParameters(random, pGen.generateParameters());
330    //             engine.init(param);
331    //             initialised = true;
332    //         }
333    //
334    //         AsymmetricCipherKeyPair         pair = engine.generateKeyPair();
335    //         ElGamalPublicKeyParameters      pub = (ElGamalPublicKeyParameters)pair.getPublic();
336    //         ElGamalPrivateKeyParameters     priv = (ElGamalPrivateKeyParameters)pair.getPrivate();
337    //
338    //         return new KeyPair(new JCEElGamalPublicKey(pub),
339    //                            new JCEElGamalPrivateKey(priv));
340    //     }
341    // }
342    // END android-removed
343
344   // BEGIN android-removed
345   //  public static class GOST3410
346   //      extends JDKKeyPairGenerator
347   //  {
348   //      GOST3410KeyGenerationParameters param;
349   //      GOST3410KeyPairGenerator        engine = new GOST3410KeyPairGenerator();
350   //      GOST3410ParameterSpec           gost3410Params;
351   //      int                             strength = 1024;
352   //      SecureRandom                    random = null;
353   //      boolean                         initialised = false;
354   //
355   //      public GOST3410()
356   //      {
357   //          super("GOST3410");
358   //      }
359   //
360   //      public void initialize(
361   //          int             strength,
362   //          SecureRandom    random)
363   //      {
364   //          this.strength = strength;
365   //          this.random = random;
366   //      }
367   //
368   //      private void init(
369   //          GOST3410ParameterSpec gParams,
370   //          SecureRandom          random)
371   //      {
372   //          GOST3410PublicKeyParameterSetSpec spec = gParams.getPublicKeyParameters();
373   //
374   //          param = new GOST3410KeyGenerationParameters(random, new GOST3410Parameters(spec.getP(), spec.getQ(), spec.getA()));
375   //
376   //          engine.init(param);
377   //
378   //          initialised = true;
379   //          gost3410Params = gParams;
380   //      }
381   //
382   //      public void initialize(
383   //          AlgorithmParameterSpec  params,
384   //          SecureRandom            random)
385   //          throws InvalidAlgorithmParameterException
386   //      {
387   //          if (!(params instanceof GOST3410ParameterSpec))
388   //          {
389   //              throw new InvalidAlgorithmParameterException("parameter object not a GOST3410ParameterSpec");
390   //          }
391   //
392   //          init((GOST3410ParameterSpec)params, random);
393   //      }
394   //
395   //      public KeyPair generateKeyPair()
396   //      {
397   //          if (!initialised)
398   //          {
399   //              init(new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A.getId()), new SecureRandom());
400   //          }
401   //
402   //          AsymmetricCipherKeyPair   pair = engine.generateKeyPair();
403   //          GOST3410PublicKeyParameters  pub = (GOST3410PublicKeyParameters)pair.getPublic();
404   //          GOST3410PrivateKeyParameters priv = (GOST3410PrivateKeyParameters)pair.getPrivate();
405   //
406   //          return new KeyPair(new JDKGOST3410PublicKey(pub, gost3410Params), new JDKGOST3410PrivateKey(priv, gost3410Params));
407   //      }
408   // }
409   // END android-removed
410}
411