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.getProperty( 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 131 * max key sizes that may or may not match with a system defined value. 132 * 133 * @param modulusLen the bit length of the RSA modulus. 134 * @param exponent the RSA exponent 135 * @param minModulusLen if {@literal > 0}, check to see if modulusLen is at 136 * least this long, otherwise unused. 137 * @param maxModulusLen caller will allow this max number of bits. 138 * Allow the smaller of the system-defined maximum and this param. 139 * 140 * @throws InvalidKeyException if any of the values are unacceptable. 141 */ 142 public static void checkKeyLengths(int modulusLen, BigInteger exponent, 143 int minModulusLen, int maxModulusLen) throws InvalidKeyException { 144 145 if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) { 146 throw new InvalidKeyException( "RSA keys must be at least " + 147 minModulusLen + " bits long"); 148 } 149 150 // Even though our policy file may allow this, we don't want 151 // either value (mod/exp) to be too big. 152 153 int maxLen = Math.min(maxModulusLen, MAX_MODLEN); 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 }