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 }