Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / security / jce / sig / EncodedKeyFactory.java
blob60152c279faf195ade573cd54565dde5ebd653a0
1 /* EncodedKeyFactory.java -- JCE Encoded key factory Adapter
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.security.jce.sig;
41 import gnu.java.security.Registry;
42 import gnu.java.security.key.dss.DSSPrivateKey;
43 import gnu.java.security.key.dss.DSSPublicKey;
44 import gnu.java.security.key.rsa.GnuRSAPrivateKey;
45 import gnu.java.security.key.rsa.GnuRSAPublicKey;
47 import java.lang.reflect.Constructor;
48 import java.lang.reflect.InvocationTargetException;
49 import java.lang.reflect.Method;
50 import java.math.BigInteger;
51 import java.security.InvalidKeyException;
52 import java.security.InvalidParameterException;
53 import java.security.Key;
54 import java.security.KeyFactorySpi;
55 import java.security.PrivateKey;
56 import java.security.PublicKey;
57 import java.security.spec.DSAPrivateKeySpec;
58 import java.security.spec.DSAPublicKeySpec;
59 import java.security.spec.InvalidKeySpecException;
60 import java.security.spec.KeySpec;
61 import java.security.spec.PKCS8EncodedKeySpec;
62 import java.security.spec.RSAPrivateCrtKeySpec;
63 import java.security.spec.RSAPublicKeySpec;
64 import java.security.spec.X509EncodedKeySpec;
65 import java.util.logging.Level;
66 import java.util.logging.Logger;
68 import javax.crypto.interfaces.DHPrivateKey;
69 import javax.crypto.interfaces.DHPublicKey;
70 import javax.crypto.spec.DHPrivateKeySpec;
71 import javax.crypto.spec.DHPublicKeySpec;
73 /**
74 * A factory for keys encoded in either the X.509 format (for public keys) or
75 * the PKCS#8 format (for private keys).
77 public class EncodedKeyFactory
78 extends KeyFactorySpi
80 private static final Logger log = Logger.getLogger(EncodedKeyFactory.class.getName());
82 // implicit 0-arguments constructor
84 // Class methods
85 // --------------------------------------------------------------------------
87 private static Object invokeConstructor(String className, Object[] params)
88 throws InvalidKeySpecException
90 Class clazz = getConcreteClass(className);
91 try
93 Constructor ctor = getConcreteCtor(clazz);
94 Object result = ctor.newInstance(params);
95 return result;
97 catch (InstantiationException x)
99 InvalidKeySpecException y = new InvalidKeySpecException();
100 y.initCause(x);
101 throw y;
103 catch (IllegalAccessException x)
105 InvalidKeySpecException y = new InvalidKeySpecException();
106 y.initCause(y);
107 throw y;
109 catch (InvocationTargetException x)
111 InvalidKeySpecException y = new InvalidKeySpecException();
112 y.initCause(x);
113 throw y;
117 private static Class getConcreteClass(String className)
118 throws InvalidKeySpecException
122 Class result = Class.forName(className);
123 return result;
125 catch (ClassNotFoundException x)
127 InvalidKeySpecException y = new InvalidKeySpecException();
128 y.initCause(x);
129 throw y;
133 private static Constructor getConcreteCtor(Class clazz)
134 throws InvalidKeySpecException
138 Constructor result = clazz.getConstructor(new Class[] {int.class,
139 BigInteger.class,
140 BigInteger.class,
141 BigInteger.class,
142 BigInteger.class});
143 return result;
145 catch (NoSuchMethodException x)
147 InvalidKeySpecException y = new InvalidKeySpecException();
148 y.initCause(x);
149 throw y;
153 private static Object invokeValueOf(String className, byte[] encoded)
154 throws InvalidKeySpecException
156 Class clazz = getConcreteClass(className);
159 Method valueOf = getValueOfMethod(clazz);
160 Object result = valueOf.invoke(null, new Object[] { encoded });
161 return result;
163 catch (IllegalAccessException x)
165 InvalidKeySpecException y = new InvalidKeySpecException();
166 y.initCause(x);
167 throw y;
169 catch (InvocationTargetException x)
171 InvalidKeySpecException y = new InvalidKeySpecException();
172 y.initCause(x);
173 throw y;
177 private static Method getValueOfMethod(Class clazz)
178 throws InvalidKeySpecException
182 Method result = clazz.getMethod("valueOf", new Class[] {byte[].class});
183 return result;
185 catch (NoSuchMethodException x)
187 InvalidKeySpecException y = new InvalidKeySpecException();
188 y.initCause(x);
189 throw y;
193 // Instance methods
194 // --------------------------------------------------------------------------
196 protected PublicKey engineGeneratePublic(KeySpec keySpec)
197 throws InvalidKeySpecException
199 log.entering(this.getClass().getName(), "engineGeneratePublic()", keySpec);
201 PublicKey result = null;
202 if (keySpec instanceof DSAPublicKeySpec)
203 result = decodeDSSPublicKey((DSAPublicKeySpec) keySpec);
204 else if (keySpec instanceof RSAPublicKeySpec)
205 result = decodeRSAPublicKey((RSAPublicKeySpec) keySpec);
206 else if (keySpec instanceof DHPublicKeySpec)
207 result = decodeDHPublicKey((DHPublicKeySpec) keySpec);
208 else
210 if (! (keySpec instanceof X509EncodedKeySpec))
211 throw new InvalidKeySpecException("Unsupported key specification");
213 byte[] input = ((X509EncodedKeySpec) keySpec).getEncoded();
214 boolean ok = false;
215 // try DSS
218 result = DSSPublicKey.valueOf(input);
219 ok = true;
221 catch (InvalidParameterException ignored)
223 log.log(Level.FINE, "Exception in DSSPublicKey.valueOf(). Ignore",
224 ignored);
227 if (! ok) // try RSA
230 result = GnuRSAPublicKey.valueOf(input);
231 ok = true;
233 catch (InvalidParameterException ignored)
235 log.log(Level.FINE,
236 "Exception in GnuRSAPublicKey.valueOf(). Ignore",
237 ignored);
240 if (! ok) // try DH
241 result = decodeDHPublicKey(input);
244 log.exiting(this.getClass().getName(), "engineGeneratePublic()", result);
245 return result;
248 protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
249 throws InvalidKeySpecException
251 log.entering(this.getClass().getName(), "engineGeneratePrivate()", keySpec);
253 PrivateKey result = null;
254 if (keySpec instanceof DSAPrivateKeySpec)
255 result = decodeDSSPrivateKey((DSAPrivateKeySpec) keySpec);
256 else if (keySpec instanceof RSAPrivateCrtKeySpec)
257 result = decodeRSAPrivateKey((RSAPrivateCrtKeySpec) keySpec);
258 else if (keySpec instanceof DHPrivateKeySpec)
259 result = decodeDHPrivateKey((DHPrivateKeySpec) keySpec);
260 else
262 if (! (keySpec instanceof PKCS8EncodedKeySpec))
263 throw new InvalidKeySpecException("Unsupported key specification");
265 byte[] input = ((PKCS8EncodedKeySpec) keySpec).getEncoded();
266 boolean ok = false;
267 // try DSS
270 result = DSSPrivateKey.valueOf(input);
271 ok = true;
273 catch (InvalidParameterException ignored)
275 log.log(Level.FINE, "Exception in DSSPrivateKey.valueOf(). Ignore",
276 ignored);
279 if (! ok) // try RSA
282 result = GnuRSAPrivateKey.valueOf(input);
283 ok = true;
285 catch (InvalidParameterException ignored)
287 log.log(Level.FINE,
288 "Exception in GnuRSAPrivateKey.valueOf(). Ignore",
289 ignored);
292 if (! ok) // try DH
293 result = decodeDHPrivateKey(input);
296 log.exiting(this.getClass().getName(), "engineGeneratePrivate()", result);
297 return result;
300 protected KeySpec engineGetKeySpec(Key key, Class keySpec)
301 throws InvalidKeySpecException
303 if (key instanceof PublicKey
304 && Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat())
305 && keySpec.isAssignableFrom(X509EncodedKeySpec.class))
306 return new X509EncodedKeySpec(key.getEncoded());
308 if (key instanceof PrivateKey
309 && Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat())
310 && keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class))
311 return new PKCS8EncodedKeySpec(key.getEncoded());
313 throw new InvalidKeySpecException("Unsupported format or invalid key spec class");
316 protected Key engineTranslateKey(Key key) throws InvalidKeyException
318 throw new InvalidKeyException("Key translation not supported");
322 * @param spec an instance of {@link DSAPublicKeySpec} to decode.
323 * @return an instance of {@link DSSPublicKey} constructed from the
324 * information in the designated key-specification.
326 private DSSPublicKey decodeDSSPublicKey(DSAPublicKeySpec spec)
328 BigInteger p = spec.getP();
329 BigInteger q = spec.getQ();
330 BigInteger g = spec.getG();
331 BigInteger y = spec.getY();
332 return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
336 * @param spec an instance of {@link RSAPublicKeySpec} to decode.
337 * @return an instance of {@link GnuRSAPublicKey} constructed from the
338 * information in the designated key-specification.
340 private GnuRSAPublicKey decodeRSAPublicKey(RSAPublicKeySpec spec)
342 BigInteger n = spec.getModulus();
343 BigInteger e = spec.getPublicExponent();
344 return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
348 * @param spec an instance of {@link DHPublicKeySpec} to decode.
349 * @return an instance of a {@link DHPublicKey} constructed from the
350 * information in the designated key-specification.
351 * @throws InvalidKeySpecException if no concrete implementation of the
352 * {@link DHPublicKey} interface exists at run-time, or if an
353 * exception occurs during its instantiation.
355 private DHPublicKey decodeDHPublicKey(DHPublicKeySpec spec)
356 throws InvalidKeySpecException
358 BigInteger p = spec.getP();
359 BigInteger g = spec.getG();
360 BigInteger y = spec.getY();
361 Object[] params = new Object[] {new Integer(Registry.X509_ENCODING_ID),
362 null, p, g, y};
363 Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPublicKey",
364 params);
365 return (DHPublicKey) obj;
369 * @param encoded the bytes to decode.
370 * @return an instance of a {@link DHPublicKey} constructed from the
371 * information in the designated key-specification.
372 * @throws InvalidKeySpecException if no concrete implementation of the
373 * {@link DHPublicKey} interface exists at run-time, or if an
374 * exception occurs during its instantiation.
376 private DHPublicKey decodeDHPublicKey(byte[] encoded)
377 throws InvalidKeySpecException
379 Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPublicKey",
380 encoded);
381 return (DHPublicKey) obj;
385 * @param spec an instance of {@link DSAPrivateKeySpec} to decode.
386 * @return an instance of {@link DSSPrivateKey} constructed from the
387 * information in the designated key-specification.
389 private PrivateKey decodeDSSPrivateKey(DSAPrivateKeySpec spec)
391 BigInteger p = spec.getP();
392 BigInteger q = spec.getQ();
393 BigInteger g = spec.getG();
394 BigInteger x = spec.getX();
395 return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
399 * @param spec an instance of {@link RSAPrivateCrtKeySpec} to decode.
400 * @return an instance of {@link GnuRSAPrivateKey} constructed from the
401 * information in the designated key-specification.
403 private PrivateKey decodeRSAPrivateKey(RSAPrivateCrtKeySpec spec)
405 BigInteger n = spec.getModulus();
406 BigInteger e = spec.getPublicExponent();
407 BigInteger d = spec.getPrivateExponent();
408 BigInteger p = spec.getPrimeP();
409 BigInteger q = spec.getPrimeQ();
410 BigInteger dP = spec.getPrimeExponentP();
411 BigInteger dQ = spec.getPrimeExponentQ();
412 BigInteger qInv = spec.getCrtCoefficient();
413 return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
414 n, e, d, p, q, dP, dQ, qInv);
418 * @param spec an instance of {@link DHPrivateKeySpec} to decode.
419 * @return an instance of a {@link DHPrivateKey} constructed from the
420 * information in the designated key-specification.
421 * @throws InvalidKeySpecException if no concrete implementation of the
422 * {@link DHPrivateKey} interface exists at run-time, or if an
423 * exception occurs during its instantiation.
425 private DHPrivateKey decodeDHPrivateKey(DHPrivateKeySpec spec)
426 throws InvalidKeySpecException
428 BigInteger p = spec.getP();
429 BigInteger g = spec.getG();
430 BigInteger x = spec.getX();
431 Object[] params = new Object[] {new Integer(Registry.PKCS8_ENCODING_ID),
432 null, p, g, x};
433 Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPrivateKey",
434 params);
435 return (DHPrivateKey) obj;
439 * @param encoded the bytes to decode.
440 * @return an instance of a {@link DHPrivateKey} constructed from the
441 * information in the designated key-specification.
442 * @throws InvalidKeySpecException if no concrete implementation of the
443 * {@link DHPrivateKey} interface exists at run-time, or if an
444 * exception occurs during its instantiation.
446 private DHPrivateKey decodeDHPrivateKey(byte[] encoded)
447 throws InvalidKeySpecException
449 Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPrivateKey",
450 encoded);
451 return (DHPrivateKey) obj;