JDK-8215524 : Finished message validation failure should be decrypt_error alert
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 11,12,13
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-12-18
  • Updated: 2020-11-19
  • Resolved: 2019-02-25
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 8 Other
11.0.6-oracleFixed 13 b10Fixed 8u261Fixed openjdk8u272Fixed
Description
When Finished message verification fails, JSSE responds illegal_parameter error alert, like the below,
javax.net.ssl|ERROR|01|main|2018-12-18 10:33:09.490 CST|TransportContext.java:313|Fatal (ILLEGAL_PARAMETER): The Finished message cannot be verified. (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: The Finished message cannot be verified.
  	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
  	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
  	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
  	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
  	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
  	at java.base/sun.security.ssl.Finished$FinishedMessage.<init>(Finished.java:124)
  	at java.base/sun.security.ssl.Finished$T13FinishedConsumer.onConsumeFinished(Finished.java:984)
  	at java.base/sun.security.ssl.Finished$T13FinishedConsumer.consume(Finished.java:859)
  	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
  	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:448)
  	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:425)
  	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:178)
  	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)
  	at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:716)
  	at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:799)
  	at java.base/java.io.InputStream.read(InputStream.java:213)
... ...
javax.net.ssl|DEBUG|01|main|2018-12-18 10:36:13.753 CST|SSLSocketOutputRecord.java:71|WRITE: TLS13 alert(illegal_parameter), length = 2

but per RFC 8446 section 6.2, this alert should be decrypt_error.
"decrypt_error:  A handshake (not record layer) cryptographic operation failed, including being unable to correctly verify a signature or validate a Finished message or a PSK binder."
Comments
Fix request I want to downport this for parity with 11.0.6-oracle. Applies clean.
15-11-2019

In addition, per RFC 8446 section 6.2: "decode_error: A message could not be decoded because some field was out of the specified range or the length of the message was incorrect..." So, if Finished is missed (empty or cannot be parsed), this would alert decode_error. javax.net.ssl|ERROR|01|main|2019-02-25 11:01:16.551 CST|TransportContext.java:312|Fatal (ILLEGAL_PARAMETER): Inappropriate finished message: need 32 but remaining 0 bytes verify_data ( "throwable" : { javax.net.ssl.SSLHandshakeException: Inappropriate finished message: need 32 but remaining 0 bytes verify_data 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:307) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:254) at java.base/sun.security.ssl.Finished$FinishedMessage.<init>(Finished.java:105) at java.base/sun.security.ssl.Finished$T13FinishedConsumer.onConsumeFinished(Finished.java:996) at java.base/sun.security.ssl.Finished$T13FinishedConsumer.consume(Finished.java:867) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:441) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:419) at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:177) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164) at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1180) at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1091) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402) at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:721) at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:804) at java.base/java.io.InputStream.read(InputStream.java:213) at SimpleTLS.readIn(SimpleTLS.java:40) at SimpleTLS.main(SimpleTLS.java:27)} ) javax.net.ssl|ALL|01|main|2019-02-25 11:01:16.552 CST|SSLSessionImpl.java:795|Invalidated session: Session(1551063676261|TLS_AES_128_GCM_SHA256) javax.net.ssl|DEBUG|01|main|2019-02-25 11:01:16.552 CST|SSLSocketOutputRecord.java:71|WRITE: TLS13 alert(illegal_parameter), length = 2
25-02-2019

Finished message should be encrypted. In RFC 8446 section 4.4.4: ... The key used to compute the Finished message is computed from the Base Key defined in Section 4.4 using HKDF (see Section 7.1). Specifically: finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) ... The same section also states: Recipients of Finished messages MUST verify that the contents are correct and if incorrect MUST terminate the connection with a "decrypt_error" alert.
18-12-2018

I think illegal_parameter is correct error here since there is no cryptographic operation attempted yet. I will leave it to Xuelei to validate and close as not a bug if he agrees.
18-12-2018

Some other associated cases in Finished.java [1] also should be double-checked. For example, 100 if (m.remaining() != verifyDataLen) { 101 context.conContext.fatal(Alert.ILLEGAL_PARAMETER, 102 "Inappropriate finished message: need " + verifyDataLen + 103 " but remaining " + m.remaining() + " bytes verify_data"); 104 } [1] http://hg.openjdk.java.net/jdk/jdk/file/d5a2a29ca589/src/java.base/share/classes/sun/security/ssl/Finished.java
18-12-2018