1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68:
69: import ;
70: import ;
71: import ;
72: import ;
73:
74:
78: public class EncodedKeyFactory
79: extends KeyFactorySpi
80: {
81: private static final Logger log = Configuration.DEBUG ?
82: Logger.getLogger(EncodedKeyFactory.class.getName()) : null;
83:
84: private static Object invokeConstructor(String className, Object[] params)
85: throws InvalidKeySpecException
86: {
87: Class clazz = getConcreteClass(className);
88: try
89: {
90: Constructor ctor = getConcreteCtor(clazz);
91: Object result = ctor.newInstance(params);
92: return result;
93: }
94: catch (InstantiationException x)
95: {
96: throw new InvalidKeySpecException(x.getMessage(), x);
97: }
98: catch (IllegalAccessException x)
99: {
100: throw new InvalidKeySpecException(x.getMessage(), x);
101: }
102: catch (InvocationTargetException x)
103: {
104: throw new InvalidKeySpecException(x.getMessage(), x);
105: }
106: }
107:
108: private static Class getConcreteClass(String className)
109: throws InvalidKeySpecException
110: {
111: try
112: {
113: Class result = Class.forName(className);
114: return result;
115: }
116: catch (ClassNotFoundException x)
117: {
118: throw new InvalidKeySpecException(x.getMessage(), x);
119: }
120: }
121:
122: private static Constructor getConcreteCtor(Class clazz)
123: throws InvalidKeySpecException
124: {
125: try
126: {
127: Constructor result = clazz.getConstructor(new Class[] {int.class,
128: BigInteger.class,
129: BigInteger.class,
130: BigInteger.class,
131: BigInteger.class});
132: return result;
133: }
134: catch (NoSuchMethodException x)
135: {
136: throw new InvalidKeySpecException(x.getMessage(), x);
137: }
138: }
139:
140: private static Object invokeValueOf(String className, byte[] encoded)
141: throws InvalidKeySpecException
142: {
143: Class clazz = getConcreteClass(className);
144: try
145: {
146: Method valueOf = getValueOfMethod(clazz);
147: Object result = valueOf.invoke(null, new Object[] { encoded });
148: return result;
149: }
150: catch (IllegalAccessException x)
151: {
152: throw new InvalidKeySpecException(x.getMessage(), x);
153: }
154: catch (InvocationTargetException x)
155: {
156: throw new InvalidKeySpecException(x.getMessage(), x);
157: }
158: }
159:
160: private static Method getValueOfMethod(Class clazz)
161: throws InvalidKeySpecException
162: {
163: try
164: {
165: Method result = clazz.getMethod("valueOf", new Class[] {byte[].class});
166: return result;
167: }
168: catch (NoSuchMethodException x)
169: {
170: throw new InvalidKeySpecException(x.getMessage(), x);
171: }
172: }
173:
174: protected PublicKey engineGeneratePublic(KeySpec keySpec)
175: throws InvalidKeySpecException
176: {
177: if (Configuration.DEBUG)
178: log.entering(this.getClass().getName(), "engineGeneratePublic()", keySpec);
179: PublicKey result = null;
180: if (keySpec instanceof DSAPublicKeySpec)
181: result = decodeDSSPublicKey((DSAPublicKeySpec) keySpec);
182: else if (keySpec instanceof RSAPublicKeySpec)
183: result = decodeRSAPublicKey((RSAPublicKeySpec) keySpec);
184: else if (keySpec instanceof DHPublicKeySpec)
185: result = decodeDHPublicKey((DHPublicKeySpec) keySpec);
186: else
187: {
188: if (! (keySpec instanceof X509EncodedKeySpec))
189: throw new InvalidKeySpecException("Unsupported key specification");
190:
191: byte[] input = ((X509EncodedKeySpec) keySpec).getEncoded();
192: boolean ok = false;
193:
194: try
195: {
196: result = DSSPublicKey.valueOf(input);
197: ok = true;
198: }
199: catch (InvalidParameterException ignored)
200: {
201: if (Configuration.DEBUG)
202: log.log(Level.FINE, "Exception in DSSPublicKey.valueOf(). Ignore",
203: ignored);
204: }
205: if (! ok)
206: try
207: {
208: result = GnuRSAPublicKey.valueOf(input);
209: ok = true;
210: }
211: catch (InvalidParameterException ignored)
212: {
213: if (Configuration.DEBUG)
214: log.log(Level.FINE,
215: "Exception in GnuRSAPublicKey.valueOf(). Ignore",
216: ignored);
217: }
218: if (! ok)
219: result = decodeDHPublicKey(input);
220: }
221: if (Configuration.DEBUG)
222: log.exiting(this.getClass().getName(), "engineGeneratePublic()", result);
223: return result;
224: }
225:
226: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
227: throws InvalidKeySpecException
228: {
229: if (Configuration.DEBUG)
230: log.entering(this.getClass().getName(), "engineGeneratePrivate()", keySpec);
231: PrivateKey result = null;
232: if (keySpec instanceof DSAPrivateKeySpec)
233: result = decodeDSSPrivateKey((DSAPrivateKeySpec) keySpec);
234: else if (keySpec instanceof RSAPrivateCrtKeySpec)
235: result = decodeRSAPrivateKey((RSAPrivateCrtKeySpec) keySpec);
236: else if (keySpec instanceof DHPrivateKeySpec)
237: result = decodeDHPrivateKey((DHPrivateKeySpec) keySpec);
238: else
239: {
240: if (! (keySpec instanceof PKCS8EncodedKeySpec))
241: throw new InvalidKeySpecException("Unsupported key specification");
242:
243: byte[] input = ((PKCS8EncodedKeySpec) keySpec).getEncoded();
244: boolean ok = false;
245:
246: try
247: {
248: result = DSSPrivateKey.valueOf(input);
249: ok = true;
250: }
251: catch (InvalidParameterException ignored)
252: {
253: if (Configuration.DEBUG)
254: log.log(Level.FINE, "Exception in DSSPrivateKey.valueOf(). Ignore",
255: ignored);
256: }
257: if (! ok)
258: try
259: {
260: result = GnuRSAPrivateKey.valueOf(input);
261: ok = true;
262: }
263: catch (InvalidParameterException ignored)
264: {
265: if (Configuration.DEBUG)
266: log.log(Level.FINE,
267: "Exception in GnuRSAPrivateKey.valueOf(). Ignore",
268: ignored);
269: }
270: if (! ok)
271: result = decodeDHPrivateKey(input);
272: }
273: if (Configuration.DEBUG)
274: log.exiting(this.getClass().getName(), "engineGeneratePrivate()", result);
275: return result;
276: }
277:
278: protected KeySpec engineGetKeySpec(Key key, Class keySpec)
279: throws InvalidKeySpecException
280: {
281: if (key instanceof PublicKey
282: && Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat())
283: && keySpec.isAssignableFrom(X509EncodedKeySpec.class))
284: return new X509EncodedKeySpec(key.getEncoded());
285:
286: if (key instanceof PrivateKey
287: && Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat())
288: && keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class))
289: return new PKCS8EncodedKeySpec(key.getEncoded());
290:
291: throw new InvalidKeySpecException("Unsupported format or invalid key spec class");
292: }
293:
294: protected Key engineTranslateKey(Key key) throws InvalidKeyException
295: {
296: throw new InvalidKeyException("Key translation not supported");
297: }
298:
299:
304: private DSSPublicKey decodeDSSPublicKey(DSAPublicKeySpec spec)
305: {
306: BigInteger p = spec.getP();
307: BigInteger q = spec.getQ();
308: BigInteger g = spec.getG();
309: BigInteger y = spec.getY();
310: return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
311: }
312:
313:
318: private GnuRSAPublicKey decodeRSAPublicKey(RSAPublicKeySpec spec)
319: {
320: BigInteger n = spec.getModulus();
321: BigInteger e = spec.getPublicExponent();
322: return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
323: }
324:
325:
333: private DHPublicKey decodeDHPublicKey(DHPublicKeySpec spec)
334: throws InvalidKeySpecException
335: {
336: BigInteger p = spec.getP();
337: BigInteger g = spec.getG();
338: BigInteger y = spec.getY();
339: Object[] params = new Object[] {Integer.valueOf(Registry.X509_ENCODING_ID),
340: null, p, g, y};
341: Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPublicKey",
342: params);
343: return (DHPublicKey) obj;
344: }
345:
346:
354: private DHPublicKey decodeDHPublicKey(byte[] encoded)
355: throws InvalidKeySpecException
356: {
357: Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPublicKey",
358: encoded);
359: return (DHPublicKey) obj;
360: }
361:
362:
367: private PrivateKey decodeDSSPrivateKey(DSAPrivateKeySpec spec)
368: {
369: BigInteger p = spec.getP();
370: BigInteger q = spec.getQ();
371: BigInteger g = spec.getG();
372: BigInteger x = spec.getX();
373: return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
374: }
375:
376:
381: private PrivateKey decodeRSAPrivateKey(RSAPrivateCrtKeySpec spec)
382: {
383: BigInteger n = spec.getModulus();
384: BigInteger e = spec.getPublicExponent();
385: BigInteger d = spec.getPrivateExponent();
386: BigInteger p = spec.getPrimeP();
387: BigInteger q = spec.getPrimeQ();
388: BigInteger dP = spec.getPrimeExponentP();
389: BigInteger dQ = spec.getPrimeExponentQ();
390: BigInteger qInv = spec.getCrtCoefficient();
391: return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
392: n, e, d, p, q, dP, dQ, qInv);
393: }
394:
395:
403: private DHPrivateKey decodeDHPrivateKey(DHPrivateKeySpec spec)
404: throws InvalidKeySpecException
405: {
406: BigInteger p = spec.getP();
407: BigInteger g = spec.getG();
408: BigInteger x = spec.getX();
409: Object[] params = new Object[] {Integer.valueOf(Registry.PKCS8_ENCODING_ID),
410: null, p, g, x};
411: Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPrivateKey",
412: params);
413: return (DHPrivateKey) obj;
414: }
415:
416:
424: private DHPrivateKey decodeDHPrivateKey(byte[] encoded)
425: throws InvalidKeySpecException
426: {
427: Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPrivateKey",
428: encoded);
429: return (DHPrivateKey) obj;
430: }
431: }