1 /* 2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.rsa; 27 28 import java.math.BigInteger; 29 30 import java.security.*; 31 import java.security.interfaces.*; 32 import java.security.spec.*; 33 34 import sun.security.action.GetPropertyAction; 35 36 /** 37 * KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey 38 * and getAlgorithm() must return "RSA". For such keys, it supports conversion 39 * between the following: 40 * 41 * For public keys: 42 * . PublicKey with an X.509 encoding 43 * . RSAPublicKey 44 * . RSAPublicKeySpec 45 * . X509EncodedKeySpec 46 * 47 * For private keys: 48 * . PrivateKey with a PKCS#8 encoding 49 * . RSAPrivateKey 50 * . RSAPrivateCrtKey 51 * . RSAPrivateKeySpec 52 * . RSAPrivateCrtKeySpec 53 * . PKCS8EncodedKeySpec 54 * (of course, CRT variants only for CRT keys) 55 * 56 * Note: as always, RSA keys should be at least 512 bits long 57 * 58 * @since 1.5 59 * @author Andreas Sterbenz 60 */ 61 public final class RSAKeyFactory extends KeyFactorySpi { 62 63 private static final Class<?> rsaPublicKeySpecClass = 64 RSAPublicKeySpec.class; 65 private static final Class<?> rsaPrivateKeySpecClass = 66 RSAPrivateKeySpec.class; 67 private static final Class<?> rsaPrivateCrtKeySpecClass = 68 RSAPrivateCrtKeySpec.class; 69 70 private static final Class<?> x509KeySpecClass = X509EncodedKeySpec.class; 71 private static final Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class; 72 73 public static final int MIN_MODLEN = 512; 74 public static final int MAX_MODLEN = 16384; 75 76 /* 77 * If the modulus length is above this value, restrict the size of 78 * the exponent to something that can be reasonably computed. We 79 * could simply hardcode the exp len to something like 64 bits, but 80 * this approach allows flexibility in case impls would like to use 81 * larger module and exponent values. 82 */ 83 public static final int MAX_MODLEN_RESTRICT_EXP = 3072; 84 public static final int MAX_RESTRICTED_EXPLEN = 64; 85 86 private static final boolean restrictExpLen = 87 "true".equalsIgnoreCase(GetPropertyAction.privilegedGetProperty( 88 "sun.security.rsa.restrictRSAExponent", "true")); 89 90 // instance used for static translateKey(); 91 private static final RSAKeyFactory INSTANCE = new RSAKeyFactory(); 92 93 public RSAKeyFactory() { 94 // empty 95 } 96 97 /** 98 * Static method to convert Key into an instance of RSAPublicKeyImpl 99 * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be 100 * used, throw an InvalidKeyException. 101 * 102 * Used by RSASignature and RSACipher. 103 */ 104 public static RSAKey toRSAKey(Key key) throws InvalidKeyException { 105 if ((key instanceof RSAPrivateKeyImpl) || 106 (key instanceof RSAPrivateCrtKeyImpl) || 107 (key instanceof RSAPublicKeyImpl)) { 108 return (RSAKey)key; 109 } else { 110 return (RSAKey)INSTANCE.engineTranslateKey(key); 111 } 112 } 113 114 /* 115 * Single test entry point for all of the mechanisms in the SunRsaSign 116 * provider (RSA*KeyImpls). All of the tests are the same. 117 * 118 * For compatibility, we round up to the nearest byte here: 119 * some Key impls might pass in a value within a byte of the 120 * real value. 121 */ 122 static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent) 123 throws InvalidKeyException { 124 checkKeyLengths(((modulusLen + 7) & ~7), exponent, 125 RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE); 126 } 127 128 /** 129 * Check the length of an RSA key modulus/exponent to make sure it 130 * is not too short or long. Some impls have their own min and 154 155 // If a RSAPrivateKey/RSAPublicKey, make sure the 156 // modulus len isn't too big. 157 if (modulusLen > maxLen) { 158 throw new InvalidKeyException( 159 "RSA keys must be no longer than " + maxLen + " bits"); 160 } 161 162 // If a RSAPublicKey, make sure the exponent isn't too big. 163 if (restrictExpLen && (exponent != null) && 164 (modulusLen > MAX_MODLEN_RESTRICT_EXP) && 165 (exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) { 166 throw new InvalidKeyException( 167 "RSA exponents can be no longer than " + 168 MAX_RESTRICTED_EXPLEN + " bits " + 169 " if modulus is greater than " + 170 MAX_MODLEN_RESTRICT_EXP + " bits"); 171 } 172 } 173 174 /** 175 * Translate an RSA key into a SunRsaSign RSA key. If conversion is 176 * not possible, throw an InvalidKeyException. 177 * See also JCA doc. 178 */ 179 protected Key engineTranslateKey(Key key) throws InvalidKeyException { 180 if (key == null) { 181 throw new InvalidKeyException("Key must not be null"); 182 } 183 String keyAlg = key.getAlgorithm(); 184 if (keyAlg.equals("RSA") == false) { 185 throw new InvalidKeyException("Not an RSA key: " + keyAlg); 186 } 187 if (key instanceof PublicKey) { 188 return translatePublicKey((PublicKey)key); 189 } else if (key instanceof PrivateKey) { 190 return translatePrivateKey((PrivateKey)key); 191 } else { 192 throw new InvalidKeyException("Neither a public nor a private key"); 193 } 194 } 195 196 // see JCA doc 197 protected PublicKey engineGeneratePublic(KeySpec keySpec) 198 throws InvalidKeySpecException { 199 try { 200 return generatePublic(keySpec); 201 } catch (InvalidKeySpecException e) { 202 throw e; 203 } catch (GeneralSecurityException e) { 204 throw new InvalidKeySpecException(e); 205 } 206 } 207 208 // see JCA doc 209 protected PrivateKey engineGeneratePrivate(KeySpec keySpec) 210 throws InvalidKeySpecException { 211 try { 212 return generatePrivate(keySpec); 213 } catch (InvalidKeySpecException e) { 214 throw e; 215 } catch (GeneralSecurityException e) { 216 throw new InvalidKeySpecException(e); 217 } 218 } 219 220 // internal implementation of translateKey() for public keys. See JCA doc 221 private PublicKey translatePublicKey(PublicKey key) 222 throws InvalidKeyException { 223 if (key instanceof RSAPublicKey) { 224 if (key instanceof RSAPublicKeyImpl) { 225 return key; 226 } 227 RSAPublicKey rsaKey = (RSAPublicKey)key; 228 try { 229 return new RSAPublicKeyImpl( 230 rsaKey.getModulus(), 231 rsaKey.getPublicExponent() 232 ); 233 } catch (RuntimeException e) { 234 // catch providers that incorrectly implement RSAPublicKey 235 throw new InvalidKeyException("Invalid key", e); 236 } 237 } else if ("X.509".equals(key.getFormat())) { 238 byte[] encoded = key.getEncoded(); 239 return new RSAPublicKeyImpl(encoded); 240 } else { 241 throw new InvalidKeyException("Public keys must be instance " 242 + "of RSAPublicKey or have X.509 encoding"); 243 } 244 } 245 246 // internal implementation of translateKey() for private keys. See JCA doc 247 private PrivateKey translatePrivateKey(PrivateKey key) 248 throws InvalidKeyException { 249 if (key instanceof RSAPrivateCrtKey) { 250 if (key instanceof RSAPrivateCrtKeyImpl) { 251 return key; 252 } 253 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; 254 try { 255 return new RSAPrivateCrtKeyImpl( 256 rsaKey.getModulus(), 257 rsaKey.getPublicExponent(), 258 rsaKey.getPrivateExponent(), 259 rsaKey.getPrimeP(), 260 rsaKey.getPrimeQ(), 261 rsaKey.getPrimeExponentP(), 262 rsaKey.getPrimeExponentQ(), 263 rsaKey.getCrtCoefficient() 264 ); 265 } catch (RuntimeException e) { 266 // catch providers that incorrectly implement RSAPrivateCrtKey 267 throw new InvalidKeyException("Invalid key", e); 268 } 269 } else if (key instanceof RSAPrivateKey) { 270 if (key instanceof RSAPrivateKeyImpl) { 271 return key; 272 } 273 RSAPrivateKey rsaKey = (RSAPrivateKey)key; 274 try { 275 return new RSAPrivateKeyImpl( 276 rsaKey.getModulus(), 277 rsaKey.getPrivateExponent() 278 ); 279 } catch (RuntimeException e) { 280 // catch providers that incorrectly implement RSAPrivateKey 281 throw new InvalidKeyException("Invalid key", e); 282 } 283 } else if ("PKCS#8".equals(key.getFormat())) { 284 byte[] encoded = key.getEncoded(); 285 return RSAPrivateCrtKeyImpl.newKey(encoded); 286 } else { 287 throw new InvalidKeyException("Private keys must be instance " 288 + "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); 289 } 290 } 291 292 // internal implementation of generatePublic. See JCA doc 293 private PublicKey generatePublic(KeySpec keySpec) 294 throws GeneralSecurityException { 295 if (keySpec instanceof X509EncodedKeySpec) { 296 X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; 297 return new RSAPublicKeyImpl(x509Spec.getEncoded()); 298 } else if (keySpec instanceof RSAPublicKeySpec) { 299 RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec; 300 return new RSAPublicKeyImpl( 301 rsaSpec.getModulus(), 302 rsaSpec.getPublicExponent() 303 ); 304 } else { 305 throw new InvalidKeySpecException("Only RSAPublicKeySpec " 306 + "and X509EncodedKeySpec supported for RSA public keys"); 307 } 308 } 309 310 // internal implementation of generatePrivate. See JCA doc 311 private PrivateKey generatePrivate(KeySpec keySpec) 312 throws GeneralSecurityException { 313 if (keySpec instanceof PKCS8EncodedKeySpec) { 314 PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; 315 return RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded()); 316 } else if (keySpec instanceof RSAPrivateCrtKeySpec) { 317 RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec; 318 return new RSAPrivateCrtKeyImpl( 319 rsaSpec.getModulus(), 320 rsaSpec.getPublicExponent(), 321 rsaSpec.getPrivateExponent(), 322 rsaSpec.getPrimeP(), 323 rsaSpec.getPrimeQ(), 324 rsaSpec.getPrimeExponentP(), 325 rsaSpec.getPrimeExponentQ(), 326 rsaSpec.getCrtCoefficient() 327 ); 328 } else if (keySpec instanceof RSAPrivateKeySpec) { 329 RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec; 330 return new RSAPrivateKeyImpl( 331 rsaSpec.getModulus(), 332 rsaSpec.getPrivateExponent() 333 ); 334 } else { 335 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " 336 + "and PKCS8EncodedKeySpec supported for RSA private keys"); 337 } 338 } 339 340 protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) 341 throws InvalidKeySpecException { 342 try { 343 // convert key to one of our keys 344 // this also verifies that the key is a valid RSA key and ensures 345 // that the encoding is X.509/PKCS#8 for public/private keys 346 key = engineTranslateKey(key); 347 } catch (InvalidKeyException e) { 348 throw new InvalidKeySpecException(e); 349 } 350 if (key instanceof RSAPublicKey) { 351 RSAPublicKey rsaKey = (RSAPublicKey)key; 352 if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) { 353 return keySpec.cast(new RSAPublicKeySpec( 354 rsaKey.getModulus(), 355 rsaKey.getPublicExponent() 356 )); 357 } else if (x509KeySpecClass.isAssignableFrom(keySpec)) { 358 return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); 359 } else { 360 throw new InvalidKeySpecException 361 ("KeySpec must be RSAPublicKeySpec or " 362 + "X509EncodedKeySpec for RSA public keys"); 363 } 364 } else if (key instanceof RSAPrivateKey) { 365 if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) { 366 return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); 367 } else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) { 368 if (key instanceof RSAPrivateCrtKey) { 369 RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key; 370 return keySpec.cast(new RSAPrivateCrtKeySpec( 371 crtKey.getModulus(), 372 crtKey.getPublicExponent(), 373 crtKey.getPrivateExponent(), 374 crtKey.getPrimeP(), 375 crtKey.getPrimeQ(), 376 crtKey.getPrimeExponentP(), 377 crtKey.getPrimeExponentQ(), 378 crtKey.getCrtCoefficient() 379 )); 380 } else { 381 throw new InvalidKeySpecException 382 ("RSAPrivateCrtKeySpec can only be used with CRT keys"); 383 } 384 } else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) { 385 RSAPrivateKey rsaKey = (RSAPrivateKey)key; 386 return keySpec.cast(new RSAPrivateKeySpec( 387 rsaKey.getModulus(), 388 rsaKey.getPrivateExponent() 389 )); 390 } else { 391 throw new InvalidKeySpecException 392 ("KeySpec must be RSAPrivate(Crt)KeySpec or " 393 + "PKCS8EncodedKeySpec for RSA private keys"); 394 } 395 } else { 396 // should not occur, caught in engineTranslateKey() 397 throw new InvalidKeySpecException("Neither public nor private key"); 398 } 399 } 400 } | 1 /* 2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.rsa; 27 28 import java.math.BigInteger; 29 30 import java.security.*; 31 import java.security.interfaces.*; 32 import java.security.spec.*; 33 34 import sun.security.action.GetPropertyAction; 35 import sun.security.x509.AlgorithmId; 36 import static sun.security.rsa.RSAUtil.KeyType; 37 38 /** 39 * KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS". 40 * Keys must be instances of PublicKey or PrivateKey 41 * and getAlgorithm() must return a value which matches the type which are 42 * specified during construction time of the KeyFactory object. 43 * For such keys, it supports conversion 44 * between the following: 45 * 46 * For public keys: 47 * . PublicKey with an X.509 encoding 48 * . RSAPublicKey 49 * . RSAPublicKeySpec 50 * . X509EncodedKeySpec 51 * 52 * For private keys: 53 * . PrivateKey with a PKCS#8 encoding 54 * . RSAPrivateKey 55 * . RSAPrivateCrtKey 56 * . RSAPrivateKeySpec 57 * . RSAPrivateCrtKeySpec 58 * . PKCS8EncodedKeySpec 59 * (of course, CRT variants only for CRT keys) 60 * 61 * Note: as always, RSA keys should be at least 512 bits long 62 * 63 * @since 1.5 64 * @author Andreas Sterbenz 65 */ 66 public class RSAKeyFactory extends KeyFactorySpi { 67 68 private static final Class<?> RSA_PUB_KEYSPEC_CLS = RSAPublicKeySpec.class; 69 private static final Class<?> RSA_PRIV_KEYSPEC_CLS = 70 RSAPrivateKeySpec.class; 71 private static final Class<?> RSA_PRIVCRT_KEYSPEC_CLS = 72 RSAPrivateCrtKeySpec.class; 73 private static final Class<?> X509_KEYSPEC_CLS = X509EncodedKeySpec.class; 74 private static final Class<?> PKCS8_KEYSPEC_CLS = PKCS8EncodedKeySpec.class; 75 76 public static final int MIN_MODLEN = 512; 77 public static final int MAX_MODLEN = 16384; 78 79 private final KeyType type; 80 81 /* 82 * If the modulus length is above this value, restrict the size of 83 * the exponent to something that can be reasonably computed. We 84 * could simply hardcode the exp len to something like 64 bits, but 85 * this approach allows flexibility in case impls would like to use 86 * larger module and exponent values. 87 */ 88 public static final int MAX_MODLEN_RESTRICT_EXP = 3072; 89 public static final int MAX_RESTRICTED_EXPLEN = 64; 90 91 private static final boolean restrictExpLen = 92 "true".equalsIgnoreCase(GetPropertyAction.privilegedGetProperty( 93 "sun.security.rsa.restrictRSAExponent", "true")); 94 95 static RSAKeyFactory getInstance(KeyType type) { 96 return new RSAKeyFactory(type); 97 } 98 99 // Internal utility method for checking key algorithm 100 private static void checkKeyAlgo(Key key, String expectedAlg) 101 throws InvalidKeyException { 102 String keyAlg = key.getAlgorithm(); 103 if (!(keyAlg.equalsIgnoreCase(expectedAlg))) { 104 throw new InvalidKeyException("Expected a " + expectedAlg 105 + " key, but got " + keyAlg); 106 } 107 } 108 109 /** 110 * Static method to convert Key into an instance of RSAPublicKeyImpl 111 * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be 112 * used, throw an InvalidKeyException. 113 * 114 * Used by RSASignature and RSACipher. 115 */ 116 public static RSAKey toRSAKey(Key key) throws InvalidKeyException { 117 if ((key instanceof RSAPrivateKeyImpl) || 118 (key instanceof RSAPrivateCrtKeyImpl) || 119 (key instanceof RSAPublicKeyImpl)) { 120 return (RSAKey)key; 121 } else { 122 try { 123 String keyAlgo = key.getAlgorithm(); 124 KeyType type = KeyType.lookup(keyAlgo); 125 RSAKeyFactory kf = RSAKeyFactory.getInstance(type); 126 return (RSAKey) kf.engineTranslateKey(key); 127 } catch (ProviderException e) { 128 throw new InvalidKeyException(e); 129 } 130 } 131 } 132 133 /* 134 * Single test entry point for all of the mechanisms in the SunRsaSign 135 * provider (RSA*KeyImpls). All of the tests are the same. 136 * 137 * For compatibility, we round up to the nearest byte here: 138 * some Key impls might pass in a value within a byte of the 139 * real value. 140 */ 141 static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent) 142 throws InvalidKeyException { 143 checkKeyLengths(((modulusLen + 7) & ~7), exponent, 144 RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE); 145 } 146 147 /** 148 * Check the length of an RSA key modulus/exponent to make sure it 149 * is not too short or long. Some impls have their own min and 173 174 // If a RSAPrivateKey/RSAPublicKey, make sure the 175 // modulus len isn't too big. 176 if (modulusLen > maxLen) { 177 throw new InvalidKeyException( 178 "RSA keys must be no longer than " + maxLen + " bits"); 179 } 180 181 // If a RSAPublicKey, make sure the exponent isn't too big. 182 if (restrictExpLen && (exponent != null) && 183 (modulusLen > MAX_MODLEN_RESTRICT_EXP) && 184 (exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) { 185 throw new InvalidKeyException( 186 "RSA exponents can be no longer than " + 187 MAX_RESTRICTED_EXPLEN + " bits " + 188 " if modulus is greater than " + 189 MAX_MODLEN_RESTRICT_EXP + " bits"); 190 } 191 } 192 193 // disallowed as KeyType is required 194 private RSAKeyFactory() { 195 this.type = KeyType.RSA; 196 } 197 198 public RSAKeyFactory(KeyType type) { 199 this.type = type; 200 } 201 202 /** 203 * Translate an RSA key into a SunRsaSign RSA key. If conversion is 204 * not possible, throw an InvalidKeyException. 205 * See also JCA doc. 206 */ 207 protected Key engineTranslateKey(Key key) throws InvalidKeyException { 208 if (key == null) { 209 throw new InvalidKeyException("Key must not be null"); 210 } 211 // ensure the key algorithm matches the current KeyFactory instance 212 checkKeyAlgo(key, type.keyAlgo()); 213 214 // no translation needed if the key is already our own impl 215 if ((key instanceof RSAPrivateKeyImpl) || 216 (key instanceof RSAPrivateCrtKeyImpl) || 217 (key instanceof RSAPublicKeyImpl)) { 218 return key; 219 } 220 if (key instanceof PublicKey) { 221 return translatePublicKey((PublicKey)key); 222 } else if (key instanceof PrivateKey) { 223 return translatePrivateKey((PrivateKey)key); 224 } else { 225 throw new InvalidKeyException("Neither a public nor a private key"); 226 } 227 } 228 229 // see JCA doc 230 protected PublicKey engineGeneratePublic(KeySpec keySpec) 231 throws InvalidKeySpecException { 232 try { 233 return generatePublic(keySpec); 234 } catch (InvalidKeySpecException e) { 235 throw e; 236 } catch (GeneralSecurityException e) { 237 throw new InvalidKeySpecException(e); 238 } 239 } 240 241 // see JCA doc 242 protected PrivateKey engineGeneratePrivate(KeySpec keySpec) 243 throws InvalidKeySpecException { 244 try { 245 return generatePrivate(keySpec); 246 } catch (InvalidKeySpecException e) { 247 throw e; 248 } catch (GeneralSecurityException e) { 249 throw new InvalidKeySpecException(e); 250 } 251 } 252 253 // internal implementation of translateKey() for public keys. See JCA doc 254 private PublicKey translatePublicKey(PublicKey key) 255 throws InvalidKeyException { 256 if (key instanceof RSAPublicKey) { 257 RSAPublicKey rsaKey = (RSAPublicKey)key; 258 try { 259 return new RSAPublicKeyImpl( 260 RSAUtil.createAlgorithmId(type, rsaKey.getParams()), 261 rsaKey.getModulus(), 262 rsaKey.getPublicExponent()); 263 } catch (ProviderException e) { 264 // catch providers that incorrectly implement RSAPublicKey 265 throw new InvalidKeyException("Invalid key", e); 266 } 267 } else if ("X.509".equals(key.getFormat())) { 268 byte[] encoded = key.getEncoded(); 269 RSAPublicKey translated = new RSAPublicKeyImpl(encoded); 270 // ensure the key algorithm matches the current KeyFactory instance 271 checkKeyAlgo(translated, type.keyAlgo()); 272 return translated; 273 } else { 274 throw new InvalidKeyException("Public keys must be instance " 275 + "of RSAPublicKey or have X.509 encoding"); 276 } 277 } 278 279 // internal implementation of translateKey() for private keys. See JCA doc 280 private PrivateKey translatePrivateKey(PrivateKey key) 281 throws InvalidKeyException { 282 if (key instanceof RSAPrivateCrtKey) { 283 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; 284 try { 285 return new RSAPrivateCrtKeyImpl( 286 RSAUtil.createAlgorithmId(type, rsaKey.getParams()), 287 rsaKey.getModulus(), 288 rsaKey.getPublicExponent(), 289 rsaKey.getPrivateExponent(), 290 rsaKey.getPrimeP(), 291 rsaKey.getPrimeQ(), 292 rsaKey.getPrimeExponentP(), 293 rsaKey.getPrimeExponentQ(), 294 rsaKey.getCrtCoefficient() 295 ); 296 } catch (ProviderException e) { 297 // catch providers that incorrectly implement RSAPrivateCrtKey 298 throw new InvalidKeyException("Invalid key", e); 299 } 300 } else if (key instanceof RSAPrivateKey) { 301 RSAPrivateKey rsaKey = (RSAPrivateKey)key; 302 try { 303 return new RSAPrivateKeyImpl( 304 RSAUtil.createAlgorithmId(type, rsaKey.getParams()), 305 rsaKey.getModulus(), 306 rsaKey.getPrivateExponent() 307 ); 308 } catch (ProviderException e) { 309 // catch providers that incorrectly implement RSAPrivateKey 310 throw new InvalidKeyException("Invalid key", e); 311 } 312 } else if ("PKCS#8".equals(key.getFormat())) { 313 byte[] encoded = key.getEncoded(); 314 RSAPrivateKey translated = RSAPrivateCrtKeyImpl.newKey(encoded); 315 // ensure the key algorithm matches the current KeyFactory instance 316 checkKeyAlgo(translated, type.keyAlgo()); 317 return translated; 318 } else { 319 throw new InvalidKeyException("Private keys must be instance " 320 + "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); 321 } 322 } 323 324 // internal implementation of generatePublic. See JCA doc 325 private PublicKey generatePublic(KeySpec keySpec) 326 throws GeneralSecurityException { 327 if (keySpec instanceof X509EncodedKeySpec) { 328 X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; 329 RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded()); 330 // ensure the key algorithm matches the current KeyFactory instance 331 checkKeyAlgo(generated, type.keyAlgo()); 332 return generated; 333 } else if (keySpec instanceof RSAPublicKeySpec) { 334 RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec; 335 try { 336 return new RSAPublicKeyImpl( 337 RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), 338 rsaSpec.getModulus(), 339 rsaSpec.getPublicExponent() 340 ); 341 } catch (ProviderException e) { 342 throw new InvalidKeySpecException(e); 343 } 344 } else { 345 throw new InvalidKeySpecException("Only RSAPublicKeySpec " 346 + "and X509EncodedKeySpec supported for RSA public keys"); 347 } 348 } 349 350 // internal implementation of generatePrivate. See JCA doc 351 private PrivateKey generatePrivate(KeySpec keySpec) 352 throws GeneralSecurityException { 353 if (keySpec instanceof PKCS8EncodedKeySpec) { 354 PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; 355 RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded()); 356 // ensure the key algorithm matches the current KeyFactory instance 357 checkKeyAlgo(generated, type.keyAlgo()); 358 return generated; 359 } else if (keySpec instanceof RSAPrivateCrtKeySpec) { 360 RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec; 361 try { 362 return new RSAPrivateCrtKeyImpl( 363 RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), 364 rsaSpec.getModulus(), 365 rsaSpec.getPublicExponent(), 366 rsaSpec.getPrivateExponent(), 367 rsaSpec.getPrimeP(), 368 rsaSpec.getPrimeQ(), 369 rsaSpec.getPrimeExponentP(), 370 rsaSpec.getPrimeExponentQ(), 371 rsaSpec.getCrtCoefficient() 372 ); 373 } catch (ProviderException e) { 374 throw new InvalidKeySpecException(e); 375 } 376 } else if (keySpec instanceof RSAPrivateKeySpec) { 377 RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec; 378 try { 379 return new RSAPrivateKeyImpl( 380 RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), 381 rsaSpec.getModulus(), 382 rsaSpec.getPrivateExponent() 383 ); 384 } catch (ProviderException e) { 385 throw new InvalidKeySpecException(e); 386 } 387 } else { 388 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " 389 + "and PKCS8EncodedKeySpec supported for RSA private keys"); 390 } 391 } 392 393 protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) 394 throws InvalidKeySpecException { 395 try { 396 // convert key to one of our keys 397 // this also verifies that the key is a valid RSA key and ensures 398 // that the encoding is X.509/PKCS#8 for public/private keys 399 key = engineTranslateKey(key); 400 } catch (InvalidKeyException e) { 401 throw new InvalidKeySpecException(e); 402 } 403 if (key instanceof RSAPublicKey) { 404 RSAPublicKey rsaKey = (RSAPublicKey)key; 405 if (RSA_PUB_KEYSPEC_CLS.isAssignableFrom(keySpec)) { 406 return keySpec.cast(new RSAPublicKeySpec( 407 rsaKey.getModulus(), 408 rsaKey.getPublicExponent(), 409 rsaKey.getParams() 410 )); 411 } else if (X509_KEYSPEC_CLS.isAssignableFrom(keySpec)) { 412 return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); 413 } else { 414 throw new InvalidKeySpecException 415 ("KeySpec must be RSAPublicKeySpec or " 416 + "X509EncodedKeySpec for RSA public keys"); 417 } 418 } else if (key instanceof RSAPrivateKey) { 419 if (PKCS8_KEYSPEC_CLS.isAssignableFrom(keySpec)) { 420 return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); 421 } else if (RSA_PRIVCRT_KEYSPEC_CLS.isAssignableFrom(keySpec)) { 422 if (key instanceof RSAPrivateCrtKey) { 423 RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key; 424 return keySpec.cast(new RSAPrivateCrtKeySpec( 425 crtKey.getModulus(), 426 crtKey.getPublicExponent(), 427 crtKey.getPrivateExponent(), 428 crtKey.getPrimeP(), 429 crtKey.getPrimeQ(), 430 crtKey.getPrimeExponentP(), 431 crtKey.getPrimeExponentQ(), 432 crtKey.getCrtCoefficient(), 433 crtKey.getParams() 434 )); 435 } else { 436 throw new InvalidKeySpecException 437 ("RSAPrivateCrtKeySpec can only be used with CRT keys"); 438 } 439 } else if (RSA_PRIV_KEYSPEC_CLS.isAssignableFrom(keySpec)) { 440 RSAPrivateKey rsaKey = (RSAPrivateKey)key; 441 return keySpec.cast(new RSAPrivateKeySpec( 442 rsaKey.getModulus(), 443 rsaKey.getPrivateExponent(), 444 rsaKey.getParams() 445 )); 446 } else { 447 throw new InvalidKeySpecException 448 ("KeySpec must be RSAPrivate(Crt)KeySpec or " 449 + "PKCS8EncodedKeySpec for RSA private keys"); 450 } 451 } else { 452 // should not occur, caught in engineTranslateKey() 453 throw new InvalidKeySpecException("Neither public nor private key"); 454 } 455 } 456 457 public static final class Legacy extends RSAKeyFactory { 458 public Legacy() { 459 super(KeyType.RSA); 460 } 461 } 462 463 public static final class PSS extends RSAKeyFactory { 464 public PSS() { 465 super(KeyType.PSS); 466 } 467 } 468 } |