mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-16 01:40:31 +00:00
8371333: Optimize static initialization of SSLContextImpl classes and improve logging
Reviewed-by: hchao, jnimeh
This commit is contained in:
parent
ce6ccd385f
commit
93fe49abef
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, 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
|
||||
@ -31,6 +31,7 @@ import java.security.*;
|
||||
import java.security.cert.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.net.ssl.*;
|
||||
import sun.security.provider.certpath.AlgorithmChecker;
|
||||
import sun.security.ssl.SSLAlgorithmConstraints.SIGNATURE_CONSTRAINTS_MODE;
|
||||
@ -366,13 +367,24 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
Collection<CipherSuite> allowedCipherSuites,
|
||||
List<ProtocolVersion> protocols) {
|
||||
LinkedHashSet<CipherSuite> suites = new LinkedHashSet<>();
|
||||
List<String> disabledSuites = null;
|
||||
List<String> unAvailableSuites = null;
|
||||
|
||||
if (SSLLogger.isOn() && SSLLogger.isOn(SSLLogger.Opt.SSLCTX)) {
|
||||
disabledSuites = new ArrayList<>();
|
||||
unAvailableSuites = new ArrayList<>();
|
||||
}
|
||||
|
||||
if (protocols != null && (!protocols.isEmpty())) {
|
||||
for (CipherSuite suite : allowedCipherSuites) {
|
||||
if (!suite.isAvailable()) {
|
||||
if (SSLLogger.isOn() &&
|
||||
SSLLogger.isOn(SSLLogger.Opt.SSLCTX)) {
|
||||
unAvailableSuites.add(suite.name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isSupported = false;
|
||||
for (ProtocolVersion protocol : protocols) {
|
||||
if (!suite.supports(protocol) ||
|
||||
!suite.bulkCipher.isAvailable()) {
|
||||
@ -383,27 +395,43 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
suite.name, null)) {
|
||||
suites.add(suite);
|
||||
isSupported = true;
|
||||
} else if (SSLLogger.isOn() &&
|
||||
SSLLogger.isOn(SSLLogger.Opt.HANDSHAKE)) {
|
||||
SSLLogger.fine(
|
||||
"Ignore disabled cipher suite: " + suite.name);
|
||||
SSLLogger.isOn(SSLLogger.Opt.SSLCTX)) {
|
||||
disabledSuites.add(suite.name);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isSupported && SSLLogger.isOn() &&
|
||||
SSLLogger.isOn(SSLLogger.Opt.HANDSHAKE)) {
|
||||
SSLLogger.finest(
|
||||
"Ignore unsupported cipher suite: " + suite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(SSLLogger.isOn() && SSLLogger.isOn(SSLLogger.Opt.SSLCTX)) {
|
||||
logSuites("Ignore disabled cipher suites for protocols: ",
|
||||
protocols, disabledSuites);
|
||||
logSuites("Ignore unavailable cipher suites for protocols: ",
|
||||
protocols, unAvailableSuites);
|
||||
logSuites("Available cipher suites for protocols: ",
|
||||
protocols, suites);
|
||||
|
||||
}
|
||||
return new ArrayList<>(suites);
|
||||
}
|
||||
|
||||
private static void logSuites(String message,
|
||||
List<ProtocolVersion> protocols,
|
||||
Collection<?> suites) {
|
||||
if (suites.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String protocolStr = protocols.stream()
|
||||
.map(pv -> pv.name)
|
||||
.collect(Collectors.joining(", ", "[", "]"));
|
||||
String suiteStr = String.join(", ",
|
||||
suites.stream().map(Object::toString).collect(Collectors.toList()));
|
||||
SSLLogger.finest(message + protocolStr + System.lineSeparator() +
|
||||
Utilities.wrapText("[" + suiteStr + "]", 140));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the customized cipher suites specified by the given system property.
|
||||
*/
|
||||
@ -459,10 +487,14 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cipherSuites.isEmpty() && SSLLogger.isOn()
|
||||
&& SSLLogger.isOn(SSLLogger.Opt.SSLCTX)) {
|
||||
SSLLogger.fine(
|
||||
"No cipher suites satisfy property: " + propertyName +
|
||||
". Returning empty list");
|
||||
}
|
||||
return cipherSuites;
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -530,9 +562,6 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
private static final List<ProtocolVersion> supportedProtocols;
|
||||
private static final List<ProtocolVersion> serverDefaultProtocols;
|
||||
|
||||
private static final List<CipherSuite> supportedCipherSuites;
|
||||
private static final List<CipherSuite> serverDefaultCipherSuites;
|
||||
|
||||
static {
|
||||
supportedProtocols = Arrays.asList(
|
||||
ProtocolVersion.TLS13,
|
||||
@ -550,13 +579,15 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
ProtocolVersion.TLS11,
|
||||
ProtocolVersion.TLS10
|
||||
});
|
||||
|
||||
supportedCipherSuites = getApplicableSupportedCipherSuites(
|
||||
supportedProtocols);
|
||||
serverDefaultCipherSuites = getApplicableEnabledCipherSuites(
|
||||
serverDefaultProtocols, false);
|
||||
}
|
||||
|
||||
private static final LazyConstant<List<CipherSuite>>
|
||||
supportedCipherSuites = LazyConstant.of(() ->
|
||||
getApplicableSupportedCipherSuites(supportedProtocols));
|
||||
private static final LazyConstant<List<CipherSuite>>
|
||||
serverDefaultCipherSuites = LazyConstant.of(() ->
|
||||
getApplicableEnabledCipherSuites(serverDefaultProtocols, false));
|
||||
|
||||
@Override
|
||||
List<ProtocolVersion> getSupportedProtocolVersions() {
|
||||
return supportedProtocols;
|
||||
@ -564,7 +595,7 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
|
||||
@Override
|
||||
List<CipherSuite> getSupportedCipherSuites() {
|
||||
return supportedCipherSuites;
|
||||
return supportedCipherSuites.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -574,7 +605,7 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
|
||||
@Override
|
||||
List<CipherSuite> getServerDefaultCipherSuites() {
|
||||
return serverDefaultCipherSuites;
|
||||
return serverDefaultCipherSuites.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -814,10 +845,18 @@ public abstract class SSLContextImpl extends SSLContextSpi {
|
||||
clientDefaultCipherSuites =
|
||||
getApplicableEnabledCipherSuites(
|
||||
clientDefaultProtocols, true);
|
||||
serverDefaultCipherSuites =
|
||||
getApplicableEnabledCipherSuites(
|
||||
serverDefaultProtocols, false);
|
||||
|
||||
// getApplicableEnabledCipherSuites returns same CS List if
|
||||
// no customized CS in use and protocols are same. Can avoid
|
||||
// the getApplicableEnabledCipherSuites call
|
||||
if (clientCustomizedCipherSuites.isEmpty() &&
|
||||
serverCustomizedCipherSuites.isEmpty() &&
|
||||
clientDefaultProtocols.equals(serverDefaultProtocols)) {
|
||||
serverDefaultCipherSuites = clientDefaultCipherSuites;
|
||||
} else {
|
||||
serverDefaultCipherSuites =
|
||||
getApplicableEnabledCipherSuites(
|
||||
serverDefaultProtocols, false);
|
||||
}
|
||||
} else {
|
||||
// unlikely to be used
|
||||
clientDefaultProtocols = null;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026, 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
|
||||
@ -168,6 +168,35 @@ final class Utilities {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
static String wrapText(String text, int maxWidth) {
|
||||
if (text == null || text.isEmpty() || maxWidth <= 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder result = new StringBuilder();
|
||||
String[] values = text.split(",\\s*");
|
||||
StringBuilder line = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
String value = values[i];
|
||||
// If adding this value would exceed maxWidth
|
||||
if (line.length() > 0) {
|
||||
// +1 for the comma
|
||||
if (line.length() + 1 + value.length() > maxWidth) {
|
||||
result.append(line).append(LINE_SEP);
|
||||
line.setLength(0);
|
||||
} else {
|
||||
line.append(",");
|
||||
}
|
||||
}
|
||||
line.append(value);
|
||||
}
|
||||
// Append any remaining line
|
||||
if (line.length() > 0) {
|
||||
result.append(line);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
static String byte16HexString(int id) {
|
||||
return "0x" + HEX_FORMATTER.toHexDigits((short)id);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 2026, 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
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8350582 8340312 8369995 8044609 8372004
|
||||
* @bug 8350582 8340312 8369995 8044609 8372004 8371333
|
||||
* @library /test/lib /javax/net/ssl/templates
|
||||
* @summary Correct the parsing of the ssl value in javax.net.debug
|
||||
* @run junit DebugPropertyValuesTest
|
||||
@ -60,8 +60,8 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate {
|
||||
"supported_versions"));
|
||||
debugMessages.put("handshake-expand",
|
||||
List.of("\"logger\".*: \"javax.net.ssl\",",
|
||||
"\"specifics\" : \\[",
|
||||
"\"message\".*: \"Produced ClientHello handshake message"));
|
||||
"\"specifics\" : \\[",
|
||||
"\"message\".*: \"Produced ClientHello handshake message"));
|
||||
debugMessages.put("keymanager", List.of("Choosing key:"));
|
||||
debugMessages.put("packet", List.of("Raw write"));
|
||||
debugMessages.put("plaintext",
|
||||
@ -73,11 +73,13 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate {
|
||||
debugMessages.put("session", List.of("Session initialized:"));
|
||||
debugMessages.put("ssl", List.of("jdk.tls.keyLimits:"));
|
||||
debugMessages.put("sslctx",
|
||||
List.of("trigger seeding of SecureRandom"));
|
||||
List.of("trigger seeding of SecureRandom",
|
||||
// Available list should finish with this style
|
||||
"TLS_EMPTY_RENEGOTIATION_INFO_SCSV]",
|
||||
"Ignore disabled cipher suites for protocols: " +
|
||||
"\\[TLSv1.3, TLSv1.2\\]"));
|
||||
debugMessages.put("trustmanager",
|
||||
List.of("adding as trusted certificates"));
|
||||
debugMessages.put("verbose",
|
||||
List.of("Ignore unsupported cipher suite:"));
|
||||
debugMessages.put("help",
|
||||
List.of("print this help message and exit",
|
||||
"verbose handshake message printing"));
|
||||
@ -110,17 +112,16 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate {
|
||||
Arguments.of(List.of("-Djavax.net.debug=all"),
|
||||
List.of("handshake", "keymanager", "packet",
|
||||
"plaintext", "record", "session", "ssl",
|
||||
"sslctx", "trustmanager", "verbose")),
|
||||
"sslctx", "trustmanager")),
|
||||
// ssl should print most details except verbose details
|
||||
Arguments.of(List.of("-Djavax.net.debug=ssl"),
|
||||
List.of("handshake", "keymanager",
|
||||
"record", "session", "ssl",
|
||||
"sslctx", "trustmanager", "verbose")),
|
||||
"sslctx", "trustmanager")),
|
||||
// allow expand option for more verbose output
|
||||
Arguments.of(
|
||||
List.of("-Djavax.net.debug=ssl,handshake,expand"),
|
||||
List.of("handshake", "handshake-expand",
|
||||
"ssl", "verbose")),
|
||||
List.of("handshake", "handshake-expand", "ssl")),
|
||||
// filtering on record option, with expand
|
||||
Arguments.of(List.of("-Djavax.net.debug=ssl:record,expand"),
|
||||
List.of("record", "record-expand", "ssl")),
|
||||
@ -142,12 +143,12 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate {
|
||||
Arguments.of(List.of("-Djavax.net.debug=ssl,typo"),
|
||||
List.of("handshake", "keymanager",
|
||||
"record", "session", "ssl",
|
||||
"sslctx", "trustmanager", "verbose")),
|
||||
"sslctx", "trustmanager")),
|
||||
// ssltypo contains "ssl". Treat like "ssl"
|
||||
Arguments.of(List.of("-Djavax.net.debug=ssltypo"),
|
||||
List.of("handshake", "keymanager",
|
||||
"record", "session", "ssl",
|
||||
"sslctx", "trustmanager", "verbose")),
|
||||
"sslctx", "trustmanager")),
|
||||
// plaintext is valid for record option
|
||||
Arguments.of(List.of("-Djavax.net.debug=ssl:record:plaintext"),
|
||||
List.of("plaintext", "record", "ssl")),
|
||||
@ -168,7 +169,7 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate {
|
||||
List.of("handshake", "javax.net.debug.logger",
|
||||
"keymanager", "packet", "plaintext",
|
||||
"record", "session", "ssl",
|
||||
"sslctx", "trustmanager", "verbose"))
|
||||
"sslctx", "trustmanager"))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user