001: package org.bouncycastle.jce.provider;
002:
003: import org.bouncycastle.asn1.ASN1InputStream;
004: import org.bouncycastle.asn1.ASN1Sequence;
005: import org.bouncycastle.asn1.DERObjectIdentifier;
006: import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
007: import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
008: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
009: import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
010: import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
011: import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
012: import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
013: import org.bouncycastle.jce.interfaces.ElGamalPrivateKey;
014: import org.bouncycastle.jce.interfaces.ElGamalPublicKey;
015: import org.bouncycastle.jce.spec.ECPrivateKeySpec;
016: import org.bouncycastle.jce.spec.ECPublicKeySpec;
017: import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec;
018: import org.bouncycastle.jce.spec.ElGamalPublicKeySpec;
019: import org.bouncycastle.jce.spec.GOST3410PrivateKeySpec;
020: import org.bouncycastle.jce.spec.GOST3410PublicKeySpec;
021:
022: import javax.crypto.interfaces.DHPrivateKey;
023: import javax.crypto.interfaces.DHPublicKey;
024: import javax.crypto.spec.DHPrivateKeySpec;
025: import javax.crypto.spec.DHPublicKeySpec;
026: import java.io.IOException;
027: import java.security.InvalidKeyException;
028: import java.security.Key;
029: import java.security.KeyFactorySpi;
030: import java.security.PrivateKey;
031: import java.security.PublicKey;
032: import java.security.interfaces.DSAPrivateKey;
033: import java.security.interfaces.DSAPublicKey;
034: import java.security.interfaces.ECPrivateKey;
035: import java.security.interfaces.ECPublicKey;
036: import java.security.interfaces.RSAPrivateCrtKey;
037: import java.security.interfaces.RSAPrivateKey;
038: import java.security.interfaces.RSAPublicKey;
039: import java.security.spec.DSAPrivateKeySpec;
040: import java.security.spec.DSAPublicKeySpec;
041: import java.security.spec.InvalidKeySpecException;
042: import java.security.spec.KeySpec;
043: import java.security.spec.PKCS8EncodedKeySpec;
044: import java.security.spec.RSAPrivateCrtKeySpec;
045: import java.security.spec.RSAPrivateKeySpec;
046: import java.security.spec.RSAPublicKeySpec;
047: import java.security.spec.X509EncodedKeySpec;
048:
049: public abstract class JDKKeyFactory extends KeyFactorySpi {
050: protected boolean elGamalFactory = false;
051:
052: public JDKKeyFactory() {
053: }
054:
055: protected KeySpec engineGetKeySpec(Key key, Class spec)
056: throws InvalidKeySpecException {
057: if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class)
058: && key.getFormat().equals("PKCS#8")) {
059: return new PKCS8EncodedKeySpec(key.getEncoded());
060: } else if (spec.isAssignableFrom(X509EncodedKeySpec.class)
061: && key.getFormat().equals("X.509")) {
062: return new X509EncodedKeySpec(key.getEncoded());
063: } else if (spec.isAssignableFrom(RSAPublicKeySpec.class)
064: && key instanceof RSAPublicKey) {
065: RSAPublicKey k = (RSAPublicKey) key;
066:
067: return new RSAPublicKeySpec(k.getModulus(), k
068: .getPublicExponent());
069: } else if (spec.isAssignableFrom(RSAPrivateKeySpec.class)
070: && key instanceof RSAPrivateKey) {
071: RSAPrivateKey k = (RSAPrivateKey) key;
072:
073: return new RSAPrivateKeySpec(k.getModulus(), k
074: .getPrivateExponent());
075: } else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class)
076: && key instanceof RSAPrivateCrtKey) {
077: RSAPrivateCrtKey k = (RSAPrivateCrtKey) key;
078:
079: return new RSAPrivateCrtKeySpec(k.getModulus(), k
080: .getPublicExponent(), k.getPrivateExponent(), k
081: .getPrimeP(), k.getPrimeQ(), k.getPrimeExponentP(),
082: k.getPrimeExponentQ(), k.getCrtCoefficient());
083: } else if (spec.isAssignableFrom(DHPrivateKeySpec.class)
084: && key instanceof DHPrivateKey) {
085: DHPrivateKey k = (DHPrivateKey) key;
086:
087: return new DHPrivateKeySpec(k.getX(), k.getParams().getP(),
088: k.getParams().getG());
089: } else if (spec.isAssignableFrom(DHPublicKeySpec.class)
090: && key instanceof DHPublicKey) {
091: DHPublicKey k = (DHPublicKey) key;
092:
093: return new DHPublicKeySpec(k.getY(), k.getParams().getP(),
094: k.getParams().getG());
095: } else if (spec
096: .isAssignableFrom(java.security.spec.ECPublicKeySpec.class)
097: && key instanceof ECPublicKey) {
098: ECPublicKey k = (ECPublicKey) key;
099:
100: return new java.security.spec.ECPublicKeySpec(k.getW(), k
101: .getParams());
102: } else if (spec
103: .isAssignableFrom(java.security.spec.ECPrivateKeySpec.class)
104: && key instanceof ECPrivateKey) {
105: ECPrivateKey k = (ECPrivateKey) key;
106:
107: return new java.security.spec.ECPrivateKeySpec(k.getS(), k
108: .getParams());
109: }
110:
111: throw new RuntimeException("not implemented yet " + key + " "
112: + spec);
113: }
114:
115: protected Key engineTranslateKey(Key key)
116: throws InvalidKeyException {
117: if (key instanceof RSAPublicKey) {
118: return new JCERSAPublicKey((RSAPublicKey) key);
119: } else if (key instanceof RSAPrivateCrtKey) {
120: return new JCERSAPrivateCrtKey((RSAPrivateCrtKey) key);
121: } else if (key instanceof RSAPrivateKey) {
122: return new JCERSAPrivateKey((RSAPrivateKey) key);
123: } else if (key instanceof DHPublicKey) {
124: if (elGamalFactory) {
125: return new JCEElGamalPublicKey((DHPublicKey) key);
126: } else {
127: return new JCEDHPublicKey((DHPublicKey) key);
128: }
129: } else if (key instanceof DHPrivateKey) {
130: if (elGamalFactory) {
131: return new JCEElGamalPrivateKey((DHPrivateKey) key);
132: } else {
133: return new JCEDHPrivateKey((DHPrivateKey) key);
134: }
135: } else if (key instanceof DSAPublicKey) {
136: return new JDKDSAPublicKey((DSAPublicKey) key);
137: } else if (key instanceof DSAPrivateKey) {
138: return new JDKDSAPrivateKey((DSAPrivateKey) key);
139: } else if (key instanceof ElGamalPublicKey) {
140: return new JCEElGamalPublicKey((ElGamalPublicKey) key);
141: } else if (key instanceof ElGamalPrivateKey) {
142: return new JCEElGamalPrivateKey((ElGamalPrivateKey) key);
143: } else if (key instanceof ECPublicKey) {
144: return new JCEECPublicKey((ECPublicKey) key);
145: } else if (key instanceof ECPrivateKey) {
146: return new JCEECPrivateKey((ECPrivateKey) key);
147: }
148:
149: throw new InvalidKeyException("key type unknown");
150: }
151:
152: /**
153: * create a public key from the given DER encoded input stream.
154: */
155: static PublicKey createPublicKeyFromDERStream(byte[] in)
156: throws IOException {
157: return createPublicKeyFromPublicKeyInfo(new SubjectPublicKeyInfo(
158: (ASN1Sequence) (new ASN1InputStream(in).readObject())));
159: }
160:
161: /**
162: * create a public key from the given public key info object.
163: */
164: static PublicKey createPublicKeyFromPublicKeyInfo(
165: SubjectPublicKeyInfo info) {
166: DERObjectIdentifier algOid = info.getAlgorithmId()
167: .getObjectId();
168:
169: if (RSAUtil.isRsaOid(algOid)) {
170: return new JCERSAPublicKey(info);
171: } else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) {
172: return new JCEDHPublicKey(info);
173: } else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber)) {
174: return new JCEDHPublicKey(info);
175: } else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm)) {
176: return new JCEElGamalPublicKey(info);
177: } else if (algOid.equals(X9ObjectIdentifiers.id_dsa)) {
178: return new JDKDSAPublicKey(info);
179: } else if (algOid.equals(OIWObjectIdentifiers.dsaWithSHA1)) {
180: return new JDKDSAPublicKey(info);
181: } else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) {
182: return new JCEECPublicKey(info);
183: } else if (algOid
184: .equals(CryptoProObjectIdentifiers.gostR3410_94)) {
185: return new JDKGOST3410PublicKey(info);
186: } else if (algOid
187: .equals(CryptoProObjectIdentifiers.gostR3410_2001)) {
188: return new JCEECPublicKey(info);
189: } else {
190: throw new RuntimeException("algorithm identifier " + algOid
191: + " in key not recognised");
192: }
193: }
194:
195: /**
196: * create a private key from the given DER encoded input stream.
197: */
198: static PrivateKey createPrivateKeyFromDERStream(byte[] in)
199: throws IOException {
200: return createPrivateKeyFromPrivateKeyInfo(new PrivateKeyInfo(
201: (ASN1Sequence) (new ASN1InputStream(in).readObject())));
202: }
203:
204: /**
205: * create a private key from the given public key info object.
206: */
207: static PrivateKey createPrivateKeyFromPrivateKeyInfo(
208: PrivateKeyInfo info) {
209: DERObjectIdentifier algOid = info.getAlgorithmId()
210: .getObjectId();
211:
212: if (RSAUtil.isRsaOid(algOid)) {
213: return new JCERSAPrivateCrtKey(info);
214: } else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) {
215: return new JCEDHPrivateKey(info);
216: } else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm)) {
217: return new JCEElGamalPrivateKey(info);
218: } else if (algOid.equals(X9ObjectIdentifiers.id_dsa)) {
219: return new JDKDSAPrivateKey(info);
220: } else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) {
221: return new JCEECPrivateKey(info);
222: } else if (algOid
223: .equals(CryptoProObjectIdentifiers.gostR3410_94)) {
224: return new JDKGOST3410PrivateKey(info);
225: } else if (algOid
226: .equals(CryptoProObjectIdentifiers.gostR3410_2001)) {
227: return new JCEECPrivateKey(info);
228: } else {
229: throw new RuntimeException("algorithm identifier " + algOid
230: + " in key not recognised");
231: }
232: }
233:
234: public static class RSA extends JDKKeyFactory {
235: public RSA() {
236: }
237:
238: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
239: throws InvalidKeySpecException {
240: if (keySpec instanceof PKCS8EncodedKeySpec) {
241: try {
242: return JDKKeyFactory
243: .createPrivateKeyFromDERStream(((PKCS8EncodedKeySpec) keySpec)
244: .getEncoded());
245: } catch (Exception e) {
246: //
247: // in case it's just a RSAPrivateKey object...
248: //
249: try {
250: return new JCERSAPrivateCrtKey(
251: new RSAPrivateKeyStructure(
252: (ASN1Sequence) new ASN1InputStream(
253: ((PKCS8EncodedKeySpec) keySpec)
254: .getEncoded())
255: .readObject()));
256: } catch (Exception ex) {
257: throw new InvalidKeySpecException(ex.toString());
258: }
259: }
260: } else if (keySpec instanceof RSAPrivateCrtKeySpec) {
261: return new JCERSAPrivateCrtKey(
262: (RSAPrivateCrtKeySpec) keySpec);
263: } else if (keySpec instanceof RSAPrivateKeySpec) {
264: return new JCERSAPrivateKey((RSAPrivateKeySpec) keySpec);
265: }
266:
267: throw new InvalidKeySpecException("Unknown KeySpec type: "
268: + keySpec.getClass().getName());
269: }
270:
271: protected PublicKey engineGeneratePublic(KeySpec keySpec)
272: throws InvalidKeySpecException {
273: if (keySpec instanceof X509EncodedKeySpec) {
274: try {
275: return JDKKeyFactory
276: .createPublicKeyFromDERStream(((X509EncodedKeySpec) keySpec)
277: .getEncoded());
278: } catch (Exception e) {
279: throw new InvalidKeySpecException(e.toString());
280: }
281: } else if (keySpec instanceof RSAPublicKeySpec) {
282: return new JCERSAPublicKey((RSAPublicKeySpec) keySpec);
283: }
284:
285: throw new InvalidKeySpecException("Unknown KeySpec type: "
286: + keySpec.getClass().getName());
287: }
288: }
289:
290: public static class DH extends JDKKeyFactory {
291: public DH() {
292: }
293:
294: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
295: throws InvalidKeySpecException {
296: if (keySpec instanceof PKCS8EncodedKeySpec) {
297: try {
298: return JDKKeyFactory
299: .createPrivateKeyFromDERStream(((PKCS8EncodedKeySpec) keySpec)
300: .getEncoded());
301: } catch (Exception e) {
302: throw new InvalidKeySpecException(e.toString());
303: }
304: } else if (keySpec instanceof DHPrivateKeySpec) {
305: return new JCEDHPrivateKey((DHPrivateKeySpec) keySpec);
306: }
307:
308: throw new InvalidKeySpecException("Unknown KeySpec type: "
309: + keySpec.getClass().getName());
310: }
311:
312: protected PublicKey engineGeneratePublic(KeySpec keySpec)
313: throws InvalidKeySpecException {
314: if (keySpec instanceof X509EncodedKeySpec) {
315: try {
316: return JDKKeyFactory
317: .createPublicKeyFromDERStream(((X509EncodedKeySpec) keySpec)
318: .getEncoded());
319: } catch (Exception e) {
320: throw new InvalidKeySpecException(e.toString());
321: }
322: } else if (keySpec instanceof DHPublicKeySpec) {
323: return new JCEDHPublicKey((DHPublicKeySpec) keySpec);
324: }
325:
326: throw new InvalidKeySpecException("Unknown KeySpec type: "
327: + keySpec.getClass().getName());
328: }
329: }
330:
331: public static class DSA extends JDKKeyFactory {
332: public DSA() {
333: }
334:
335: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
336: throws InvalidKeySpecException {
337: if (keySpec instanceof PKCS8EncodedKeySpec) {
338: try {
339: return JDKKeyFactory
340: .createPrivateKeyFromDERStream(((PKCS8EncodedKeySpec) keySpec)
341: .getEncoded());
342: } catch (Exception e) {
343: throw new InvalidKeySpecException(e.toString());
344: }
345: } else if (keySpec instanceof DSAPrivateKeySpec) {
346: return new JDKDSAPrivateKey((DSAPrivateKeySpec) keySpec);
347: }
348:
349: throw new InvalidKeySpecException("Unknown KeySpec type: "
350: + keySpec.getClass().getName());
351: }
352:
353: protected PublicKey engineGeneratePublic(KeySpec keySpec)
354: throws InvalidKeySpecException {
355: if (keySpec instanceof X509EncodedKeySpec) {
356: try {
357: return JDKKeyFactory
358: .createPublicKeyFromDERStream(((X509EncodedKeySpec) keySpec)
359: .getEncoded());
360: } catch (Exception e) {
361: throw new InvalidKeySpecException(e.toString());
362: }
363: } else if (keySpec instanceof DSAPublicKeySpec) {
364: return new JDKDSAPublicKey((DSAPublicKeySpec) keySpec);
365: }
366:
367: throw new InvalidKeySpecException("Unknown KeySpec type: "
368: + keySpec.getClass().getName());
369: }
370: }
371:
372: public static class GOST3410 extends JDKKeyFactory {
373: public GOST3410() {
374: }
375:
376: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
377: throws InvalidKeySpecException {
378: if (keySpec instanceof PKCS8EncodedKeySpec) {
379: try {
380: return JDKKeyFactory
381: .createPrivateKeyFromDERStream(((PKCS8EncodedKeySpec) keySpec)
382: .getEncoded());
383: } catch (Exception e) {
384: throw new InvalidKeySpecException(e.toString());
385: }
386: } else if (keySpec instanceof GOST3410PrivateKeySpec) {
387: return new JDKGOST3410PrivateKey(
388: (GOST3410PrivateKeySpec) keySpec);
389: }
390:
391: throw new InvalidKeySpecException("Unknown KeySpec type: "
392: + keySpec.getClass().getName());
393: }
394:
395: protected PublicKey engineGeneratePublic(KeySpec keySpec)
396: throws InvalidKeySpecException {
397: if (keySpec instanceof X509EncodedKeySpec) {
398: try {
399: return JDKKeyFactory
400: .createPublicKeyFromDERStream(((X509EncodedKeySpec) keySpec)
401: .getEncoded());
402: } catch (Exception e) {
403: throw new InvalidKeySpecException(e.toString());
404: }
405: } else if (keySpec instanceof GOST3410PublicKeySpec) {
406: return new JDKGOST3410PublicKey(
407: (GOST3410PublicKeySpec) keySpec);
408: }
409:
410: throw new InvalidKeySpecException("Unknown KeySpec type: "
411: + keySpec.getClass().getName());
412: }
413: }
414:
415: public static class ElGamal extends JDKKeyFactory {
416: public ElGamal() {
417: elGamalFactory = true;
418: }
419:
420: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
421: throws InvalidKeySpecException {
422: if (keySpec instanceof PKCS8EncodedKeySpec) {
423: try {
424: return JDKKeyFactory
425: .createPrivateKeyFromDERStream(((PKCS8EncodedKeySpec) keySpec)
426: .getEncoded());
427: } catch (Exception e) {
428: throw new InvalidKeySpecException(e.toString());
429: }
430: } else if (keySpec instanceof ElGamalPrivateKeySpec) {
431: return new JCEElGamalPrivateKey(
432: (ElGamalPrivateKeySpec) keySpec);
433: } else if (keySpec instanceof DHPrivateKeySpec) {
434: return new JCEElGamalPrivateKey(
435: (DHPrivateKeySpec) keySpec);
436: }
437:
438: throw new InvalidKeySpecException("Unknown KeySpec type: "
439: + keySpec.getClass().getName());
440: }
441:
442: protected PublicKey engineGeneratePublic(KeySpec keySpec)
443: throws InvalidKeySpecException {
444: if (keySpec instanceof X509EncodedKeySpec) {
445: try {
446: return JDKKeyFactory
447: .createPublicKeyFromDERStream(((X509EncodedKeySpec) keySpec)
448: .getEncoded());
449: } catch (Exception e) {
450: throw new InvalidKeySpecException(e.toString());
451: }
452: } else if (keySpec instanceof ElGamalPublicKeySpec) {
453: return new JCEElGamalPublicKey(
454: (ElGamalPublicKeySpec) keySpec);
455: } else if (keySpec instanceof DHPublicKeySpec) {
456: return new JCEElGamalPublicKey(
457: (DHPublicKeySpec) keySpec);
458: }
459:
460: throw new InvalidKeySpecException("Unknown KeySpec type: "
461: + keySpec.getClass().getName());
462: }
463: }
464:
465: /**
466: * This isn't really correct, however the class path project API seems to think such
467: * a key factory will exist.
468: */
469: public static class X509 extends JDKKeyFactory {
470: public X509() {
471: }
472:
473: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
474: throws InvalidKeySpecException {
475: if (keySpec instanceof PKCS8EncodedKeySpec) {
476: try {
477: return JDKKeyFactory
478: .createPrivateKeyFromDERStream(((PKCS8EncodedKeySpec) keySpec)
479: .getEncoded());
480: } catch (Exception e) {
481: throw new InvalidKeySpecException(e.toString());
482: }
483: }
484:
485: throw new InvalidKeySpecException("Unknown KeySpec type: "
486: + keySpec.getClass().getName());
487: }
488:
489: protected PublicKey engineGeneratePublic(KeySpec keySpec)
490: throws InvalidKeySpecException {
491: if (keySpec instanceof X509EncodedKeySpec) {
492: try {
493: return JDKKeyFactory
494: .createPublicKeyFromDERStream(((X509EncodedKeySpec) keySpec)
495: .getEncoded());
496: } catch (Exception e) {
497: throw new InvalidKeySpecException(e.toString());
498: }
499: }
500:
501: throw new InvalidKeySpecException("Unknown KeySpec type: "
502: + keySpec.getClass().getName());
503: }
504: }
505:
506: public static class EC extends JDKKeyFactory {
507: String algorithm;
508:
509: public EC() {
510: this ("EC");
511: }
512:
513: public EC(String algorithm) {
514: this .algorithm = algorithm;
515: }
516:
517: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
518: throws InvalidKeySpecException {
519: if (keySpec instanceof PKCS8EncodedKeySpec) {
520: try {
521: JCEECPrivateKey key = (JCEECPrivateKey) JDKKeyFactory
522: .createPrivateKeyFromDERStream(((PKCS8EncodedKeySpec) keySpec)
523: .getEncoded());
524:
525: return new JCEECPrivateKey(algorithm, key);
526: } catch (Exception e) {
527: throw new InvalidKeySpecException(e.toString());
528: }
529: } else if (keySpec instanceof ECPrivateKeySpec) {
530: return new JCEECPrivateKey(algorithm,
531: (ECPrivateKeySpec) keySpec);
532: } else if (keySpec instanceof java.security.spec.ECPrivateKeySpec) {
533: return new JCEECPrivateKey(algorithm,
534: (java.security.spec.ECPrivateKeySpec) keySpec);
535: }
536:
537: throw new InvalidKeySpecException("Unknown KeySpec type: "
538: + keySpec.getClass().getName());
539: }
540:
541: protected PublicKey engineGeneratePublic(KeySpec keySpec)
542: throws InvalidKeySpecException {
543: if (keySpec instanceof X509EncodedKeySpec) {
544: try {
545: JCEECPublicKey key = (JCEECPublicKey) JDKKeyFactory
546: .createPublicKeyFromDERStream(((X509EncodedKeySpec) keySpec)
547: .getEncoded());
548:
549: return new JCEECPublicKey(algorithm, key);
550: } catch (Exception e) {
551: throw new InvalidKeySpecException(e.toString());
552: }
553: } else if (keySpec instanceof ECPublicKeySpec) {
554: return new JCEECPublicKey(algorithm,
555: (ECPublicKeySpec) keySpec);
556: } else if (keySpec instanceof java.security.spec.ECPublicKeySpec) {
557: return new JCEECPublicKey(algorithm,
558: (java.security.spec.ECPublicKeySpec) keySpec);
559: }
560:
561: throw new InvalidKeySpecException("Unknown KeySpec type: "
562: + keySpec.getClass().getName());
563: }
564: }
565:
566: public static class ECDSA extends EC {
567: public ECDSA() {
568: super ("ECDSA");
569: }
570: }
571:
572: public static class ECGOST3410 extends EC {
573: public ECGOST3410() {
574: super ("ECGOST3410");
575: }
576: }
577:
578: public static class ECDH extends EC {
579: public ECDH() {
580: super ("ECDH");
581: }
582: }
583:
584: public static class ECDHC extends EC {
585: public ECDHC() {
586: super ("ECDHC");
587: }
588: }
589: }
|