< prev index next >

src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java

Print this page


   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 }
< prev index next >