Skip to content
Permalink
Browse files
8211227: Inconsistent TLS protocol version in debug output
Reviewed-by: sgehwolf
Backport-of: a867288
  • Loading branch information
TheRealMDoerr committed Sep 14, 2021
1 parent 74eed68 commit 124f3aca23ddf7c4f5a5959b1519dcf5b610be3b
Showing 6 changed files with 165 additions and 11 deletions.
@@ -266,7 +266,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());
}
@@ -494,7 +494,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());
}
@@ -295,13 +295,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);
}
}

@@ -264,7 +264,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());
}
@@ -503,7 +503,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());
}
@@ -68,7 +68,7 @@ synchronized void encodeAlert(
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));
@@ -173,7 +173,7 @@ synchronized void encodeHandshake(byte[] source,

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

if (SSLLogger.isOn && SSLLogger.isOn("record")) {
SSLLogger.fine(
"WRITE: " + protocolVersion +
"WRITE: " + protocolVersion.name +
" " + ContentType.HANDSHAKE.name +
", length = " + (count - headerSize));
}
@@ -307,7 +307,7 @@ synchronized void deliver(

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,154 @@
/*
* 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 {

// JDK-8230435 introduces serverAddress in SSLSocketTemplate, but we don't have it.
InetAddress serverAddress;

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 124f3ac

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 124f3ac Sep 14, 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.