001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.util.jce.provider; 019 020 import java.io.ByteArrayInputStream; 021 import java.io.IOException; 022 import java.io.InputStream; 023 import java.security.InvalidKeyException; 024 import java.security.Key; 025 import java.security.KeyFactorySpi; 026 import java.security.PrivateKey; 027 import java.security.PublicKey; 028 import java.security.interfaces.DSAPrivateKey; 029 import java.security.interfaces.DSAPublicKey; 030 import java.security.interfaces.RSAPrivateCrtKey; 031 import java.security.interfaces.RSAPrivateKey; 032 import java.security.interfaces.RSAPublicKey; 033 import java.security.spec.DSAPrivateKeySpec; 034 import java.security.spec.DSAPublicKeySpec; 035 import java.security.spec.InvalidKeySpecException; 036 import java.security.spec.KeySpec; 037 import java.security.spec.PKCS8EncodedKeySpec; 038 import java.security.spec.RSAPrivateCrtKeySpec; 039 import java.security.spec.RSAPrivateKeySpec; 040 import java.security.spec.RSAPublicKeySpec; 041 import java.security.spec.X509EncodedKeySpec; 042 043 import javax.crypto.interfaces.DHPrivateKey; 044 import javax.crypto.interfaces.DHPublicKey; 045 import javax.crypto.spec.DHPrivateKeySpec; 046 import javax.crypto.spec.DHPublicKeySpec; 047 048 import org.apache.geronimo.util.asn1.ASN1InputStream; 049 import org.apache.geronimo.util.asn1.ASN1Sequence; 050 import org.apache.geronimo.util.asn1.cryptopro.CryptoProObjectIdentifiers; 051 import org.apache.geronimo.util.asn1.oiw.OIWObjectIdentifiers; 052 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers; 053 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo; 054 import org.apache.geronimo.util.asn1.pkcs.RSAPrivateKeyStructure; 055 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier; 056 import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo; 057 import org.apache.geronimo.util.asn1.x509.X509ObjectIdentifiers; 058 import org.apache.geronimo.util.asn1.x9.X9ObjectIdentifiers; 059 import org.apache.geronimo.util.jce.provider.JCEDHPrivateKey; 060 import org.apache.geronimo.util.jce.provider.JCEDHPublicKey; 061 062 public abstract class JDKKeyFactory 063 extends KeyFactorySpi 064 { 065 public JDKKeyFactory() 066 { 067 } 068 069 protected KeySpec engineGetKeySpec( 070 Key key, 071 Class spec) 072 throws InvalidKeySpecException 073 { 074 if (spec.isAssignableFrom(PKCS8EncodedKeySpec.class) && key.getFormat().equals("PKCS#8")) 075 { 076 return new PKCS8EncodedKeySpec(key.getEncoded()); 077 } 078 else if (spec.isAssignableFrom(X509EncodedKeySpec.class) && key.getFormat().equals("X.509")) 079 { 080 return new X509EncodedKeySpec(key.getEncoded()); 081 } 082 else if (spec.isAssignableFrom(RSAPublicKeySpec.class) && key instanceof RSAPublicKey) 083 { 084 RSAPublicKey k = (RSAPublicKey)key; 085 086 return new RSAPublicKeySpec(k.getModulus(), k.getPublicExponent()); 087 } 088 else if (spec.isAssignableFrom(RSAPrivateKeySpec.class) && key instanceof RSAPrivateKey) 089 { 090 RSAPrivateKey k = (RSAPrivateKey)key; 091 092 return new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent()); 093 } 094 else if (spec.isAssignableFrom(RSAPrivateCrtKeySpec.class) && key instanceof RSAPrivateCrtKey) 095 { 096 RSAPrivateCrtKey k = (RSAPrivateCrtKey)key; 097 098 return new RSAPrivateCrtKeySpec( 099 k.getModulus(), k.getPublicExponent(), 100 k.getPrivateExponent(), 101 k.getPrimeP(), k.getPrimeQ(), 102 k.getPrimeExponentP(), k.getPrimeExponentQ(), 103 k.getCrtCoefficient()); 104 } 105 else if (spec.isAssignableFrom(DHPrivateKeySpec.class) && key instanceof DHPrivateKey) 106 { 107 DHPrivateKey k = (DHPrivateKey)key; 108 109 return new DHPrivateKeySpec(k.getX(), k.getParams().getP(), k.getParams().getG()); 110 } 111 else if (spec.isAssignableFrom(DHPublicKeySpec.class) && key instanceof DHPublicKey) 112 { 113 DHPublicKey k = (DHPublicKey)key; 114 115 return new DHPublicKeySpec(k.getY(), k.getParams().getP(), k.getParams().getG()); 116 } 117 118 throw new RuntimeException("not implemented yet " + key + " " + spec); 119 } 120 121 protected Key engineTranslateKey( 122 Key key) 123 throws InvalidKeyException 124 { 125 if (key instanceof RSAPublicKey) 126 { 127 return new JCERSAPublicKey((RSAPublicKey)key); 128 } 129 else if (key instanceof RSAPrivateCrtKey) 130 { 131 return new JCERSAPrivateCrtKey((RSAPrivateCrtKey)key); 132 } 133 else if (key instanceof RSAPrivateKey) 134 { 135 return new JCERSAPrivateKey((RSAPrivateKey)key); 136 } 137 else if (key instanceof DHPublicKey) 138 { 139 return new JCEDHPublicKey((DHPublicKey)key); 140 } 141 else if (key instanceof DHPrivateKey) 142 { 143 return new JCEDHPrivateKey((DHPrivateKey)key); 144 } 145 else if (key instanceof DSAPublicKey) 146 { 147 return new JDKDSAPublicKey((DSAPublicKey)key); 148 } 149 else if (key instanceof DSAPrivateKey) 150 { 151 return new JDKDSAPrivateKey((DSAPrivateKey)key); 152 } 153 throw new InvalidKeyException("key type unknown"); 154 } 155 156 /** 157 * create a public key from the given DER encoded input stream. 158 */ 159 static PublicKey createPublicKeyFromDERStream( 160 InputStream in) 161 throws IOException 162 { 163 return createPublicKeyFromPublicKeyInfo( 164 new SubjectPublicKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject()))); 165 } 166 167 /** 168 * create a public key from the given public key info object. 169 */ 170 static PublicKey createPublicKeyFromPublicKeyInfo( 171 SubjectPublicKeyInfo info) 172 { 173 AlgorithmIdentifier algId = info.getAlgorithmId(); 174 175 if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption) 176 || algId.getObjectId().equals(X509ObjectIdentifiers.id_ea_rsa)) 177 { 178 return new JCERSAPublicKey(info); 179 } 180 else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement)) 181 { 182 return new JCEDHPublicKey(info); 183 } 184 else if (algId.getObjectId().equals(X9ObjectIdentifiers.dhpublicnumber)) 185 { 186 return new JCEDHPublicKey(info); 187 } 188 else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa)) 189 { 190 return new JDKDSAPublicKey(info); 191 } 192 else if (algId.getObjectId().equals(OIWObjectIdentifiers.dsaWithSHA1)) 193 { 194 return new JDKDSAPublicKey(info); 195 } 196 else 197 { 198 throw new RuntimeException("algorithm identifier in key not recognised"); 199 } 200 } 201 202 /** 203 * create a private key from the given DER encoded input stream. 204 */ 205 static PrivateKey createPrivateKeyFromDERStream( 206 InputStream in) 207 throws IOException 208 { 209 return createPrivateKeyFromPrivateKeyInfo( 210 new PrivateKeyInfo((ASN1Sequence)(new ASN1InputStream(in).readObject()))); 211 } 212 213 /** 214 * create a private key from the given public key info object. 215 */ 216 static PrivateKey createPrivateKeyFromPrivateKeyInfo( 217 PrivateKeyInfo info) 218 { 219 AlgorithmIdentifier algId = info.getAlgorithmId(); 220 221 if (algId.getObjectId().equals(PKCSObjectIdentifiers.rsaEncryption)) 222 { 223 return new JCERSAPrivateCrtKey(info); 224 } 225 else if (algId.getObjectId().equals(PKCSObjectIdentifiers.dhKeyAgreement)) 226 { 227 return new JCEDHPrivateKey(info); 228 } 229 else if (algId.getObjectId().equals(X9ObjectIdentifiers.id_dsa)) 230 { 231 return new JDKDSAPrivateKey(info); 232 } 233 else 234 { 235 throw new RuntimeException("algorithm identifier in key not recognised"); 236 } 237 } 238 239 public static class RSA 240 extends JDKKeyFactory 241 { 242 public RSA() 243 { 244 } 245 246 protected PrivateKey engineGeneratePrivate( 247 KeySpec keySpec) 248 throws InvalidKeySpecException 249 { 250 if (keySpec instanceof PKCS8EncodedKeySpec) 251 { 252 try 253 { 254 return JDKKeyFactory.createPrivateKeyFromDERStream( 255 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())); 256 } 257 catch (Exception e) 258 { 259 // 260 // in case it's just a RSAPrivateKey object... 261 // 262 try 263 { 264 return new JCERSAPrivateCrtKey( 265 new RSAPrivateKeyStructure( 266 (ASN1Sequence)new ASN1InputStream(new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())).readObject())); 267 } 268 catch (Exception ex) 269 { 270 throw (InvalidKeySpecException)new InvalidKeySpecException(ex.getMessage()).initCause(ex); 271 } 272 } 273 } 274 else if (keySpec instanceof RSAPrivateCrtKeySpec) 275 { 276 return new JCERSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec); 277 } 278 else if (keySpec instanceof RSAPrivateKeySpec) 279 { 280 return new JCERSAPrivateKey((RSAPrivateKeySpec)keySpec); 281 } 282 283 throw new InvalidKeySpecException("Unknown KeySpec type."); 284 } 285 286 protected PublicKey engineGeneratePublic( 287 KeySpec keySpec) 288 throws InvalidKeySpecException 289 { 290 if (keySpec instanceof X509EncodedKeySpec) 291 { 292 try 293 { 294 return JDKKeyFactory.createPublicKeyFromDERStream( 295 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded())); 296 } 297 catch (Exception e) 298 { 299 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e); 300 } 301 } 302 else if (keySpec instanceof RSAPublicKeySpec) 303 { 304 return new JCERSAPublicKey((RSAPublicKeySpec)keySpec); 305 } 306 307 throw new InvalidKeySpecException("Unknown KeySpec type."); 308 } 309 } 310 311 public static class DH 312 extends JDKKeyFactory 313 { 314 public DH() 315 { 316 } 317 318 protected PrivateKey engineGeneratePrivate( 319 KeySpec keySpec) 320 throws InvalidKeySpecException 321 { 322 if (keySpec instanceof PKCS8EncodedKeySpec) 323 { 324 try 325 { 326 return JDKKeyFactory.createPrivateKeyFromDERStream( 327 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())); 328 } 329 catch (Exception e) 330 { 331 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e); 332 } 333 } 334 else if (keySpec instanceof DHPrivateKeySpec) 335 { 336 return new JCEDHPrivateKey((DHPrivateKeySpec)keySpec); 337 } 338 339 throw new InvalidKeySpecException("Unknown KeySpec type."); 340 } 341 342 protected PublicKey engineGeneratePublic( 343 KeySpec keySpec) 344 throws InvalidKeySpecException 345 { 346 if (keySpec instanceof X509EncodedKeySpec) 347 { 348 try 349 { 350 return JDKKeyFactory.createPublicKeyFromDERStream( 351 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded())); 352 } 353 catch (Exception e) 354 { 355 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e); 356 } 357 } 358 else if (keySpec instanceof DHPublicKeySpec) 359 { 360 return new JCEDHPublicKey((DHPublicKeySpec)keySpec); 361 } 362 363 throw new InvalidKeySpecException("Unknown KeySpec type."); 364 } 365 } 366 367 public static class DSA 368 extends JDKKeyFactory 369 { 370 public DSA() 371 { 372 } 373 374 protected PrivateKey engineGeneratePrivate( 375 KeySpec keySpec) 376 throws InvalidKeySpecException 377 { 378 if (keySpec instanceof PKCS8EncodedKeySpec) 379 { 380 try 381 { 382 return JDKKeyFactory.createPrivateKeyFromDERStream( 383 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())); 384 } 385 catch (Exception e) 386 { 387 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e); 388 } 389 } 390 else if (keySpec instanceof DSAPrivateKeySpec) 391 { 392 return new JDKDSAPrivateKey((DSAPrivateKeySpec)keySpec); 393 } 394 395 throw new InvalidKeySpecException("Unknown KeySpec type."); 396 } 397 398 protected PublicKey engineGeneratePublic( 399 KeySpec keySpec) 400 throws InvalidKeySpecException 401 { 402 if (keySpec instanceof X509EncodedKeySpec) 403 { 404 try 405 { 406 return JDKKeyFactory.createPublicKeyFromDERStream( 407 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded())); 408 } 409 catch (Exception e) 410 { 411 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e); 412 } 413 } 414 else if (keySpec instanceof DSAPublicKeySpec) 415 { 416 return new JDKDSAPublicKey((DSAPublicKeySpec)keySpec); 417 } 418 419 throw new InvalidKeySpecException("Unknown KeySpec type."); 420 } 421 } 422 423 424 public static class EC 425 extends JDKKeyFactory 426 { 427 String algorithm; 428 429 public EC() 430 { 431 this("EC"); 432 } 433 434 public EC( 435 String algorithm) 436 { 437 this.algorithm = algorithm; 438 } 439 440 protected PrivateKey engineGeneratePrivate( 441 KeySpec keySpec) 442 throws InvalidKeySpecException 443 { 444 if (keySpec instanceof PKCS8EncodedKeySpec) 445 { 446 try 447 { 448 return JDKKeyFactory.createPrivateKeyFromDERStream( 449 new ByteArrayInputStream(((PKCS8EncodedKeySpec)keySpec).getEncoded())); 450 } 451 catch (Exception e) 452 { 453 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e); 454 } 455 } 456 457 throw new InvalidKeySpecException("Unknown KeySpec type."); 458 } 459 460 protected PublicKey engineGeneratePublic( 461 KeySpec keySpec) 462 throws InvalidKeySpecException 463 { 464 if (keySpec instanceof X509EncodedKeySpec) 465 { 466 try 467 { 468 return JDKKeyFactory.createPublicKeyFromDERStream( 469 new ByteArrayInputStream(((X509EncodedKeySpec)keySpec).getEncoded())); 470 } 471 catch (Exception e) 472 { 473 throw (InvalidKeySpecException)new InvalidKeySpecException(e.getMessage()).initCause(e); 474 } 475 } 476 477 throw new InvalidKeySpecException("Unknown KeySpec type."); 478 } 479 } 480 }