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