Skip to content
Permalink
Browse files
8211227: Inconsistent TLS protocol version in debug output
Backport-of: a86728850e9919d2bbeeef70093adbd87bc3bb26
  • Loading branch information
Evan Whelan authored and RealCLanger committed Jun 4, 2021
1 parent 375be17 commit 7616b2c053dd1125e1c553d91ca68e8efb2bc026
Showing 6 changed files with 162 additions and 11 deletions.
@@ -271,7 +271,7 @@ private Ciphertext encode(ByteBuffer[] sources, int offset, int length,

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion + " " +
"WRITE: " + protocolVersion.name + " " +
ContentType.APPLICATION_DATA.name +
", length = " + destination.remaining());
}
@@ -499,7 +499,7 @@ Ciphertext acquireCiphertext(ByteBuffer dstBuf) throws IOException {

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion + " " +
"WRITE: " + protocolVersion.name + " " +
ContentType.nameOf(memo.contentType) +
", length = " + dstBuf.remaining());
}
@@ -297,13 +297,13 @@ private static List<ProtocolVersion> getActiveProtocols(
} else if (SSLLogger.isOn && SSLLogger.isOn("verbose")) {
SSLLogger.fine(
"Ignore unsupported cipher suite: " + suite +
" for " + protocol);
" for " + protocol.name);
}
}

if (!found && (SSLLogger.isOn) && SSLLogger.isOn("handshake")) {
SSLLogger.fine(
"No available cipher suite for " + protocol);
"No available cipher suite for " + protocol.name);
}
}

@@ -269,7 +269,7 @@ private Ciphertext encode(ByteBuffer[] sources, int offset, int length,

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion + " " +
"WRITE: " + protocolVersion.name + " " +
ContentType.APPLICATION_DATA.name +
", length = " + destination.remaining());
}
@@ -508,7 +508,7 @@ Ciphertext acquireCiphertext(ByteBuffer dstBuf) throws IOException {

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion + " " +
"WRITE: " + protocolVersion.name + " " +
ContentType.nameOf(memo.contentType) +
", length = " + dstBuf.remaining());
}
@@ -69,7 +69,7 @@ void encodeAlert(byte level, byte description) throws IOException {
write(level);
write(description);
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine("WRITE: " + protocolVersion +
SSLLogger.fine("WRITE: " + protocolVersion.name +
" " + ContentType.ALERT.name +
"(" + Alert.nameOf(description) + ")" +
", length = " + (count - headerSize));
@@ -180,7 +180,7 @@ void encodeHandshake(byte[] source,

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion +
"WRITE: " + protocolVersion.name +
" " + ContentType.HANDSHAKE.name +
", length = " + (count - headerSize));
}
@@ -256,7 +256,7 @@ public void flush() throws IOException {

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion +
"WRITE: " + protocolVersion.name +
" " + ContentType.HANDSHAKE.name +
", length = " + (count - headerSize));
}
@@ -329,7 +329,7 @@ void deliver(byte[] source, int offset, int length) throws IOException {

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion +
"WRITE: " + protocolVersion.name +
" " + ContentType.APPLICATION_DATA.name +
", length = " + (count - position));
}
@@ -131,7 +131,7 @@ public static void main(String args[]) throws Exception {
OutputAnalyzer output = ProcessTools.executeTestJvm(
"-Dtest.src=" + System.getProperty("test.src"),
"-Djavax.net.debug=all", "DebugReportsOneExtraByte", "p");
output.shouldContain("WRITE: TLS10 application_data, length = 8");
output.shouldContain("WRITE: TLSv1 application_data, length = 8");

System.out.println("Test Passed.");
} else {
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* @test
* @bug 8211227
* @library /test/lib /javax/net/ssl/templates ../../
* @summary Tests for consistency in logging format of TLS Versions
* @run main/othervm LoggingFormatConsistency
*/

/*
* This test runs in another process so we can monitor the debug
* results. The OutputAnalyzer must see correct debug output to return a
* success.
*/

import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.security.SecurityUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.URL;

import static java.nio.charset.StandardCharsets.UTF_8;

public class LoggingFormatConsistency extends SSLSocketTemplate {

LoggingFormatConsistency () {
serverAddress = InetAddress.getLoopbackAddress();
SecurityUtils.removeFromDisabledTlsAlgs("TLSv1", "TLSv1.1");
}

public static void main(String[] args) throws Exception {
if (args.length != 0) {
// A non-empty set of arguments occurs when the "runTest" argument
// is passed to the test via ProcessTools::executeTestJvm.
//
// This is done because an OutputAnalyzer is unable to read
// the output of the current running JVM, and must therefore create
// a test JVM. When this case occurs, it will inherit all specified
// properties passed to the test JVM - debug flags, tls version, etc.
new LoggingFormatConsistency().run();
} else {
// We are in the test JVM that the test is being ran in.
var testSrc = "-Dtest.src=" + System.getProperty("test.src");
var javaxNetDebug = "-Djavax.net.debug=all";

var correctTlsVersionsFormat = new String[]{"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};
var incorrectTLSVersionsFormat = new String[]{"TLS10", "TLS11", "TLS12", "TLS13"};

for (var i = 0; i < correctTlsVersionsFormat.length; i++) {
var expectedTLSVersion = correctTlsVersionsFormat[i];
var incorrectTLSVersion = incorrectTLSVersionsFormat[i];

System.out.println("TESTING " + expectedTLSVersion);
var activeTLSProtocol = "-Djdk.tls.client.protocols=" + expectedTLSVersion;
var output = ProcessTools.executeTestJvm(
testSrc,
activeTLSProtocol,
javaxNetDebug,
"LoggingFormatConsistency",
"runTest"); // Ensuring args.length is greater than 0 when test JVM starts

if (output.getExitValue() != 0) {
throw new RuntimeException("Test JVM process failed. JVM stderr= " + output.getStderr());
}

output.shouldContain(expectedTLSVersion);
output.shouldNotContain(incorrectTLSVersion);
}
}
}

@Override
protected boolean isCustomizedClientConnection() { return true; }

@Override
protected void runServerApplication(SSLSocket socket) throws Exception {
var response = "Hello World!";
var out = new DataOutputStream(socket.getOutputStream());
try {
// We don't need to process the data from the socket
// Simply sending a response right away is sufficient
// to generate the desired debug output
var responseBytes = response.getBytes(UTF_8);

out.writeBytes("HTTP/1.0 200 OK\r\n");
out.writeBytes("Content-Length: " + responseBytes.length + "\r\n");
out.writeBytes("Content-Type: text/html\r\n\r\n");
out.write(responseBytes);
out.flush();
} catch (IOException e) {
out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
out.writeBytes("Content-Type: text/html\r\n\r\n");
out.flush();
}
}

@Override
protected void runClientApplication(int serverPort) throws Exception {
var context = createClientSSLContext();
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());

var host = serverAddress == null ? "localhost" : serverAddress.getHostAddress();
var url = new URL("https://" + host + ":" + serverPort + "/");
var httpsConnection = (HttpsURLConnection) url.openConnection();
httpsConnection.disconnect();
try (var in = new BufferedReader(new InputStreamReader(httpsConnection.getInputStream()))) {
// Getting the input stream from the BufferedReader is sufficient to generate the desired debug output
// We don't need to process the data
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private static class NameVerifier implements HostnameVerifier {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
}

1 comment on commit 7616b2c

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 7616b2c Jun 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.