OpenJDK / jdk-updates / jdk11u
changeset 52566:ff2ef987e77a
8231780: Better TLS messaging support
Reviewed-by: ascarpino, rhalade, mschoene
author | jnimeh |
---|---|
date | Mon, 28 Oct 2019 18:53:51 -0700 |
parents | 336d24e8dcd1 |
children | d13c9c7f4156 |
files | src/java.base/share/classes/sun/security/ssl/Alert.java src/java.base/share/classes/sun/security/ssl/CertificateMessage.java src/java.base/share/classes/sun/security/ssl/CertificateVerify.java src/java.base/share/classes/sun/security/ssl/Finished.java |
diffstat | 4 files changed, 83 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/share/classes/sun/security/ssl/Alert.java Wed Oct 23 15:14:24 2019 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/Alert.java Mon Oct 28 18:53:51 2019 -0700 @@ -271,8 +271,14 @@ ClientAuthType.CLIENT_AUTH_REQUESTED)) { throw tc.fatal(Alert.HANDSHAKE_FAILURE, "received handshake warning: " + alert.description); - } // Otherwise, ignore the warning - } // Otherwise, ignore the warning. + } else { + // Otherwise ignore the warning but remove the + // CertificateVerify handshake consumer so the state + // machine doesn't expect it. + tc.handshakeContext.handshakeConsumers.remove( + SSLHandshake.CERTIFICATE_VERIFY.id); + } + } // Otherwise, ignore the warning } else { // fatal or unknown String diagnostic; if (alert == null) {
--- a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java Wed Oct 23 15:14:24 2019 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java Mon Oct 28 18:53:51 2019 -0700 @@ -371,6 +371,10 @@ T12CertificateMessage certificateMessage )throws IOException { List<byte[]> encodedCerts = certificateMessage.encodedCertChain; if (encodedCerts == null || encodedCerts.isEmpty()) { + // For empty Certificate messages, we should not expect + // a CertificateVerify message to follow + shc.handshakeConsumers.remove( + SSLHandshake.CERTIFICATE_VERIFY.id); if (shc.sslConfig.clientAuthType != ClientAuthType.CLIENT_AUTH_REQUESTED) { // unexpected or require client authentication @@ -1157,6 +1161,10 @@ T13CertificateMessage certificateMessage )throws IOException { if (certificateMessage.certEntries == null || certificateMessage.certEntries.isEmpty()) { + // For empty Certificate messages, we should not expect + // a CertificateVerify message to follow + shc.handshakeConsumers.remove( + SSLHandshake.CERTIFICATE_VERIFY.id); if (shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED) { throw shc.conContext.fatal(Alert.BAD_CERTIFICATE, "Empty client certificate chain");
--- a/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java Wed Oct 23 15:14:24 2019 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java Mon Oct 28 18:53:51 2019 -0700 @@ -286,6 +286,17 @@ ByteBuffer message) throws IOException { // The consuming happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)context; + + // Clean up this consumer + shc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id); + + // Ensure that the CV message follows the CKE + if (shc.handshakeConsumers.containsKey( + SSLHandshake.CLIENT_KEY_EXCHANGE.id)) { + throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected CertificateVerify handshake message"); + } + S30CertificateVerifyMessage cvm = new S30CertificateVerifyMessage(shc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -528,6 +539,17 @@ ByteBuffer message) throws IOException { // The consuming happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)context; + + // Clean up this consumer + shc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id); + + // Ensure that the CV message follows the CKE + if (shc.handshakeConsumers.containsKey( + SSLHandshake.CLIENT_KEY_EXCHANGE.id)) { + throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected CertificateVerify handshake message"); + } + T10CertificateVerifyMessage cvm = new T10CertificateVerifyMessage(shc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -768,6 +790,17 @@ ByteBuffer message) throws IOException { // The consuming happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)context; + + // Clean up this consumer + shc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id); + + // Ensure that the CV message follows the CKE + if (shc.handshakeConsumers.containsKey( + SSLHandshake.CLIENT_KEY_EXCHANGE.id)) { + throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected CertificateVerify handshake message"); + } + T12CertificateVerifyMessage cvm = new T12CertificateVerifyMessage(shc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -1122,6 +1155,10 @@ ByteBuffer message) throws IOException { // The producing happens in handshake context only. HandshakeContext hc = (HandshakeContext)context; + + // Clean up this consumer + hc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id); + T13CertificateVerifyMessage cvm = new T13CertificateVerifyMessage(hc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
--- a/src/java.base/share/classes/sun/security/ssl/Finished.java Wed Oct 23 15:14:24 2019 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/Finished.java Mon Oct 28 18:53:51 2019 -0700 @@ -580,6 +580,16 @@ private void onConsumeFinished(ServerHandshakeContext shc, ByteBuffer message) throws IOException { + // Make sure that any expected CertificateVerify message + // has been received and processed. + if (!shc.isResumption) { + if (shc.handshakeConsumers.containsKey( + SSLHandshake.CERTIFICATE_VERIFY.id)) { + throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected Finished handshake message"); + } + } + FinishedMessage fm = new FinishedMessage(shc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine( @@ -871,6 +881,16 @@ private void onConsumeFinished(ClientHandshakeContext chc, ByteBuffer message) throws IOException { + // Make sure that any expected CertificateVerify message + // has been received and processed. + if (!chc.isResumption) { + if (chc.handshakeConsumers.containsKey( + SSLHandshake.CERTIFICATE_VERIFY.id)) { + throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected Finished handshake message"); + } + } + FinishedMessage fm = new FinishedMessage(chc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine( @@ -993,6 +1013,16 @@ private void onConsumeFinished(ServerHandshakeContext shc, ByteBuffer message) throws IOException { + // Make sure that any expected CertificateVerify message + // has been received and processed. + if (!shc.isResumption) { + if (shc.handshakeConsumers.containsKey( + SSLHandshake.CERTIFICATE_VERIFY.id)) { + throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, + "Unexpected Finished handshake message"); + } + } + FinishedMessage fm = new FinishedMessage(shc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine(