• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.jce.provider.asymmetric.ec;
2 
3 import java.math.BigInteger;
4 import java.security.InvalidAlgorithmParameterException;
5 import java.security.InvalidParameterException;
6 import java.security.KeyPair;
7 import java.security.SecureRandom;
8 import java.security.spec.AlgorithmParameterSpec;
9 import java.security.spec.ECGenParameterSpec;
10 import java.util.Hashtable;
11 
12 import org.bouncycastle.asn1.DERObjectIdentifier;
13 // BEGIN android-removed
14 // import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
15 // END android-removed
16 import org.bouncycastle.asn1.nist.NISTNamedCurves;
17 import org.bouncycastle.asn1.sec.SECNamedCurves;
18 // BEGIN android-removed
19 // import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
20 // END android-removed
21 import org.bouncycastle.asn1.x9.X962NamedCurves;
22 import org.bouncycastle.asn1.x9.X9ECParameters;
23 import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
24 import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
25 import org.bouncycastle.crypto.params.ECDomainParameters;
26 import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
27 import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
28 import org.bouncycastle.crypto.params.ECPublicKeyParameters;
29 import org.bouncycastle.jce.provider.JCEECPrivateKey;
30 import org.bouncycastle.jce.provider.JCEECPublicKey;
31 import org.bouncycastle.jce.provider.JDKKeyPairGenerator;
32 import org.bouncycastle.jce.provider.ProviderUtil;
33 import org.bouncycastle.jce.spec.ECNamedCurveSpec;
34 import org.bouncycastle.jce.spec.ECParameterSpec;
35 import org.bouncycastle.math.ec.ECCurve;
36 import org.bouncycastle.math.ec.ECPoint;
37 
38 public abstract class KeyPairGenerator
39     extends JDKKeyPairGenerator
40 {
KeyPairGenerator(String algorithmName)41     public KeyPairGenerator(String algorithmName)
42     {
43         super(algorithmName);
44     }
45 
46     public static class EC
47         extends KeyPairGenerator
48     {
49         ECKeyGenerationParameters   param;
50         ECKeyPairGenerator          engine = new ECKeyPairGenerator();
51         Object                      ecParams = null;
52         int                         strength = 239;
53         int                         certainty = 50;
54         SecureRandom                random = new SecureRandom();
55         boolean                     initialised = false;
56         String                      algorithm;
57 
58         static private Hashtable    ecParameters;
59 
60         static {
61             ecParameters = new Hashtable();
62 
63             // BEGIN android-changed
64             ecParameters.put(Integer.valueOf(192), new ECGenParameterSpec("prime192v1")); // a.k.a P-192
65             ecParameters.put(Integer.valueOf(239), new ECGenParameterSpec("prime239v1"));
66             ecParameters.put(Integer.valueOf(256), new ECGenParameterSpec("prime256v1")); // a.k.a P-256
67 
68             ecParameters.put(Integer.valueOf(224), new ECGenParameterSpec("P-224"));
69             ecParameters.put(Integer.valueOf(384), new ECGenParameterSpec("P-384"));
70             ecParameters.put(Integer.valueOf(521), new ECGenParameterSpec("P-521"));
71             // END android-changed
72         }
73 
EC()74         public EC()
75         {
76             super("EC");
77             this.algorithm = "EC";
78         }
79 
EC( String algorithm)80         public EC(
81             String  algorithm)
82         {
83             super(algorithm);
84             this.algorithm = algorithm;
85         }
86 
initialize( int strength, SecureRandom random)87         public void initialize(
88             int             strength,
89             SecureRandom    random)
90         {
91             this.strength = strength;
92             // BEGIN android-added
93             if (random != null) {
94             // END android-added
95             this.random = random;
96             // BEGIN android-added
97             }
98             // END android-added
99             // BEGIN android-changed
100             this.ecParams = ecParameters.get(Integer.valueOf(strength));
101             // END android-changed
102 
103             if (ecParams != null)
104             {
105                 try
106                 {
107                     initialize((ECGenParameterSpec)ecParams, random);
108                 }
109                 catch (InvalidAlgorithmParameterException e)
110                 {
111                     throw new InvalidParameterException("key size not configurable.");
112                 }
113             }
114             else
115             {
116                 throw new InvalidParameterException("unknown key size.");
117             }
118         }
119 
initialize( AlgorithmParameterSpec params, SecureRandom random)120         public void initialize(
121             AlgorithmParameterSpec  params,
122             SecureRandom            random)
123             throws InvalidAlgorithmParameterException
124         {
125             // BEGIN android-added
126             if (random == null) {
127                 random = this.random;
128             }
129             // END android-added
130             if (params instanceof ECParameterSpec)
131             {
132                 ECParameterSpec p = (ECParameterSpec)params;
133                 this.ecParams = params;
134 
135                 param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random);
136 
137                 engine.init(param);
138                 initialised = true;
139             }
140             else if (params instanceof java.security.spec.ECParameterSpec)
141             {
142                 java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)params;
143                 this.ecParams = params;
144 
145                 ECCurve curve = EC5Util.convertCurve(p.getCurve());
146                 ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false);
147 
148                 param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random);
149 
150                 engine.init(param);
151                 initialised = true;
152             }
153             else if (params instanceof ECGenParameterSpec)
154             {
155                 final String curveName = ((ECGenParameterSpec)params).getName();
156 
157                 // BEGIN android-removed
158                 // if (this.algorithm.equals("ECGOST3410"))
159                 // {
160                 //     ECDomainParameters  ecP = ECGOST3410NamedCurves.getByName(curveName);
161                 //     if (ecP == null)
162                 //     {
163                 //         throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
164                 //     }
165                 //
166                 //     this.ecParams = new ECNamedCurveSpec(
167                 //                                     curveName,
168                 //                                     ecP.getCurve(),
169                 //                                     ecP.getG(),
170                 //                                     ecP.getN(),
171                 //                                     ecP.getH(),
172                 //                                     ecP.getSeed());
173                 // }
174                 // else
175                 // END android-removed
176                 {
177                     X9ECParameters  ecP = X962NamedCurves.getByName(curveName);
178                     if (ecP == null)
179                     {
180                         ecP = SECNamedCurves.getByName(curveName);
181                         if (ecP == null)
182                         {
183                             ecP = NISTNamedCurves.getByName(curveName);
184                         }
185                         // BEGIN android-removed
186                         // if (ecP == null)
187                         // {
188                         //     ecP = TeleTrusTNamedCurves.getByName(curveName);
189                         // }
190                         // END android-removed
191                         if (ecP == null)
192                         {
193                             // See if it's actually an OID string (SunJSSE ServerHandshaker setupEphemeralECDHKeys bug)
194                             try
195                             {
196                                 DERObjectIdentifier oid = new DERObjectIdentifier(curveName);
197                                 ecP = X962NamedCurves.getByOID(oid);
198                                 if (ecP == null)
199                                 {
200                                     ecP = SECNamedCurves.getByOID(oid);
201                                 }
202                                 if (ecP == null)
203                                 {
204                                     ecP = NISTNamedCurves.getByOID(oid);
205                                 }
206                                 // BEGIN android-removed
207                                 // if (ecP == null)
208                                 // {
209                                 //     ecP = TeleTrusTNamedCurves.getByOID(oid);
210                                 // }
211                                 // END android-removed
212                                 if (ecP == null)
213                                 {
214                                     throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
215                                 }
216                             }
217                             catch (IllegalArgumentException ex)
218                             {
219                                 throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
220                             }
221                         }
222                     }
223 
224                     this.ecParams = new ECNamedCurveSpec(
225                             curveName,
226                             ecP.getCurve(),
227                             ecP.getG(),
228                             ecP.getN(),
229                             ecP.getH(),
230                             null); // ecP.getSeed());   Work-around JDK bug -- it won't look up named curves properly if seed is present
231                 }
232 
233                 java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams;
234 
235                 ECCurve curve = EC5Util.convertCurve(p.getCurve());
236                 ECPoint g = EC5Util.convertPoint(curve, p.getGenerator(), false);
237 
238                 param = new ECKeyGenerationParameters(new ECDomainParameters(curve, g, p.getOrder(), BigInteger.valueOf(p.getCofactor())), random);
239 
240                 engine.init(param);
241                 initialised = true;
242             }
243             else if (params == null && ProviderUtil.getEcImplicitlyCa() != null)
244             {
245                 ECParameterSpec p = ProviderUtil.getEcImplicitlyCa();
246                 this.ecParams = params;
247 
248                 param = new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), random);
249 
250                 engine.init(param);
251                 initialised = true;
252             }
253             else if (params == null && ProviderUtil.getEcImplicitlyCa() == null)
254             {
255                 throw new InvalidAlgorithmParameterException("null parameter passed but no implicitCA set");
256             }
257             else
258             {
259                 throw new InvalidAlgorithmParameterException("parameter object not a ECParameterSpec");
260             }
261         }
262 
generateKeyPair()263         public KeyPair generateKeyPair()
264         {
265             if (!initialised)
266             {
267                 // BEGIN android-removed
268                 // throw new IllegalStateException("EC Key Pair Generator not initialised");
269                 // END android-removed
270                 // BEGIN android-added
271                 /*
272                  * KeyPairGenerator documentation says that a default initialization must be provided
273                  */
274                 initialize(192, random);
275                 // END android-added
276             }
277 
278             AsymmetricCipherKeyPair     pair = engine.generateKeyPair();
279             ECPublicKeyParameters       pub = (ECPublicKeyParameters)pair.getPublic();
280             ECPrivateKeyParameters      priv = (ECPrivateKeyParameters)pair.getPrivate();
281 
282             if (ecParams instanceof ECParameterSpec)
283             {
284                 ECParameterSpec p = (ECParameterSpec)ecParams;
285 
286                 JCEECPublicKey pubKey = new JCEECPublicKey(algorithm, pub, p);
287                 return new KeyPair(pubKey,
288                                    new JCEECPrivateKey(algorithm, priv, pubKey, p));
289             }
290             else if (ecParams == null)
291             {
292                return new KeyPair(new JCEECPublicKey(algorithm, pub),
293                                    new JCEECPrivateKey(algorithm, priv));
294             }
295             else
296             {
297                 java.security.spec.ECParameterSpec p = (java.security.spec.ECParameterSpec)ecParams;
298 
299                 JCEECPublicKey pubKey = new JCEECPublicKey(algorithm, pub, p);
300 
301                 return new KeyPair(pubKey, new JCEECPrivateKey(algorithm, priv, pubKey, p));
302             }
303         }
304     }
305 
306     public static class ECDSA
307         extends EC
308     {
ECDSA()309         public ECDSA()
310         {
311             super("ECDSA");
312         }
313     }
314 
315     // BEGIN android-removed
316     // public static class ECGOST3410
317     //     extends EC
318     // {
319     //     public ECGOST3410()
320     //     {
321     //         super("ECGOST3410");
322     //     }
323     // }
324     // END android-removed
325 
326     public static class ECDH
327         extends EC
328     {
ECDH()329         public ECDH()
330         {
331             super("ECDH");
332         }
333     }
334 
335     public static class ECDHC
336         extends EC
337     {
ECDHC()338         public ECDHC()
339         {
340             super("ECDHC");
341         }
342     }
343 
344     public static class ECMQV
345         extends EC
346     {
ECMQV()347         public ECMQV()
348         {
349             super("ECMQV");
350         }
351     }
352 }
353