1package org.bouncycastle.jce.provider; 2 3import java.io.IOException; 4import java.security.InvalidKeyException; 5import java.security.Key; 6import java.security.KeyFactorySpi; 7import java.security.PrivateKey; 8import java.security.PublicKey; 9import java.security.interfaces.DSAPrivateKey; 10import java.security.interfaces.DSAPublicKey; 11import java.security.interfaces.RSAPrivateCrtKey; 12import java.security.interfaces.RSAPrivateKey; 13import java.security.interfaces.RSAPublicKey; 14import java.security.spec.DSAPrivateKeySpec; 15import java.security.spec.DSAPublicKeySpec; 16import java.security.spec.InvalidKeySpecException; 17import java.security.spec.KeySpec; 18import java.security.spec.PKCS8EncodedKeySpec; 19import java.security.spec.RSAPrivateCrtKeySpec; 20import java.security.spec.RSAPrivateKeySpec; 21import java.security.spec.RSAPublicKeySpec; 22import java.security.spec.X509EncodedKeySpec; 23 24import javax.crypto.interfaces.DHPrivateKey; 25import javax.crypto.interfaces.DHPublicKey; 26import javax.crypto.spec.DHPrivateKeySpec; 27import javax.crypto.spec.DHPublicKeySpec; 28 29import org.bouncycastle.asn1.ASN1Object; 30import org.bouncycastle.asn1.ASN1Sequence; 31import org.bouncycastle.asn1.DERObjectIdentifier; 32import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; 33import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 34import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 35import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 36import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; 37import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 38import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 39// BEGIN android-removed 40// import org.bouncycastle.jce.interfaces.ElGamalPrivateKey; 41// import org.bouncycastle.jce.interfaces.ElGamalPublicKey; 42// import org.bouncycastle.jce.spec.ElGamalPrivateKeySpec; 43// import org.bouncycastle.jce.spec.ElGamalPublicKeySpec; 44// import org.bouncycastle.jce.spec.GOST3410PrivateKeySpec; 45// import org.bouncycastle.jce.spec.GOST3410PublicKeySpec; 46// END android-removed 47 48public abstract class JDKKeyFactory 49 extends KeyFactorySpi 50{ 51 // BEGIN android-removed 52 // protected boolean elGamalFactory = false; 53 // END android-removed 54 55 public JDKKeyFactory() 56 { 57 } 58 59 protected PrivateKey engineGeneratePrivate( 60 KeySpec keySpec) 61 throws InvalidKeySpecException 62 { 63 if (keySpec instanceof PKCS8EncodedKeySpec) 64 { 65 try 66 { 67 return JDKKeyFactory.createPrivateKeyFromDERStream( 68 ((PKCS8EncodedKeySpec)keySpec).getEncoded()); 69 } 70 catch (Exception e) 71 { 72 throw new InvalidKeySpecException(e.toString()); 73 } 74 } 75 76 throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName()); 77 } 78 79 protected PublicKey engineGeneratePublic( 80 KeySpec keySpec) 81 throws InvalidKeySpecException 82 { 83 if (keySpec instanceof X509EncodedKeySpec) 84 { 85 try 86 { 87 return JDKKeyFactory.createPublicKeyFromDERStream( 88 ((X509EncodedKeySpec)keySpec).getEncoded()); 89 } 90 catch (Exception e) 91 { 92 throw new InvalidKeySpecException(e.toString()); 93 } 94 } 95 96 throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName()); 97 } 98 99 protected KeySpec engineGetKeySpec( 100 Key key, 101 Class spec) 102 throws InvalidKeySpecException 103 { 104 if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8")) 105 { 106 return new PKCS8EncodedKeySpec(key.getEncoded()); 107 } 108 else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509")) 109 { 110 return new X509EncodedKeySpec(key.getEncoded()); 111 } 112 else if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey) 113 { 114 RSAPublicKey k = (RSAPublicKey)key; 115 116 return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent()); 117 } 118 else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof RSAPrivateKey) 119 { 120 RSAPrivateKey k = (RSAPrivateKey)key; 121 122 return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent()); 123 } 124 else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey) 125 { 126 RSAPrivateCrtKey k = (RSAPrivateCrtKey)key; 127 128 return new RSAPrivateCrtKeySpec( 129 k.getModulus(), k.getPublicExponent(), 130 k.getPrivateExponent(), 131 k.getPrimeP(), k.getPrimeQ(), 132 k.getPrimeExponentP(), k.getPrimeExponentQ(), 133 k.getCrtCoefficient()); 134 } 135 else if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey) 136 { 137 DHPrivateKey k = (DHPrivateKey)key; 138 139 return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG()); 140 } 141 else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey) 142 { 143 DHPublicKey k = (DHPublicKey)key; 144 145 return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG()); 146 } 147 // BEGIN android-added 148 else if (spec.isAssignableFrom(DSAPublicKeySpec.class) && key instanceof DSAPublicKey) 149 { 150 DSAPublicKey k = (DSAPublicKey)key; 151 152 return new DSAPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()); 153 } 154 else if (spec.isAssignableFrom(DSAPrivateKeySpec.class) && key instanceof DSAPrivateKey) 155 { 156 DSAPrivateKey k = (DSAPrivateKey)key; 157 158 return new DSAPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()); 159 } 160 // END android-added 161 162 throw new RuntimeException("not implemented yet " + key + " " + spec); 163 } 164 165 protected Key engineTranslateKey( 166 Key key) 167 throws InvalidKeyException 168 { 169 if (key instanceof RSAPublicKey) 170 { 171 return new JCERSAPublicKey((RSAPublicKey)key); 172 } 173 else if (key instanceof RSAPrivateCrtKey) 174 { 175 return new JCERSAPrivateCrtKey((RSAPrivateCrtKey)key); 176 } 177 else if (key instanceof RSAPrivateKey) 178 { 179 return new JCERSAPrivateKey((RSAPrivateKey)key); 180 } 181 else if (key instanceof DHPublicKey) 182 { 183 // BEGIN android-removed 184 // if (elGamalFactory) 185 // { 186 // return new JCEElGamalPublicKey((DHPublicKey)key); 187 // } 188 // else 189 // { 190 // END android-removed 191 return new JCEDHPublicKey((DHPublicKey)key); 192 // BEGIN android-removed 193 // } 194 // END android-removed 195 } 196 else if (key instanceof DHPrivateKey) 197 { 198 // BEGIN android-removed 199 // if (elGamalFactory) 200 // { 201 // return new JCEElGamalPrivateKey((DHPrivateKey)key); 202 // } 203 // else 204 // { 205 // END android-removed 206 return new JCEDHPrivateKey((DHPrivateKey)key); 207 // BEGIN android-removed 208 // } 209 // END android-removed 210 } 211 else if (key instanceof DSAPublicKey) 212 { 213 return new JDKDSAPublicKey((DSAPublicKey)key); 214 } 215 else if (key instanceof DSAPrivateKey) 216 { 217 return new JDKDSAPrivateKey((DSAPrivateKey)key); 218 } 219 // BEGIN android-removed 220 // else if (key instanceof ElGamalPublicKey) 221 // { 222 // return new JCEElGamalPublicKey((ElGamalPublicKey)key); 223 // } 224 // else if (key instanceof ElGamalPrivateKey) 225 // { 226 // return new JCEElGamalPrivateKey((ElGamalPrivateKey)key); 227 // } 228 // END android-removed 229 230 throw new InvalidKeyException("key type unknown"); 231 } 232 233 /** 234 * create a public key from the given DER encoded input stream. 235 */ 236 public static PublicKey createPublicKeyFromDERStream( 237 byte[] in) 238 throws IOException 239 { 240 return createPublicKeyFromPublicKeyInfo( 241 new SubjectPublicKeyInfo((ASN1Sequence) ASN1Object.fromByteArray(in))); 242 } 243 244 /** 245 * create a public key from the given public key info object. 246 */ 247 static PublicKey createPublicKeyFromPublicKeyInfo( 248 SubjectPublicKeyInfo info) 249 { 250 DERObjectIdentifier algOid = info.getAlgorithmId().getObjectId(); 251 252 if (RSAUtil.isRsaOid(algOid)) 253 { 254 return new JCERSAPublicKey(info); 255 } 256 else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) 257 { 258 return new JCEDHPublicKey(info); 259 } 260 else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber)) 261 { 262 return new JCEDHPublicKey(info); 263 } 264 // BEGIN android-removed 265 // else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm)) 266 // { 267 // return new JCEElGamalPublicKey(info); 268 // } 269 // END android-removed 270 else if (algOid.equals(X9ObjectIdentifiers.id_dsa)) 271 { 272 return new JDKDSAPublicKey(info); 273 } 274 else if (algOid.equals(OIWObjectIdentifiers.dsaWithSHA1)) 275 { 276 return new JDKDSAPublicKey(info); 277 } 278 else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) 279 { 280 return new JCEECPublicKey(info); 281 } 282 // BEGIN android-removed 283 // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94)) 284 // { 285 // return new JDKGOST3410PublicKey(info); 286 // } 287 // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001)) 288 // { 289 // return new JCEECPublicKey(info); 290 // } 291 else 292 { 293 throw new RuntimeException("algorithm identifier " + algOid + " in key not recognised"); 294 } 295 } 296 297 /** 298 * create a private key from the given DER encoded input stream. 299 */ 300 protected static PrivateKey createPrivateKeyFromDERStream( 301 byte[] in) 302 throws IOException 303 { 304 return createPrivateKeyFromPrivateKeyInfo( 305 new PrivateKeyInfo((ASN1Sequence) ASN1Object.fromByteArray(in))); 306 } 307 308 /** 309 * create a private key from the given public key info object. 310 */ 311 static PrivateKey createPrivateKeyFromPrivateKeyInfo( 312 PrivateKeyInfo info) 313 { 314 DERObjectIdentifier algOid = info.getAlgorithmId().getObjectId(); 315 316 if (RSAUtil.isRsaOid(algOid)) 317 { 318 return new JCERSAPrivateCrtKey(info); 319 } 320 else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) 321 { 322 return new JCEDHPrivateKey(info); 323 } 324 else if (algOid.equals(X9ObjectIdentifiers.dhpublicnumber)) 325 { 326 return new JCEDHPrivateKey(info); 327 } 328 // BEGIN android-removed 329 // else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm)) 330 // { 331 // return new JCEElGamalPrivateKey(info); 332 // } 333 // END android-removed 334 else if (algOid.equals(X9ObjectIdentifiers.id_dsa)) 335 { 336 return new JDKDSAPrivateKey(info); 337 } 338 else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) 339 { 340 return new JCEECPrivateKey(info); 341 } 342 // BEGIN android-removed 343 // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94)) 344 // { 345 // return new JDKGOST3410PrivateKey(info); 346 // } 347 // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001)) 348 // { 349 // return new JCEECPrivateKey(info); 350 // } 351 // END android-removed 352 else 353 { 354 throw new RuntimeException("algorithm identifier " + algOid + " in key not recognised"); 355 } 356 } 357 358 public static class RSA 359 extends JDKKeyFactory 360 { 361 public RSA() 362 { 363 } 364 365 protected PrivateKey engineGeneratePrivate( 366 KeySpec keySpec) 367 throws InvalidKeySpecException 368 { 369 if (keySpec instanceof PKCS8EncodedKeySpec) 370 { 371 try 372 { 373 return JDKKeyFactory.createPrivateKeyFromDERStream( 374 ((PKCS8EncodedKeySpec)keySpec).getEncoded()); 375 } 376 catch (Exception e) 377 { 378 // 379 // in case it's just a RSAPrivateKey object... 380 // 381 try 382 { 383 return new JCERSAPrivateCrtKey( 384 new RSAPrivateKeyStructure( 385 (ASN1Sequence) ASN1Object.fromByteArray(((PKCS8EncodedKeySpec)keySpec).getEncoded()))); 386 } 387 catch (Exception ex) 388 { 389 throw new InvalidKeySpecException(ex.toString()); 390 } 391 } 392 } 393 else if (keySpec instanceof RSAPrivateCrtKeySpec) 394 { 395 return new JCERSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec); 396 } 397 else if (keySpec instanceof RSAPrivateKeySpec) 398 { 399 return new JCERSAPrivateKey((RSAPrivateKeySpec)keySpec); 400 } 401 402 throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName()); 403 } 404 405 protected PublicKey engineGeneratePublic( 406 KeySpec keySpec) 407 throws InvalidKeySpecException 408 { 409 if (keySpec instanceof RSAPublicKeySpec) 410 { 411 return new JCERSAPublicKey((RSAPublicKeySpec)keySpec); 412 } 413 414 return super.engineGeneratePublic(keySpec); 415 } 416 } 417 418 public static class DH 419 extends JDKKeyFactory 420 { 421 public DH() 422 { 423 } 424 425 protected PrivateKey engineGeneratePrivate( 426 KeySpec keySpec) 427 throws InvalidKeySpecException 428 { 429 if (keySpec instanceof DHPrivateKeySpec) 430 { 431 return new JCEDHPrivateKey((DHPrivateKeySpec)keySpec); 432 } 433 434 return super.engineGeneratePrivate(keySpec); 435 } 436 437 protected PublicKey engineGeneratePublic( 438 KeySpec keySpec) 439 throws InvalidKeySpecException 440 { 441 if (keySpec instanceof DHPublicKeySpec) 442 { 443 return new JCEDHPublicKey((DHPublicKeySpec)keySpec); 444 } 445 446 return super.engineGeneratePublic(keySpec); 447 } 448 } 449 450 public static class DSA 451 extends JDKKeyFactory 452 { 453 public DSA() 454 { 455 } 456 457 protected PrivateKey engineGeneratePrivate( 458 KeySpec keySpec) 459 throws InvalidKeySpecException 460 { 461 if (keySpec instanceof DSAPrivateKeySpec) 462 { 463 return new JDKDSAPrivateKey((DSAPrivateKeySpec)keySpec); 464 } 465 466 return super.engineGeneratePrivate(keySpec); 467 } 468 469 protected PublicKey engineGeneratePublic( 470 KeySpec keySpec) 471 throws InvalidKeySpecException 472 { 473 if (keySpec instanceof DSAPublicKeySpec) 474 { 475 return new JDKDSAPublicKey((DSAPublicKeySpec)keySpec); 476 } 477 478 return super.engineGeneratePublic(keySpec); 479 } 480 } 481 482 // BEGIN android-removed 483 // public static class GOST3410 484 // extends JDKKeyFactory 485 // { 486 // public GOST3410() 487 // { 488 // } 489 // 490 // protected PrivateKey engineGeneratePrivate( 491 // KeySpec keySpec) 492 // throws InvalidKeySpecException 493 // { 494 // if (keySpec instanceof GOST3410PrivateKeySpec) 495 // { 496 // return new JDKGOST3410PrivateKey((GOST3410PrivateKeySpec)keySpec); 497 // } 498 // 499 // return super.engineGeneratePrivate(keySpec); 500 // } 501 // 502 // protected PublicKey engineGeneratePublic( 503 // KeySpec keySpec) 504 // throws InvalidKeySpecException 505 // { 506 // if (keySpec instanceof GOST3410PublicKeySpec) 507 // { 508 // return new JDKGOST3410PublicKey((GOST3410PublicKeySpec)keySpec); 509 // } 510 // 511 // return super.engineGeneratePublic(keySpec); 512 // } 513 // } 514 515 // public static class ElGamal 516 // extends JDKKeyFactory 517 // { 518 // public ElGamal() 519 // { 520 // elGamalFactory = true; 521 // } 522 // 523 // protected PrivateKey engineGeneratePrivate( 524 // KeySpec keySpec) 525 // throws InvalidKeySpecException 526 // { 527 // if (keySpec instanceof ElGamalPrivateKeySpec) 528 // { 529 // return new JCEElGamalPrivateKey((ElGamalPrivateKeySpec)keySpec); 530 // } 531 // else if (keySpec instanceof DHPrivateKeySpec) 532 // { 533 // return new JCEElGamalPrivateKey((DHPrivateKeySpec)keySpec); 534 // } 535 // 536 // return super.engineGeneratePrivate(keySpec); 537 // } 538 // 539 // protected PublicKey engineGeneratePublic( 540 // KeySpec keySpec) 541 // throws InvalidKeySpecException 542 // { 543 // if (keySpec instanceof ElGamalPublicKeySpec) 544 // { 545 // return new JCEElGamalPublicKey((ElGamalPublicKeySpec)keySpec); 546 // } 547 // else if (keySpec instanceof DHPublicKeySpec) 548 // { 549 // return new JCEElGamalPublicKey((DHPublicKeySpec)keySpec); 550 // } 551 // 552 // return super.engineGeneratePublic(keySpec); 553 // } 554 // } 555 // 556 // 557 // 558 // /** 559 // * This isn't really correct, however the class path project API seems to think such 560 // * a key factory will exist. 561 // */ 562 // public static class X509 563 // extends JDKKeyFactory 564 // { 565 // public X509() 566 // { 567 // } 568 // } 569 // END android-removed 570} 571