JDK-8149017 : Delayed provider selection broken in RSA client key exchange.
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 8u72,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-02-03
  • Updated: 2017-07-06
  • Resolved: 2017-07-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 JDK 8 JDK 9
6u115Fixed 7u111Fixed 8u102Fixed 9 b112Fixed
Related Reports
Duplicate :  
Duplicate :  
Sub Tasks
JDK-8155741 :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_72"
Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
Java HotSpot(TM) Client VM (build 25.72-b15, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
OS independent, but tested on Windows 7.

EXTRA RELEVANT SYSTEM CONFIGURATION :
Irrelevant for the issue

A DESCRIPTION OF THE PROBLEM :
This bug has been introduced in the RSAClientKeyExchange with change:
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/3e9d6880f36f

The old (working) code looked like this:
            Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
            cipher.init(...);

The new (broken) code does this:
            Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
            boolean needFailover = !KeyUtil.isOracleJCEProvider(
                    cipher.getProvider().getName());
            if (needFailover) {
                cipher.init(Cipher.DECRYPT_MODE, privateKey);

Even shorter, it used to be:
- cipher.init

And now it's:
- cipher.getProvider()
- cipher.init

The problem with this is that calling cipher.getProvider before cipher.init breaks delayed provider selection. It forces the first provider with a matching algorithm to be selected (ignoring the key type).
This will cause an error when a incompatible key from a different provider then the first is supplied.
For example, this breaks if a PKCS11 provider (with a RSA keystore) is used, which is not the first in the list of providers. In old versions this would work without problem.

The problem manifests itself as failed SSL connections, with the following in the debug log (-Djavax.net.debug=all):
"http-bio-443-exec-6, handling exception: javax.net.ssl.SSLProtocolException: Unable to process PreMasterSecret, may be too big" The error message isn't quite correct, it's the default handling of a InvalidKeyException in RSAClientKeyExchange.




REGRESSION.  Last worked in version 6u45

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) Client VM (build 25.45-b02, mixed mode)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Use a PKCS11 provider (hardware token).
- Make sure the PKCS11 provider is the last in the list of security providers.
- Start a SSL connection using a RSA key from a keystore from the PKCS11 provider.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
SSL connections is set up without issue.
ACTUAL -
SSL Connection fails, an error is logged in the debug log (-Djavax.net.debug=all):
"http-bio-443-exec-6, handling exception: javax.net.ssl.SSLProtocolException: Unable to process PreMasterSecret, may be too big" The error message isn't quite correct, it's the default handling of a InvalidKeyException in RSAClientKeyExchange.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
"http-bio-443-exec-6, handling exception: javax.net.ssl.SSLProtocolException: Unable to process PreMasterSecret, may be too big" The error message isn't quite correct, it's the default handling of a InvalidKeyException in RSAClientKeyExchange.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Since a pkcs11 provider/hardware token is required, I can't provide a self contained sample. The description should be quite clear though.

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
It might possibly work if you add the PKCS11 provider as the first provider in the list of security providers. But this is not always a acceptable/possible workaround.



Comments
CPU16_02 is jdk8u75/u76. Not 8u72. 8u72 is CPU16_01. But anyway I agree it's too late for CPU16_02 to provide the fix. Not sure is't OK to defer it till CPU16_03. Woulld better to have the fix ASAP and provide it in one of the BPR time slot after CPU16_02 GA.
15-03-2016