jdk/src/windows/classes/sun/security/mscapi/RSACipher.java
changeset 23733 b9b80421cfa7
parent 11521 d7698e6c5f51
equal deleted inserted replaced
23732:44fe768edfd2 23733:b9b80421cfa7
    33 
    33 
    34 import javax.crypto.*;
    34 import javax.crypto.*;
    35 import javax.crypto.spec.*;
    35 import javax.crypto.spec.*;
    36 
    36 
    37 import sun.security.rsa.RSAKeyFactory;
    37 import sun.security.rsa.RSAKeyFactory;
       
    38 import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
       
    39 import sun.security.util.KeyUtil;
    38 
    40 
    39 /**
    41 /**
    40  * RSA cipher implementation using the Microsoft Crypto API.
    42  * RSA cipher implementation using the Microsoft Crypto API.
    41  * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
    43  * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
    42  *
    44  *
    90     // size of the output (the length of the key).
    92     // size of the output (the length of the key).
    91     private int outputSize;
    93     private int outputSize;
    92 
    94 
    93     // the public key, if we were initialized using a public key
    95     // the public key, if we were initialized using a public key
    94     private sun.security.mscapi.Key publicKey;
    96     private sun.security.mscapi.Key publicKey;
       
    97 
    95     // the private key, if we were initialized using a private key
    98     // the private key, if we were initialized using a private key
    96     private sun.security.mscapi.Key privateKey;
    99     private sun.security.mscapi.Key privateKey;
       
   100 
       
   101     // cipher parameter for TLS RSA premaster secret
       
   102     private AlgorithmParameterSpec spec = null;
       
   103 
       
   104     // the source of randomness
       
   105     private SecureRandom random;
    97 
   106 
    98     public RSACipher() {
   107     public RSACipher() {
    99         paddingType = PAD_PKCS1;
   108         paddingType = PAD_PKCS1;
   100     }
   109     }
   101 
   110 
   153     protected void engineInit(int opmode, Key key,
   162     protected void engineInit(int opmode, Key key,
   154             AlgorithmParameterSpec params, SecureRandom random)
   163             AlgorithmParameterSpec params, SecureRandom random)
   155             throws InvalidKeyException, InvalidAlgorithmParameterException {
   164             throws InvalidKeyException, InvalidAlgorithmParameterException {
   156 
   165 
   157         if (params != null) {
   166         if (params != null) {
   158             throw new InvalidAlgorithmParameterException
   167             if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
   159                 ("Parameters not supported");
   168                 throw new InvalidAlgorithmParameterException(
       
   169                         "Parameters not supported");
       
   170             }
       
   171             spec = params;
       
   172             this.random = random;   // for TLS RSA premaster secret
   160         }
   173         }
   161         init(opmode, key);
   174         init(opmode, key);
   162     }
   175     }
   163 
   176 
   164     // see JCE spec
   177     // see JCE spec
   354             throw new InvalidKeyException("Wrapping failed", e);
   367             throw new InvalidKeyException("Wrapping failed", e);
   355         }
   368         }
   356     }
   369     }
   357 
   370 
   358     // see JCE spec
   371     // see JCE spec
   359     protected java.security.Key engineUnwrap(byte[] wrappedKey, String algorithm,
   372     protected java.security.Key engineUnwrap(byte[] wrappedKey,
       
   373             String algorithm,
   360             int type) throws InvalidKeyException, NoSuchAlgorithmException {
   374             int type) throws InvalidKeyException, NoSuchAlgorithmException {
   361 
   375 
   362         if (wrappedKey.length > buffer.length) {
   376         if (wrappedKey.length > buffer.length) {
   363             throw new InvalidKeyException("Key is too long for unwrapping");
   377             throw new InvalidKeyException("Key is too long for unwrapping");
   364         }
   378         }
       
   379 
       
   380         boolean isTlsRsaPremasterSecret =
       
   381                 algorithm.equals("TlsRsaPremasterSecret");
       
   382         Exception failover = null;
       
   383         byte[] encoded = null;
       
   384 
   365         update(wrappedKey, 0, wrappedKey.length);
   385         update(wrappedKey, 0, wrappedKey.length);
   366 
       
   367         try {
   386         try {
   368             byte[] encoding = doFinal();
   387             encoded = doFinal();
   369 
   388         } catch (BadPaddingException e) {
   370             switch (type) {
   389             if (isTlsRsaPremasterSecret) {
   371             case Cipher.PUBLIC_KEY:
   390                 failover = e;
   372                 return constructPublicKey(encoding, algorithm);
   391             } else {
   373 
   392                 throw new InvalidKeyException("Unwrapping failed", e);
   374             case Cipher.PRIVATE_KEY:
       
   375                 return constructPrivateKey(encoding, algorithm);
       
   376 
       
   377             case Cipher.SECRET_KEY:
       
   378                 return constructSecretKey(encoding, algorithm);
       
   379 
       
   380             default:
       
   381                 throw new InvalidKeyException("Unknown key type " + type);
       
   382             }
   393             }
   383 
       
   384         } catch (BadPaddingException e) {
       
   385             // should not occur
       
   386             throw new InvalidKeyException("Unwrapping failed", e);
       
   387 
       
   388         } catch (IllegalBlockSizeException e) {
   394         } catch (IllegalBlockSizeException e) {
   389             // should not occur, handled with length check above
   395             // should not occur, handled with length check above
   390             throw new InvalidKeyException("Unwrapping failed", e);
   396             throw new InvalidKeyException("Unwrapping failed", e);
   391         }
   397         }
       
   398 
       
   399         if (isTlsRsaPremasterSecret) {
       
   400             if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
       
   401                 throw new IllegalStateException(
       
   402                         "No TlsRsaPremasterSecretParameterSpec specified");
       
   403             }
       
   404 
       
   405             // polish the TLS premaster secret
       
   406             encoded = KeyUtil.checkTlsPreMasterSecretKey(
       
   407                 ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
       
   408                 ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
       
   409                 random, encoded, (failover != null));
       
   410         }
       
   411 
       
   412         return constructKey(encoded, algorithm, type);
   392     }
   413     }
   393 
   414 
   394     // see JCE spec
   415     // see JCE spec
   395     protected int engineGetKeySize(Key key) throws InvalidKeyException {
   416     protected int engineGetKeySize(Key key) throws InvalidKeyException {
   396 
   417 
   448     // Construct an encoded secret key.
   469     // Construct an encoded secret key.
   449     private static SecretKey constructSecretKey(byte[] encodedKey,
   470     private static SecretKey constructSecretKey(byte[] encodedKey,
   450         String encodedKeyAlgorithm) {
   471         String encodedKeyAlgorithm) {
   451 
   472 
   452         return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
   473         return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
       
   474     }
       
   475 
       
   476     private static Key constructKey(byte[] encodedKey,
       
   477             String encodedKeyAlgorithm,
       
   478             int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
       
   479 
       
   480         switch (keyType) {
       
   481             case Cipher.PUBLIC_KEY:
       
   482                 return constructPublicKey(encodedKey, encodedKeyAlgorithm);
       
   483             case Cipher.PRIVATE_KEY:
       
   484                 return constructPrivateKey(encodedKey, encodedKeyAlgorithm);
       
   485             case Cipher.SECRET_KEY:
       
   486                 return constructSecretKey(encodedKey, encodedKeyAlgorithm);
       
   487             default:
       
   488                 throw new InvalidKeyException("Unknown key type " + keyType);
       
   489         }
   453     }
   490     }
   454 
   491 
   455     /*
   492     /*
   456      * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY.
   493      * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY.
   457      * It expects and returns ciphertext data in big-endian form.
   494      * It expects and returns ciphertext data in big-endian form.