Skip to content

Commit a7f1e32

Browse files
committed
8350582: Correct the parsing of the ssl value in javax.net.debug
Backport-of: 1ec64811a365442c902e334b56f4cf926c316a4a
1 parent 7e0f520 commit a7f1e32

File tree

2 files changed

+190
-3
lines changed

2 files changed

+190
-3
lines changed

src/java.base/share/classes/sun/security/ssl/SSLLogger.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -143,8 +143,10 @@ private static boolean hasOption(String option) {
143143
if (property.contains("all")) {
144144
return true;
145145
} else {
146-
int offset = property.indexOf("ssl");
147-
if (offset != -1 && property.indexOf("sslctx", offset) != -1) {
146+
// remove first occurrence of "sslctx" since
147+
// it interferes with search for "ssl"
148+
String modified = property.replaceFirst("sslctx", "");
149+
if (modified.contains("ssl")) {
148150
// don't enable data and plaintext options by default
149151
if (!(option.equals("data")
150152
|| option.equals("packet")
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8350582
27+
* @library /test/lib /javax/net/ssl/templates
28+
* @summary Correct the parsing of the ssl value in javax.net.debug
29+
* @run junit DebugPropertyValuesTest
30+
*/
31+
32+
// A test to verify debug output for different javax.net.debug scenarios
33+
34+
import jdk.test.lib.process.ProcessTools;
35+
36+
import org.junit.jupiter.api.BeforeAll;
37+
import org.junit.jupiter.params.ParameterizedTest;
38+
import org.junit.jupiter.params.provider.Arguments;
39+
import org.junit.jupiter.params.provider.MethodSource;
40+
41+
import java.nio.file.Files;
42+
import java.nio.file.Path;
43+
import java.util.ArrayList;
44+
import java.util.HashMap;
45+
import java.util.List;
46+
import java.util.stream.Stream;
47+
48+
import jdk.test.lib.process.OutputAnalyzer;
49+
50+
public class DebugPropertyValuesTest extends SSLSocketTemplate {
51+
52+
private static final Path LOG_FILE = Path.of("logging.conf");
53+
private static final HashMap<String, List<String>> debugMessages = new HashMap<>();
54+
55+
static {
56+
debugMessages.put("handshake",
57+
List.of("Produced ClientHello handshake message",
58+
"supported_versions"));
59+
debugMessages.put("keymanager", List.of("choosing key:"));
60+
debugMessages.put("packet", List.of("Raw write"));
61+
debugMessages.put("plaintext", List.of("Plaintext before ENCRYPTION"));
62+
debugMessages.put("record", List.of("handshake, length =", "WRITE:"));
63+
debugMessages.put("session", List.of("Session initialized:"));
64+
debugMessages.put("sslctx", List.of("trigger seeding of SecureRandom"));
65+
debugMessages.put("ssl", List.of("jdk.tls.keyLimits:"));
66+
debugMessages.put("trustmanager", List.of("adding as trusted certificates"));
67+
debugMessages.put("verbose", List.of("Ignore unsupported cipher suite:"));
68+
debugMessages.put("handshake-expand",
69+
List.of("\"logger\".*: \"javax.net.ssl\",",
70+
"\"message\".*: \"Produced ClientHello handshake message"));
71+
debugMessages.put("record-expand",
72+
List.of("\"logger\".*: \"javax.net.ssl\",",
73+
"\"message\".*: \"READ: TLSv1.2 application_data"));
74+
debugMessages.put("help",
75+
List.of("print the help messages",
76+
"debugging can be widened with:"));
77+
debugMessages.put("javax.net.debug",
78+
List.of("properties: Initial security property:",
79+
"certpath: Cert path validation succeeded"));
80+
debugMessages.put("logger",
81+
List.of("FINE: adding as trusted certificates",
82+
"FINE: WRITE: TLSv1.3 application_data"));
83+
}
84+
85+
@BeforeAll
86+
static void setup() throws Exception {
87+
Files.writeString(LOG_FILE, ".level = ALL\n" +
88+
"handlers= java.util.logging.ConsoleHandler\n" +
89+
"java.util.logging.ConsoleHandler.level = ALL\n");
90+
}
91+
92+
private static Stream<Arguments> patternMatches() {
93+
return Stream.of(
94+
// all should print everything
95+
Arguments.of(List.of("-Djavax.net.debug=all"),
96+
List.of("handshake", "keymanager", "packet",
97+
"plaintext", "record", "session", "ssl",
98+
"sslctx", "trustmanager", "verbose")),
99+
// ssl should print most details except verbose details
100+
Arguments.of(List.of("-Djavax.net.debug=ssl"),
101+
List.of("handshake", "keymanager",
102+
"record", "session", "ssl",
103+
"sslctx", "trustmanager", "verbose")),
104+
// allow expand option for more verbose output
105+
Arguments.of(List.of("-Djavax.net.debug=ssl,handshake,expand"),
106+
List.of("handshake", "handshake-expand", "keymanager",
107+
"record", "session", "record-expand", "ssl",
108+
"sslctx", "trustmanager", "verbose")),
109+
// filtering on record option, with expand
110+
Arguments.of(List.of("-Djavax.net.debug=ssl:record,expand"),
111+
List.of("handshake", "handshake-expand", "keymanager",
112+
"record", "record-expand", "session", "ssl",
113+
"sslctx", "trustmanager", "verbose")),
114+
// this test is equivalent to ssl:record mode
115+
Arguments.of(List.of("-Djavax.net.debug=ssl,record"),
116+
List.of("handshake", "keymanager", "record",
117+
"session", "ssl", "sslctx",
118+
"trustmanager", "verbose")),
119+
// example of test where no "ssl" value is passed
120+
// handshake debugging with verbose mode
121+
// only verbose gets printed. Needs fixing (JDK-8044609)
122+
Arguments.of(List.of("-Djavax.net.debug=handshake:verbose"),
123+
List.of("verbose")),
124+
// another example of test where no "ssl" value is passed
125+
Arguments.of(List.of("-Djavax.net.debug=record"),
126+
List.of("record")),
127+
// ignore bad sub-option. treat like "ssl"
128+
Arguments.of(List.of("-Djavax.net.debug=ssl,typo"),
129+
List.of("handshake", "keymanager",
130+
"record", "session", "ssl",
131+
"sslctx", "trustmanager", "verbose")),
132+
// ssltypo contains "ssl". Treat like "ssl"
133+
Arguments.of(List.of("-Djavax.net.debug=ssltypo"),
134+
List.of("handshake", "keymanager",
135+
"record", "session", "ssl",
136+
"sslctx", "trustmanager", "verbose")),
137+
// plaintext is valid for record option
138+
Arguments.of(List.of("-Djavax.net.debug=ssl:record:plaintext"),
139+
List.of("handshake", "keymanager", "plaintext",
140+
"record", "session", "ssl",
141+
"sslctx", "trustmanager", "verbose")),
142+
Arguments.of(List.of("-Djavax.net.debug=ssl:trustmanager"),
143+
List.of("handshake", "keymanager", "record", "session",
144+
"ssl", "sslctx", "trustmanager", "verbose")),
145+
Arguments.of(List.of("-Djavax.net.debug=ssl:sslctx"),
146+
List.of("handshake", "keymanager", "record", "session",
147+
"ssl", "sslctx", "trustmanager", "verbose")),
148+
// help message test. Should exit without running test
149+
Arguments.of(List.of("-Djavax.net.debug=help"),
150+
List.of("help")),
151+
// add in javax.net.debug sanity test
152+
Arguments.of(List.of("-Djavax.net.debug=ssl:trustmanager",
153+
"-Djava.security.debug=all"),
154+
List.of("handshake", "javax.net.debug", "keymanager",
155+
"record", "session", "ssl", "sslctx",
156+
"trustmanager", "verbose")),
157+
// empty invokes System.Logger use
158+
Arguments.of(List.of("-Djavax.net.debug",
159+
"-Djava.util.logging.config.file=" + LOG_FILE),
160+
List.of("handshake", "keymanager", "logger", "packet",
161+
"plaintext", "record", "session", "ssl",
162+
"sslctx", "trustmanager", "verbose"))
163+
);
164+
}
165+
166+
@ParameterizedTest
167+
@MethodSource("patternMatches")
168+
public void checkDebugOutput(List<String> params,
169+
List<String> expected) throws Exception {
170+
171+
List<String> args = new ArrayList<>(params);
172+
args.add("DebugPropertyValuesTest");
173+
OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(args);
174+
outputAnalyzer.shouldHaveExitValue(0);
175+
for (String s : debugMessages.keySet()) {
176+
for (String output : debugMessages.get(s)) {
177+
if (expected.contains(s)) {
178+
outputAnalyzer.shouldMatch(output);
179+
} else {
180+
outputAnalyzer.shouldNotMatch(output);
181+
}
182+
}
183+
}
184+
}
185+
}

0 commit comments

Comments
 (0)