1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.geronimo.util.jce.provider;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.security.InvalidKeyException;
25 import java.security.Key;
26 import java.security.KeyFactorySpi;
27 import java.security.PrivateKey;
28 import java.security.PublicKey;
29 import java.security.interfaces.DSAPrivateKey;
30 import java.security.interfaces.DSAPublicKey;
31 import java.security.interfaces.RSAPrivateCrtKey;
32 import java.security.interfaces.RSAPrivateKey;
33 import java.security.interfaces.RSAPublicKey;
34 import java.security.spec.DSAPrivateKeySpec;
35 import java.security.spec.DSAPublicKeySpec;
36 import java.security.spec.InvalidKeySpecException;
37 import java.security.spec.KeySpec;
38 import java.security.spec.PKCS8EncodedKeySpec;
39 import java.security.spec.RSAPrivateCrtKeySpec;
40 import java.security.spec.RSAPrivateKeySpec;
41 import java.security.spec.RSAPublicKeySpec;
42 import java.security.spec.X509EncodedKeySpec;
43
44 import javax.crypto.interfaces.DHPrivateKey;
45 import javax.crypto.interfaces.DHPublicKey;
46 import javax.crypto.spec.DHPrivateKeySpec;
47 import javax.crypto.spec.DHPublicKeySpec;
48
49 import org.apache.geronimo.util.asn1.ASN1InputStream;
50 import org.apache.geronimo.util.asn1.ASN1Sequence;
51 import org.apache.geronimo.util.asn1.cryptopro.CryptoProObjectIdentifiers;
52 import org.apache.geronimo.util.asn1.oiw.OIWObjectIdentifiers;
53 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers;
54 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo;
55 import org.apache.geronimo.util.asn1.pkcs.RSAPrivateKeyStructure;
56 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
57 import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo;
58 import org.apache.geronimo.util.asn1.x509.X509ObjectIdentifiers;
59 import org.apache.geronimo.util.asn1.x9.X9ObjectIdentifiers;
60 import org.apache.geronimo.util.jce.provider.JCEDHPrivateKey;
61 import org.apache.geronimo.util.jce.provider.JCEDHPublicKey;
62
63 public abstract class JDKKeyFactory
64 extends KeyFactorySpi
65 {
66 public JDKKeyFactory()
67 {
68 }
69
70 protected KeySpec engineGetKeySpec(
71 Key key,
72 Class spec)
73 throws InvalidKeySpecException
74 {
75 if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8"))
76 {
77 return new PKCS8EncodedKeySpec(key.getEncoded());
78 }
79 else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509"))
80 {
81 return new X509EncodedKeySpec(key.getEncoded());
82 }
83 else if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey)
84 {
85 RSAPublicKey k = (RSAPublicKey)key;
86
87 return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
88 }
89 else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof RSAPrivateKey)
90 {
91 RSAPrivateKey k = (RSAPrivateKey)key;
92
93 return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
94 }
95 else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey)
96 {
97 RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
98
99 return new RSAPrivateCrtKeySpec(
100 k.getModulus(), k.getPublicExponent(),
101 k.getPrivateExponent(),
102 k.getPrimeP(), k.getPrimeQ(),
103 k.getPrimeExponentP(), k.getPrimeExponentQ(),
104 k.getCrtCoefficient());
105 }
106 else if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey)
107 {
108 DHPrivateKey k = (DHPrivateKey)key;
109
110 return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG());
111 }
112 else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey)
113 {
114 DHPublicKey k = (DHPublicKey)key;
115
116 return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG());
117 }
118
119 throw new RuntimeException("not implemented yet " + key + " " + spec);
120 }
121
122 protected Key engineTranslateKey(
123 Key key)
124 throws InvalidKeyException
125 {
126 if (key instanceof RSAPublicKey)
127 {
128 return new JCERSAPublicKey((RSAPublicKey)key);
129 }
130 else if (key instanceof RSAPrivateCrtKey)
131 {
132 return new JCERSAPrivateCrtKey((RSAPrivateCrtKey)key);
133 }
134 else if (key instanceof RSAPrivateKey)
135 {
136 return new JCERSAPrivateKey((RSAPrivateKey)key);
137 }
138 else if (key instanceof DHPublicKey)
139 {
140 return new JCEDHPublicKey((DHPublicKey)key);
141 }
142 else if (key instanceof DHPrivateKey)
143 {
144 return new JCEDHPrivateKey((DHPrivateKey)key);
145 }
146 else if (key instanceof DSAPublicKey)
147 {
148 return new JDKDSAPublicKey((DSAPublicKey)key);
149 }
150 else if (key instanceof DSAPrivateKey)
151 {
152 return new JDKDSAPrivateKey((DSAPrivateKey)key);
153 }
154 throw new InvalidKeyException("key type unknown");
155 }
156
157 /**
158 * create a public key from the given DER encoded input stream.
159 */
160 static PublicKey createPublicKeyFromDERStream(
161 InputStream in)
162 throws IOException
163 {
164 return createPublicKeyFromPublicKeyInfo(
165 new SubjectPublicKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
166 }
167
168 /**
169 * create a public key from the given public key info object.
170 */
171 static PublicKey createPublicKeyFromPublicKeyInfo(
172 SubjectPublicKeyInfo info)
173 {
174 AlgorithmIdentifier algId = info.getAlgorithmId();
175
176 if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption)
177 || algId.getObjectId().equals(X509ObjectIdentifiers.id_ea_rsa))
178 {
179 return new JCERSAPublicKey(info);
180 }
181 else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement))
182 {
183 return new JCEDHPublicKey(info);
184 }
185 else if (algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber))
186 {
187 return new JCEDHPublicKey(info);
188 }
189 else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa))
190 {
191 return new JDKDSAPublicKey(info);
192 }
193 else if (algId.getObjectId().equals(OIWObjectIdentifiers.dsaWithSHA1))
194 {
195 return new JDKDSAPublicKey(info);
196 }
197 else
198 {
199 throw new RuntimeException("algorithm identifier in key not recognised");
200 }
201 }
202
203 /**
204 * create a private key from the given DER encoded input stream.
205 */
206 static PrivateKey createPrivateKeyFromDERStream(
207 InputStream in)
208 throws IOException
209 {
210 return createPrivateKeyFromPrivateKeyInfo(
211 new PrivateKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
212 }
213
214 /**
215 * create a private key from the given public key info object.
216 */
217 static PrivateKey createPrivateKeyFromPrivateKeyInfo(
218 PrivateKeyInfo info)
219 {
220 AlgorithmIdentifier algId = info.getAlgorithmId();
221
222 if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption))
223 {
224 return new JCERSAPrivateCrtKey(info);
225 }
226 else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement))
227 {
228 return new JCEDHPrivateKey(info);
229 }
230 else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa))
231 {
232 return new JDKDSAPrivateKey(info);
233 }
234 else
235 {
236 throw new RuntimeException("algorithm identifier in key not recognised");
237 }
238 }
239
240 public static class RSA
241 extends JDKKeyFactory
242 {
243 public RSA()
244 {
245 }
246
247 protected PrivateKey engineGeneratePrivate(
248 KeySpec keySpec)
249 throws InvalidKeySpecException
250 {
251 if (keySpec instanceof PKCS8EncodedKeySpec)
252 {
253 try
254 {
255 return JDKKeyFactory.createPrivateKeyFromDERStream(
256 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
257 }
258 catch (Exception e)
259 {
260
261
262
263 try
264 {
265 return new JCERSAPrivateCrtKey(
266 new RSAPrivateKeyStructure(
267 (ASN1Sequence)new ASN1InputStream(new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())).readObject()));
268 }
269 catch (Exception ex)
270 {
271 throw new InvalidKeySpecException(ex.toString());
272 }
273 }
274 }
275 else if (keySpec instanceof RSAPrivateCrtKeySpec)
276 {
277 return new JCERSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec);
278 }
279 else if (keySpec instanceof RSAPrivateKeySpec)
280 {
281 return new JCERSAPrivateKey((RSAPrivateKeySpec)keySpec);
282 }
283
284 throw new InvalidKeySpecException("Unknown KeySpec type.");
285 }
286
287 protected PublicKey engineGeneratePublic(
288 KeySpec keySpec)
289 throws InvalidKeySpecException
290 {
291 if (keySpec instanceof X509EncodedKeySpec)
292 {
293 try
294 {
295 return JDKKeyFactory.createPublicKeyFromDERStream(
296 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
297 }
298 catch (Exception e)
299 {
300 throw new InvalidKeySpecException(e.toString());
301 }
302 }
303 else if (keySpec instanceof RSAPublicKeySpec)
304 {
305 return new JCERSAPublicKey((RSAPublicKeySpec)keySpec);
306 }
307
308 throw new InvalidKeySpecException("Unknown KeySpec type.");
309 }
310 }
311
312 public static class DH
313 extends JDKKeyFactory
314 {
315 public DH()
316 {
317 }
318
319 protected PrivateKey engineGeneratePrivate(
320 KeySpec keySpec)
321 throws InvalidKeySpecException
322 {
323 if (keySpec instanceof PKCS8EncodedKeySpec)
324 {
325 try
326 {
327 return JDKKeyFactory.createPrivateKeyFromDERStream(
328 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
329 }
330 catch (Exception e)
331 {
332 throw new InvalidKeySpecException(e.toString());
333 }
334 }
335 else if (keySpec instanceof DHPrivateKeySpec)
336 {
337 return new JCEDHPrivateKey((DHPrivateKeySpec)keySpec);
338 }
339
340 throw new InvalidKeySpecException("Unknown KeySpec type.");
341 }
342
343 protected PublicKey engineGeneratePublic(
344 KeySpec keySpec)
345 throws InvalidKeySpecException
346 {
347 if (keySpec instanceof X509EncodedKeySpec)
348 {
349 try
350 {
351 return JDKKeyFactory.createPublicKeyFromDERStream(
352 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
353 }
354 catch (Exception e)
355 {
356 throw new InvalidKeySpecException(e.toString());
357 }
358 }
359 else if (keySpec instanceof DHPublicKeySpec)
360 {
361 return new JCEDHPublicKey((DHPublicKeySpec)keySpec);
362 }
363
364 throw new InvalidKeySpecException("Unknown KeySpec type.");
365 }
366 }
367
368 public static class DSA
369 extends JDKKeyFactory
370 {
371 public DSA()
372 {
373 }
374
375 protected PrivateKey engineGeneratePrivate(
376 KeySpec keySpec)
377 throws InvalidKeySpecException
378 {
379 if (keySpec instanceof PKCS8EncodedKeySpec)
380 {
381 try
382 {
383 return JDKKeyFactory.createPrivateKeyFromDERStream(
384 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
385 }
386 catch (Exception e)
387 {
388 throw new InvalidKeySpecException(e.toString());
389 }
390 }
391 else if (keySpec instanceof DSAPrivateKeySpec)
392 {
393 return new JDKDSAPrivateKey((DSAPrivateKeySpec)keySpec);
394 }
395
396 throw new InvalidKeySpecException("Unknown KeySpec type.");
397 }
398
399 protected PublicKey engineGeneratePublic(
400 KeySpec keySpec)
401 throws InvalidKeySpecException
402 {
403 if (keySpec instanceof X509EncodedKeySpec)
404 {
405 try
406 {
407 return JDKKeyFactory.createPublicKeyFromDERStream(
408 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
409 }
410 catch (Exception e)
411 {
412 throw new InvalidKeySpecException(e.toString());
413 }
414 }
415 else if (keySpec instanceof DSAPublicKeySpec)
416 {
417 return new JDKDSAPublicKey((DSAPublicKeySpec)keySpec);
418 }
419
420 throw new InvalidKeySpecException("Unknown KeySpec type.");
421 }
422 }
423
424
425 public static class EC
426 extends JDKKeyFactory
427 {
428 String algorithm;
429
430 public EC()
431 {
432 this("EC");
433 }
434
435 public EC(
436 String algorithm)
437 {
438 this.algorithm = algorithm;
439 }
440
441 protected PrivateKey engineGeneratePrivate(
442 KeySpec keySpec)
443 throws InvalidKeySpecException
444 {
445 if (keySpec instanceof PKCS8EncodedKeySpec)
446 {
447 try
448 {
449 return JDKKeyFactory.createPrivateKeyFromDERStream(
450 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
451 }
452 catch (Exception e)
453 {
454 throw new InvalidKeySpecException(e.toString());
455 }
456 }
457
458 throw new InvalidKeySpecException("Unknown KeySpec type.");
459 }
460
461 protected PublicKey engineGeneratePublic(
462 KeySpec keySpec)
463 throws InvalidKeySpecException
464 {
465 if (keySpec instanceof X509EncodedKeySpec)
466 {
467 try
468 {
469 return JDKKeyFactory.createPublicKeyFromDERStream(
470 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
471 }
472 catch (Exception e)
473 {
474 throw new InvalidKeySpecException(e.toString());
475 }
476 }
477
478 throw new InvalidKeySpecException("Unknown KeySpec type.");
479 }
480 }
481 }