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: }