001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.util.jce.provider;
019
020 import java.io.ByteArrayInputStream;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.security.InvalidKeyException;
024 import java.security.Key;
025 import java.security.KeyFactorySpi;
026 import java.security.PrivateKey;
027 import java.security.PublicKey;
028 import java.security.interfaces.DSAPrivateKey;
029 import java.security.interfaces.DSAPublicKey;
030 import java.security.interfaces.RSAPrivateCrtKey;
031 import java.security.interfaces.RSAPrivateKey;
032 import java.security.interfaces.RSAPublicKey;
033 import java.security.spec.DSAPrivateKeySpec;
034 import java.security.spec.DSAPublicKeySpec;
035 import java.security.spec.InvalidKeySpecException;
036 import java.security.spec.KeySpec;
037 import java.security.spec.PKCS8EncodedKeySpec;
038 import java.security.spec.RSAPrivateCrtKeySpec;
039 import java.security.spec.RSAPrivateKeySpec;
040 import java.security.spec.RSAPublicKeySpec;
041 import java.security.spec.X509EncodedKeySpec;
042
043 import javax.crypto.interfaces.DHPrivateKey;
044 import javax.crypto.interfaces.DHPublicKey;
045 import javax.crypto.spec.DHPrivateKeySpec;
046 import javax.crypto.spec.DHPublicKeySpec;
047
048 import org.apache.geronimo.util.asn1.ASN1InputStream;
049 import org.apache.geronimo.util.asn1.ASN1Sequence;
050 import org.apache.geronimo.util.asn1.cryptopro.CryptoProObjectIdentifiers;
051 import org.apache.geronimo.util.asn1.oiw.OIWObjectIdentifiers;
052 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers;
053 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo;
054 import org.apache.geronimo.util.asn1.pkcs.RSAPrivateKeyStructure;
055 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
056 import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo;
057 import org.apache.geronimo.util.asn1.x509.X509ObjectIdentifiers;
058 import org.apache.geronimo.util.asn1.x9.X9ObjectIdentifiers;
059 import org.apache.geronimo.util.jce.provider.JCEDHPrivateKey;
060 import org.apache.geronimo.util.jce.provider.JCEDHPublicKey;
061
062 public abstract class JDKKeyFactory
063 extends KeyFactorySpi
064 {
065 public JDKKeyFactory()
066 {
067 }
068
069 protected KeySpec engineGetKeySpec(
070 Key key,
071 Class spec)
072 throws InvalidKeySpecException
073 {
074 if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8"))
075 {
076 return new PKCS8EncodedKeySpec(key.getEncoded());
077 }
078 else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509"))
079 {
080 return new X509EncodedKeySpec(key.getEncoded());
081 }
082 else if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey)
083 {
084 RSAPublicKey k = (RSAPublicKey)key;
085
086 return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent());
087 }
088 else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof RSAPrivateKey)
089 {
090 RSAPrivateKey k = (RSAPrivateKey)key;
091
092 return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent());
093 }
094 else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey)
095 {
096 RSAPrivateCrtKey k = (RSAPrivateCrtKey)key;
097
098 return new RSAPrivateCrtKeySpec(
099 k.getModulus(), k.getPublicExponent(),
100 k.getPrivateExponent(),
101 k.getPrimeP(), k.getPrimeQ(),
102 k.getPrimeExponentP(), k.getPrimeExponentQ(),
103 k.getCrtCoefficient());
104 }
105 else if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey)
106 {
107 DHPrivateKey k = (DHPrivateKey)key;
108
109 return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG());
110 }
111 else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey)
112 {
113 DHPublicKey k = (DHPublicKey)key;
114
115 return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG());
116 }
117
118 throw new RuntimeException("not implemented yet " + key + " " + spec);
119 }
120
121 protected Key engineTranslateKey(
122 Key key)
123 throws InvalidKeyException
124 {
125 if (key instanceof RSAPublicKey)
126 {
127 return new JCERSAPublicKey((RSAPublicKey)key);
128 }
129 else if (key instanceof RSAPrivateCrtKey)
130 {
131 return new JCERSAPrivateCrtKey((RSAPrivateCrtKey)key);
132 }
133 else if (key instanceof RSAPrivateKey)
134 {
135 return new JCERSAPrivateKey((RSAPrivateKey)key);
136 }
137 else if (key instanceof DHPublicKey)
138 {
139 return new JCEDHPublicKey((DHPublicKey)key);
140 }
141 else if (key instanceof DHPrivateKey)
142 {
143 return new JCEDHPrivateKey((DHPrivateKey)key);
144 }
145 else if (key instanceof DSAPublicKey)
146 {
147 return new JDKDSAPublicKey((DSAPublicKey)key);
148 }
149 else if (key instanceof DSAPrivateKey)
150 {
151 return new JDKDSAPrivateKey((DSAPrivateKey)key);
152 }
153 throw new InvalidKeyException("key type unknown");
154 }
155
156 /**
157 * create a public key from the given DER encoded input stream.
158 */
159 static PublicKey createPublicKeyFromDERStream(
160 InputStream in)
161 throws IOException
162 {
163 return createPublicKeyFromPublicKeyInfo(
164 new SubjectPublicKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
165 }
166
167 /**
168 * create a public key from the given public key info object.
169 */
170 static PublicKey createPublicKeyFromPublicKeyInfo(
171 SubjectPublicKeyInfo info)
172 {
173 AlgorithmIdentifier algId = info.getAlgorithmId();
174
175 if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption)
176 || algId.getObjectId().equals(X509ObjectIdentifiers.id_ea_rsa))
177 {
178 return new JCERSAPublicKey(info);
179 }
180 else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement))
181 {
182 return new JCEDHPublicKey(info);
183 }
184 else if (algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber))
185 {
186 return new JCEDHPublicKey(info);
187 }
188 else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa))
189 {
190 return new JDKDSAPublicKey(info);
191 }
192 else if (algId.getObjectId().equals(OIWObjectIdentifiers.dsaWithSHA1))
193 {
194 return new JDKDSAPublicKey(info);
195 }
196 else
197 {
198 throw new RuntimeException("algorithm identifier in key not recognised");
199 }
200 }
201
202 /**
203 * create a private key from the given DER encoded input stream.
204 */
205 static PrivateKey createPrivateKeyFromDERStream(
206 InputStream in)
207 throws IOException
208 {
209 return createPrivateKeyFromPrivateKeyInfo(
210 new PrivateKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject())));
211 }
212
213 /**
214 * create a private key from the given public key info object.
215 */
216 static PrivateKey createPrivateKeyFromPrivateKeyInfo(
217 PrivateKeyInfo info)
218 {
219 AlgorithmIdentifier algId = info.getAlgorithmId();
220
221 if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption))
222 {
223 return new JCERSAPrivateCrtKey(info);
224 }
225 else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement))
226 {
227 return new JCEDHPrivateKey(info);
228 }
229 else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa))
230 {
231 return new JDKDSAPrivateKey(info);
232 }
233 else
234 {
235 throw new RuntimeException("algorithm identifier in key not recognised");
236 }
237 }
238
239 public static class RSA
240 extends JDKKeyFactory
241 {
242 public RSA()
243 {
244 }
245
246 protected PrivateKey engineGeneratePrivate(
247 KeySpec keySpec)
248 throws InvalidKeySpecException
249 {
250 if (keySpec instanceof PKCS8EncodedKeySpec)
251 {
252 try
253 {
254 return JDKKeyFactory.createPrivateKeyFromDERStream(
255 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
256 }
257 catch (Exception e)
258 {
259 //
260 // in case it's just a RSAPrivateKey object...
261 //
262 try
263 {
264 return new JCERSAPrivateCrtKey(
265 new RSAPrivateKeyStructure(
266 (ASN1Sequence)new ASN1InputStream(new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())).readObject()));
267 }
268 catch (Exception ex)
269 {
270 throw (InvalidKeySpecException)new InvalidKeySpecException(ex.getMessage()).initCause(ex);
271 }
272 }
273 }
274 else if (keySpec instanceof RSAPrivateCrtKeySpec)
275 {
276 return new JCERSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec);
277 }
278 else if (keySpec instanceof RSAPrivateKeySpec)
279 {
280 return new JCERSAPrivateKey((RSAPrivateKeySpec)keySpec);
281 }
282
283 throw new InvalidKeySpecException("Unknown KeySpec type.");
284 }
285
286 protected PublicKey engineGeneratePublic(
287 KeySpec keySpec)
288 throws InvalidKeySpecException
289 {
290 if (keySpec instanceof X509EncodedKeySpec)
291 {
292 try
293 {
294 return JDKKeyFactory.createPublicKeyFromDERStream(
295 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
296 }
297 catch (Exception e)
298 {
299 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e);
300 }
301 }
302 else if (keySpec instanceof RSAPublicKeySpec)
303 {
304 return new JCERSAPublicKey((RSAPublicKeySpec)keySpec);
305 }
306
307 throw new InvalidKeySpecException("Unknown KeySpec type.");
308 }
309 }
310
311 public static class DH
312 extends JDKKeyFactory
313 {
314 public DH()
315 {
316 }
317
318 protected PrivateKey engineGeneratePrivate(
319 KeySpec keySpec)
320 throws InvalidKeySpecException
321 {
322 if (keySpec instanceof PKCS8EncodedKeySpec)
323 {
324 try
325 {
326 return JDKKeyFactory.createPrivateKeyFromDERStream(
327 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
328 }
329 catch (Exception e)
330 {
331 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e);
332 }
333 }
334 else if (keySpec instanceof DHPrivateKeySpec)
335 {
336 return new JCEDHPrivateKey((DHPrivateKeySpec)keySpec);
337 }
338
339 throw new InvalidKeySpecException("Unknown KeySpec type.");
340 }
341
342 protected PublicKey engineGeneratePublic(
343 KeySpec keySpec)
344 throws InvalidKeySpecException
345 {
346 if (keySpec instanceof X509EncodedKeySpec)
347 {
348 try
349 {
350 return JDKKeyFactory.createPublicKeyFromDERStream(
351 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
352 }
353 catch (Exception e)
354 {
355 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e);
356 }
357 }
358 else if (keySpec instanceof DHPublicKeySpec)
359 {
360 return new JCEDHPublicKey((DHPublicKeySpec)keySpec);
361 }
362
363 throw new InvalidKeySpecException("Unknown KeySpec type.");
364 }
365 }
366
367 public static class DSA
368 extends JDKKeyFactory
369 {
370 public DSA()
371 {
372 }
373
374 protected PrivateKey engineGeneratePrivate(
375 KeySpec keySpec)
376 throws InvalidKeySpecException
377 {
378 if (keySpec instanceof PKCS8EncodedKeySpec)
379 {
380 try
381 {
382 return JDKKeyFactory.createPrivateKeyFromDERStream(
383 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
384 }
385 catch (Exception e)
386 {
387 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e);
388 }
389 }
390 else if (keySpec instanceof DSAPrivateKeySpec)
391 {
392 return new JDKDSAPrivateKey((DSAPrivateKeySpec)keySpec);
393 }
394
395 throw new InvalidKeySpecException("Unknown KeySpec type.");
396 }
397
398 protected PublicKey engineGeneratePublic(
399 KeySpec keySpec)
400 throws InvalidKeySpecException
401 {
402 if (keySpec instanceof X509EncodedKeySpec)
403 {
404 try
405 {
406 return JDKKeyFactory.createPublicKeyFromDERStream(
407 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
408 }
409 catch (Exception e)
410 {
411 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e);
412 }
413 }
414 else if (keySpec instanceof DSAPublicKeySpec)
415 {
416 return new JDKDSAPublicKey((DSAPublicKeySpec)keySpec);
417 }
418
419 throw new InvalidKeySpecException("Unknown KeySpec type.");
420 }
421 }
422
423
424 public static class EC
425 extends JDKKeyFactory
426 {
427 String algorithm;
428
429 public EC()
430 {
431 this("EC");
432 }
433
434 public EC(
435 String algorithm)
436 {
437 this.algorithm = algorithm;
438 }
439
440 protected PrivateKey engineGeneratePrivate(
441 KeySpec keySpec)
442 throws InvalidKeySpecException
443 {
444 if (keySpec instanceof PKCS8EncodedKeySpec)
445 {
446 try
447 {
448 return JDKKeyFactory.createPrivateKeyFromDERStream(
449 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
450 }
451 catch (Exception e)
452 {
453 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e);
454 }
455 }
456
457 throw new InvalidKeySpecException("Unknown KeySpec type.");
458 }
459
460 protected PublicKey engineGeneratePublic(
461 KeySpec keySpec)
462 throws InvalidKeySpecException
463 {
464 if (keySpec instanceof X509EncodedKeySpec)
465 {
466 try
467 {
468 return JDKKeyFactory.createPublicKeyFromDERStream(
469 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded()));
470 }
471 catch (Exception e)
472 {
473 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e);
474 }
475 }
476
477 throw new InvalidKeySpecException("Unknown KeySpec type.");
478 }
479 }
480 }