1 /* 2 * Copyright (c) 2003, 2008, 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 final static Class<?> rsaPublicKeySpecClass = 64 RSAPublicKeySpec.class; 65 private final static Class<?> rsaPrivateKeySpecClass = 66 RSAPrivateKeySpec.class; 67 private final static Class<?> rsaPrivateCrtKeySpecClass = 68 RSAPrivateCrtKeySpec.class; 69 70 private final static Class<?> x509KeySpecClass = X509EncodedKeySpec.class; 71 private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class; 72 73 public final static int MIN_MODLEN = 512; 74 public final static 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 final static int MAX_MODLEN_RESTRICT_EXP = 3072; 84 public final static int MAX_RESTRICTED_EXPLEN = 64; 85 86 private static final boolean restrictExpLen = 87 "true".equalsIgnoreCase(AccessController.doPrivileged( 88 new GetPropertyAction( 89 "sun.security.rsa.restrictRSAExponent", "true"))); 90 91 // instance used for static translateKey(); 92 private final static RSAKeyFactory INSTANCE = new RSAKeyFactory(); 93 94 public RSAKeyFactory() { 95 // empty 96 } 97 98 /** 99 * Static method to convert Key into an instance of RSAPublicKeyImpl 100 * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be 101 * used, throw an InvalidKeyException. 102 * 103 * Used by RSASignature and RSACipher. 104 */ 105 public static RSAKey toRSAKey(Key key) throws InvalidKeyException { 106 if ((key instanceof RSAPrivateKeyImpl) || 107 (key instanceof RSAPrivateCrtKeyImpl) || 108 (key instanceof RSAPublicKeyImpl)) { 109 return (RSAKey)key; 110 } else { 111 return (RSAKey)INSTANCE.engineTranslateKey(key); 112 } 113 } 114 115 /* 116 * Single test entry point for all of the mechanisms in the SunRsaSign 117 * provider (RSA*KeyImpls). All of the tests are the same. 118 * 119 * For compatibility, we round up to the nearest byte here: 120 * some Key impls might pass in a value within a byte of the 121 * real value. 122 */ 123 static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent) 124 throws InvalidKeyException { 125 checkKeyLengths(((modulusLen + 7) & ~7), exponent, 126 RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE); 127 } 128 129 /** 130 * Check the length of an RSA key modulus/exponent to make sure it 131 * is not too short or long. Some impls have their own min and 132 * max key sizes that may or may not match with a system defined value. 133 * 134 * @param modulusLen the bit length of the RSA modulus. 135 * @param exponent the RSA exponent 136 * @param minModulusLen if > 0, check to see if modulusLen is at 137 * least this long, otherwise unused. 138 * @param maxModulusLen caller will allow this max number of bits. 139 * Allow the smaller of the system-defined maximum and this param. 140 * 141 * @throws InvalidKeyException if any of the values are unacceptable. 142 */ 143 public static void checkKeyLengths(int modulusLen, BigInteger exponent, 144 int minModulusLen, int maxModulusLen) throws InvalidKeyException { 145 146 if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) { 147 throw new InvalidKeyException( "RSA keys must be at least " + 148 minModulusLen + " bits long"); 149 } 150 151 // Even though our policy file may allow this, we don't want 152 // either value (mod/exp) to be too big. 153 154 int maxLen = Math.min(maxModulusLen, MAX_MODLEN); 155 156 // If a RSAPrivateKey/RSAPublicKey, make sure the 157 // modulus len isn't too big. 158 if (modulusLen > maxLen) { 159 throw new InvalidKeyException( 160 "RSA keys must be no longer than " + maxLen + " bits"); 161 } 162 163 // If a RSAPublicKey, make sure the exponent isn't too big. 164 if (restrictExpLen && (exponent != null) && 165 (modulusLen > MAX_MODLEN_RESTRICT_EXP) && 166 (exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) { 167 throw new InvalidKeyException( 168 "RSA exponents can be no longer than " + 169 MAX_RESTRICTED_EXPLEN + " bits " + 170 " if modulus is greater than " + 171 MAX_MODLEN_RESTRICT_EXP + " bits"); 172 } 173 } 174 175 /** 176 * Translate an RSA key into a SunRsaSign RSA key. If conversion is 177 * not possible, throw an InvalidKeyException. 178 * See also JCA doc. 179 */ 180 protected Key engineTranslateKey(Key key) throws InvalidKeyException { 181 if (key == null) { 182 throw new InvalidKeyException("Key must not be null"); 183 } 184 String keyAlg = key.getAlgorithm(); 185 if (keyAlg.equals("RSA") == false) { 186 throw new InvalidKeyException("Not an RSA key: " + keyAlg); 187 } 188 if (key instanceof PublicKey) { 189 return translatePublicKey((PublicKey)key); 190 } else if (key instanceof PrivateKey) { 191 return translatePrivateKey((PrivateKey)key); 192 } else { 193 throw new InvalidKeyException("Neither a public nor a private key"); 194 } 195 } 196 197 // see JCA doc 198 protected PublicKey engineGeneratePublic(KeySpec keySpec) 199 throws InvalidKeySpecException { 200 try { 201 return generatePublic(keySpec); 202 } catch (InvalidKeySpecException e) { 203 throw e; 204 } catch (GeneralSecurityException e) { 205 throw new InvalidKeySpecException(e); 206 } 207 } 208 209 // see JCA doc 210 protected PrivateKey engineGeneratePrivate(KeySpec keySpec) 211 throws InvalidKeySpecException { 212 try { 213 return generatePrivate(keySpec); 214 } catch (InvalidKeySpecException e) { 215 throw e; 216 } catch (GeneralSecurityException e) { 217 throw new InvalidKeySpecException(e); 218 } 219 } 220 221 // internal implementation of translateKey() for public keys. See JCA doc 222 private PublicKey translatePublicKey(PublicKey key) 223 throws InvalidKeyException { 224 if (key instanceof RSAPublicKey) { 225 if (key instanceof RSAPublicKeyImpl) { 226 return key; 227 } 228 RSAPublicKey rsaKey = (RSAPublicKey)key; 229 try { 230 return new RSAPublicKeyImpl( 231 rsaKey.getModulus(), 232 rsaKey.getPublicExponent() 233 ); 234 } catch (RuntimeException e) { 235 // catch providers that incorrectly implement RSAPublicKey 236 throw new InvalidKeyException("Invalid key", e); 237 } 238 } else if ("X.509".equals(key.getFormat())) { 239 byte[] encoded = key.getEncoded(); 240 return new RSAPublicKeyImpl(encoded); 241 } else { 242 throw new InvalidKeyException("Public keys must be instance " 243 + "of RSAPublicKey or have X.509 encoding"); 244 } 245 } 246 247 // internal implementation of translateKey() for private keys. See JCA doc 248 private PrivateKey translatePrivateKey(PrivateKey key) 249 throws InvalidKeyException { 250 if (key instanceof RSAPrivateCrtKey) { 251 if (key instanceof RSAPrivateCrtKeyImpl) { 252 return key; 253 } 254 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; 255 try { 256 return new RSAPrivateCrtKeyImpl( 257 rsaKey.getModulus(), 258 rsaKey.getPublicExponent(), 259 rsaKey.getPrivateExponent(), 260 rsaKey.getPrimeP(), 261 rsaKey.getPrimeQ(), 262 rsaKey.getPrimeExponentP(), 263 rsaKey.getPrimeExponentQ(), 264 rsaKey.getCrtCoefficient() 265 ); 266 } catch (RuntimeException e) { 267 // catch providers that incorrectly implement RSAPrivateCrtKey 268 throw new InvalidKeyException("Invalid key", e); 269 } 270 } else if (key instanceof RSAPrivateKey) { 271 if (key instanceof RSAPrivateKeyImpl) { 272 return key; 273 } 274 RSAPrivateKey rsaKey = (RSAPrivateKey)key; 275 try { 276 return new RSAPrivateKeyImpl( 277 rsaKey.getModulus(), 278 rsaKey.getPrivateExponent() 279 ); 280 } catch (RuntimeException e) { 281 // catch providers that incorrectly implement RSAPrivateKey 282 throw new InvalidKeyException("Invalid key", e); 283 } 284 } else if ("PKCS#8".equals(key.getFormat())) { 285 byte[] encoded = key.getEncoded(); 286 return RSAPrivateCrtKeyImpl.newKey(encoded); 287 } else { 288 throw new InvalidKeyException("Private keys must be instance " 289 + "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); 290 } 291 } 292 293 // internal implementation of generatePublic. See JCA doc 294 private PublicKey generatePublic(KeySpec keySpec) 295 throws GeneralSecurityException { 296 if (keySpec instanceof X509EncodedKeySpec) { 297 X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; 298 return new RSAPublicKeyImpl(x509Spec.getEncoded()); 299 } else if (keySpec instanceof RSAPublicKeySpec) { 300 RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec; 301 return new RSAPublicKeyImpl( 302 rsaSpec.getModulus(), 303 rsaSpec.getPublicExponent() 304 ); 305 } else { 306 throw new InvalidKeySpecException("Only RSAPublicKeySpec " 307 + "and X509EncodedKeySpec supported for RSA public keys"); 308 } 309 } 310 311 // internal implementation of generatePrivate. See JCA doc 312 private PrivateKey generatePrivate(KeySpec keySpec) 313 throws GeneralSecurityException { 314 if (keySpec instanceof PKCS8EncodedKeySpec) { 315 PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; 316 return RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded()); 317 } else if (keySpec instanceof RSAPrivateCrtKeySpec) { 318 RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec; 319 return new RSAPrivateCrtKeyImpl( 320 rsaSpec.getModulus(), 321 rsaSpec.getPublicExponent(), 322 rsaSpec.getPrivateExponent(), 323 rsaSpec.getPrimeP(), 324 rsaSpec.getPrimeQ(), 325 rsaSpec.getPrimeExponentP(), 326 rsaSpec.getPrimeExponentQ(), 327 rsaSpec.getCrtCoefficient() 328 ); 329 } else if (keySpec instanceof RSAPrivateKeySpec) { 330 RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec; 331 return new RSAPrivateKeyImpl( 332 rsaSpec.getModulus(), 333 rsaSpec.getPrivateExponent() 334 ); 335 } else { 336 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " 337 + "and PKCS8EncodedKeySpec supported for RSA private keys"); 338 } 339 } 340 341 protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) 342 throws InvalidKeySpecException { 343 try { 344 // convert key to one of our keys 345 // this also verifies that the key is a valid RSA key and ensures 346 // that the encoding is X.509/PKCS#8 for public/private keys 347 key = engineTranslateKey(key); 348 } catch (InvalidKeyException e) { 349 throw new InvalidKeySpecException(e); 350 } 351 if (key instanceof RSAPublicKey) { 352 RSAPublicKey rsaKey = (RSAPublicKey)key; 353 if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) { 354 return (T) new RSAPublicKeySpec( 355 rsaKey.getModulus(), 356 rsaKey.getPublicExponent() 357 ); 358 } else if (x509KeySpecClass.isAssignableFrom(keySpec)) { 359 return (T) new X509EncodedKeySpec(key.getEncoded()); 360 } else { 361 throw new InvalidKeySpecException 362 ("KeySpec must be RSAPublicKeySpec or " 363 + "X509EncodedKeySpec for RSA public keys"); 364 } 365 } else if (key instanceof RSAPrivateKey) { 366 if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) { 367 return (T) new PKCS8EncodedKeySpec(key.getEncoded()); 368 } else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) { 369 if (key instanceof RSAPrivateCrtKey) { 370 RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key; 371 return (T) new RSAPrivateCrtKeySpec( 372 crtKey.getModulus(), 373 crtKey.getPublicExponent(), 374 crtKey.getPrivateExponent(), 375 crtKey.getPrimeP(), 376 crtKey.getPrimeQ(), 377 crtKey.getPrimeExponentP(), 378 crtKey.getPrimeExponentQ(), 379 crtKey.getCrtCoefficient() 380 ); 381 } else { 382 throw new InvalidKeySpecException 383 ("RSAPrivateCrtKeySpec can only be used with CRT keys"); 384 } 385 } else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) { 386 RSAPrivateKey rsaKey = (RSAPrivateKey)key; 387 return (T) new RSAPrivateKeySpec( 388 rsaKey.getModulus(), 389 rsaKey.getPrivateExponent() 390 ); 391 } else { 392 throw new InvalidKeySpecException 393 ("KeySpec must be RSAPrivate(Crt)KeySpec or " 394 + "PKCS8EncodedKeySpec for RSA private keys"); 395 } 396 } else { 397 // should not occur, caught in engineTranslateKey() 398 throw new InvalidKeySpecException("Neither public nor private key"); 399 } 400 } 401 }