JDK-8236039 : JSSE Client does not accept status_request extension in CertificateRequest messages for TLS 1.3
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 8,11,14,15
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2019-12-16
  • Updated: 2021-02-19
  • Resolved: 2020-01-06
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 11 JDK 13 JDK 14 JDK 15 JDK 8 Other
11.0.7Fixed 13.0.3Fixed 14.0.2Fixed 15 b05Fixed 8u261Fixed openjdk8u272Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
The JSSE client will not accept the status_request message when TLS 1.3 is negotiated and the server sends a CertiicateRequest message with that extension in it.

When this occurs the client throws an exception:
javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request

This is an allowed extension in TLS 1.3.

Since the client does not currently support OCSP stapling, the client should not throw an exception on the extension, but instead should proceed with presenting the certificate without any OCSP response information.

Support for client-side OCSP stapling is out of scope for this bug and should be filed as a separate RFE.
Comments
Fix Request (For 14u): This issue is now affecting Kubernetes as well and thus the priority has been raised to a P2. The backport applies cleanly and manual testing has been done to verify the fix.
19-06-2020

This is a problem for Kubernetes: https://github.com/kubernetes-client/java/issues/874 so changing the priority to P2
19-06-2020

Further information from the submitter: I used Oracle Java 11 on Windows 10 to generate the log in the previous email. Here's the version info: ------------------------------------------------------ java version "11.0.7" 2020-04-14 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.7+8-LTS) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.7+8-LTS, mixed mode) ------------------------------------------------------ I also tested the same with Oracle Java 14, as well as Zulu 11. The former throws the same exception as Oracle Java 11, but the latter runs without issues. I attached the logs for these versions as well. To be specific: Oracle Java 14, ------------------------------------------------------ java version "14.0.1" 2020-04-14 Java(TM) SE Runtime Environment (build 14.0.1+7) Java HotSpot(TM) 64-Bit Server VM (build 14.0.1+7, mixed mode, sharing) ------------------------------------------------------ Zulu 11, ------------------------------------------------------ openjdk version "11.0.7" 2020-04-14 LTS OpenJDK Runtime Environment Zulu11.39+15-CA (build 11.0.7+10-LTS) OpenJDK 64-Bit Server VM Zulu11.39+15-CA (build 11.0.7+10-LTS, mixed mode) ------------------------------------------------------
12-05-2020

Requested a detailed log on the client side (-Djavax.net.debug=ssl:handshake)
12-05-2020

Another submitter provides more information about this issue: ADDITIONAL SYSTEM INFORMATION : The issue occurs on Oracle JDK 11+, as TLS 1.3 is not yet supported by previous version of Oracle JDK (I tested 11.0.6, 11.0.7, and 14.0.1) on Windows 10. A DESCRIPTION OF THE PROBLEM : When client authentication is enabled, the issue reported in JDK-8236039 arises. This can be tested by running the Go application attached to JDK-8236039 with switch "-A NEEDVFY", and connect to it with a JSSE client with TLS1.3 and client authentication configured. The issue happened on Oracle JDK. I tested it with Zulu JDK without any issue. STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : 1) Run the Go application attached to JDK-8236039 with switch "-A NEEDVFY". 2) Create a JSSE client with client authentication properly configured: SSLContext sslContext = SSLContextBuilder .create() .loadKeyMaterial(keyStore, keyStoreIntegrityKey, entryConfidentialityKey) .loadTrustMaterial(trustStore, trustStoreIntegrityKey) .build(); EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - I expected the JSSE client to handshake properly with the server. ACTUAL - I received the following exception: Exception in thread "main" javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:314) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:270) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:261) at java.base/sun.security.ssl.SSLExtensions.<init>(SSLExtensions.java:89) at java.base/sun.security.ssl.CertificateRequest$T13CertificateRequestMessage.<init>(CertificateRequest.java:818) at java.base/sun.security.ssl.CertificateRequest$T13CertificateRequestConsumer.consume(CertificateRequest.java:922) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:451) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:428) at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:184) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164) at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1151) at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1062) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402) ...... ---------- BEGIN SOURCE ---------- import javax.net.ssl.*; import java.io.File; import java.security.KeyStore; import java.security.SecureRandom; public class SSLSocketClient { public static void main(String[] args) throws Exception { File trustStore = new File("trustStore.p12"); File keyStore = new File("keyStore.p12"); char[] password = "123".toCharArray(); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore ks = KeyStore.getInstance(keyStore, password); kmf.init(ks, password); TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore ts = KeyStore.getInstance(trustStore, password); tmf.init(ts); SSLContext sslContext = SSLContext.getInstance("TLSv1.3"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); SSLSocketFactory factory = sslContext.getSocketFactory(); SSLSocket socket = (SSLSocket) factory.createSocket("localhost", 443); socket.startHandshake(); } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : I used Zulu JDK to compile my program, and it worked OK. FREQUENCY : always
12-05-2020

Fix Request (13u) This allows us to better handle exceptions in tls code, applies cleanly
24-03-2020

RFR for 11u: https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2020-January/002349.html
09-01-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/b9d1ce20dd4b User: jnimeh Date: 2020-01-06 05:05:05 +0000
06-01-2020

I've attached a simple HTTPS server written in Go that can be used to create the issue since JSSE does not currently assert this extension in CertificateRequest messages. This code should be built using Go 1.13 (I used 1.13.5) and once built is invoked as follows: tlsserv -c <CERT-FILE> -k <KEY-FILE> -p <PORT> -A NEED There are a couple other command-line flags, but this is all you need to make the issue happen. I will be marking this bug as noreg-hard due to the fact that it is currently difficult to write completely java-based TLS 1.3 tests when the endpoints don't implement certain features like this.
28-12-2019

Original github discussion about the issue: https://github.com/golang/go/issues/35722
19-12-2019

The change is pretty simple, just invoke the SSLExtension constructor for CR_STATUS_REQUEST and use nulls for all producer and consumer fields. Then a JSSE client will ignore the extension but it will show up in debug logs. I have tested the fix against a simple golang TLS server configured to add the status_request extension in the CR message and it makes it through the handshake.
19-12-2019