8366364: Return enabled signature schemes with SSLConfiguration#getSSLParameters() call

Reviewed-by: mullan
This commit is contained in:
Artur Barashev 2025-11-03 15:05:16 +00:00
parent 18e8873cad
commit 02a7217491
8 changed files with 209 additions and 44 deletions

View File

@ -146,6 +146,16 @@ public final class SecuritySettings {
ostream.println(THREEINDENT + s);
}
}
ostream.println("\n" + TWOINDENT + "Enabled Signature Schemes:");
String[] schemes = ssls.getSSLParameters().getSignatureSchemes();
if (schemes == null) {
ostream.println(THREEINDENT + "<none>");
} else {
for (String s : schemes) {
ostream.println(THREEINDENT + s);
}
}
}
ostream.println();

View File

@ -38,6 +38,7 @@ import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import sun.security.ssl.SSLExtension.ClientExtensions;
import sun.security.ssl.SSLExtension.ServerExtensions;
import sun.security.ssl.SignatureScheme.SupportedSigSchemes;
/**
* SSL/(D)TLS configuration.
@ -241,8 +242,12 @@ final class SSLConfiguration implements Cloneable {
this.maximumPacketSize = 0; // please reset it explicitly later
this.signatureSchemes = isClientMode ?
CustomizedClientSignatureSchemes.signatureSchemes :
CustomizedServerSignatureSchemes.signatureSchemes;
CustomizedClientSignatureSchemes.signatureSchemes != null ?
CustomizedClientSignatureSchemes.signatureSchemes :
SupportedSigSchemes.DEFAULT :
CustomizedServerSignatureSchemes.signatureSchemes != null ?
CustomizedServerSignatureSchemes.signatureSchemes :
SupportedSigSchemes.DEFAULT;
this.namedGroups = NamedGroup.SupportedGroups.namedGroups;
this.maximumProtocolVersion = ProtocolVersion.NONE;
for (ProtocolVersion pv : enabledProtocols) {
@ -362,7 +367,9 @@ final class SSLConfiguration implements Cloneable {
// Note if 'ss' is empty, then no signature schemes should be
// specified over the connections.
this.signatureSchemes = ss;
} // Otherwise, use the default values
} else { // Otherwise, use the default values.
this.signatureSchemes = SupportedSigSchemes.DEFAULT;
}
String[] ngs = params.getNamedGroups();
if (ngs != null) {
@ -514,7 +521,8 @@ final class SSLConfiguration implements Cloneable {
void toggleClientMode() {
this.isClientMode ^= true;
// Reset the signature schemes, if it was configured with SSLParameters.
// Reset the signature schemes, if it was configured with a
// system property.
if (Arrays.equals(signatureSchemes,
CustomizedClientSignatureSchemes.signatureSchemes) ||
Arrays.equals(signatureSchemes,

View File

@ -297,7 +297,7 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* Return whether a protocol list is the original default enabled
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultProtocolVesions(List<ProtocolVersion> protocols) {
boolean isDefaultProtocolVersions(List<ProtocolVersion> protocols) {
return (protocols == getServerDefaultProtocolVersions()) ||
(protocols == getClientDefaultProtocolVersions());
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2025, 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
@ -195,7 +195,7 @@ final class SSLServerSocketImpl extends SSLServerSocket {
* default ones.
*/
if (sslConfig.isClientMode != useClientMode) {
if (sslContext.isDefaultProtocolVesions(
if (sslContext.isDefaultProtocolVersions(
sslConfig.enabledProtocols)) {
sslConfig.enabledProtocols =
sslContext.getDefaultProtocolVersions(!useClientMode);

View File

@ -34,7 +34,6 @@ import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -413,11 +412,23 @@ enum SignatureScheme {
List<ProtocolVersion> activeProtocols,
Set<SSLScope> scopes) {
List<SignatureScheme> supported = new LinkedList<>();
List<SignatureScheme> schemesToCheck;
List<SignatureScheme> schemesToCheck =
config.signatureSchemes == null ?
Arrays.asList(SignatureScheme.values()) :
namesOfAvailable(config.signatureSchemes);
// No need to look up the names of the default signature schemes.
if (config.signatureSchemes == SupportedSigSchemes.DEFAULT) {
schemesToCheck = Arrays.asList(SignatureScheme.values());
} else {
schemesToCheck = new ArrayList<>();
for (String name : config.signatureSchemes) {
var ss = SignatureScheme.nameOf(name);
if (ss != null) {
schemesToCheck.add(ss);
} else {
SSLLogger.logWarning("ssl,handshake", "Unavailable "
+ "configured signature scheme: " + name);
}
}
}
for (SignatureScheme ss: schemesToCheck) {
if (!ss.isAvailable) {
@ -470,8 +481,8 @@ enum SignatureScheme {
"Unsupported signature scheme: " +
SignatureScheme.nameOf(ssid));
}
} else if ((config.signatureSchemes == null
|| Utilities.contains(config.signatureSchemes, ss.name))
} else if ((config.signatureSchemes == SupportedSigSchemes.DEFAULT
|| Utilities.contains(config.signatureSchemes, ss.name))
&& ss.isAllowed(constraints, protocolVersion, scopes)) {
supported.add(ss);
} else {
@ -614,33 +625,6 @@ enum SignatureScheme {
return new String[0];
}
private static List<SignatureScheme> namesOfAvailable(
String[] signatureSchemes) {
if (signatureSchemes == null || signatureSchemes.length == 0) {
return Collections.emptyList();
}
List<SignatureScheme> sss = new ArrayList<>(signatureSchemes.length);
for (String ss : signatureSchemes) {
SignatureScheme scheme = SignatureScheme.nameOf(ss);
if (scheme == null || !scheme.isAvailable) {
if (SSLLogger.isOn &&
SSLLogger.isOn("ssl,handshake,verbose")) {
SSLLogger.finest(
"Ignore the signature algorithm (" + ss
+ "), unsupported or unavailable");
}
continue;
}
sss.add(scheme);
}
return sss;
}
// This method is used to get the signature instance of this signature
// scheme for the specific public key. Unlike getSigner(), the exception
// is bubbled up. If the public key does not support this signature
@ -686,4 +670,15 @@ enum SignatureScheme {
return null;
}
// Default signature schemes for SSLConfiguration.
static final class SupportedSigSchemes {
static final String[] DEFAULT = Arrays.stream(
SignatureScheme.values())
.filter(ss -> ss.isAvailable
&& ss.isPermitted(
SSLAlgorithmConstraints.DEFAULT, null))
.map(ss -> ss.name).toArray(String[]::new);
}
}

View File

@ -471,7 +471,7 @@ final class TransportContext implements ConnectionContext {
* default ones.
*/
if (sslConfig.isClientMode != useClientMode) {
if (sslContext.isDefaultProtocolVesions(
if (sslContext.isDefaultProtocolVersions(
sslConfig.enabledProtocols)) {
sslConfig.enabledProtocols =
sslContext.getDefaultProtocolVersions(!useClientMode);

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2025, 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 8366364
* @summary Return enabled signature schemes with
* SSLConfiguration#getSSLParameters() call
* @library /javax/net/ssl/templates
* /test/lib
* @comment *_sha224 signatures schemes are not available on Windows
* @requires os.family != "windows"
*
* @run main/othervm DefaultSSLConfigSignatureSchemes
* @run main/othervm
* -Djdk.tls.server.SignatureSchemes=ecdsa_secp384r1_sha384,ed25519
* -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256,ed448
* DefaultSSLConfigSignatureSchemes
*/
import static jdk.test.lib.Asserts.assertFalse;
import static jdk.test.lib.Asserts.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import javax.net.ssl.SSLEngine;
import jdk.test.lib.security.SecurityUtils;
public class DefaultSSLConfigSignatureSchemes extends SSLEngineTemplate {
protected static final String DISABLED_SS = "ecdsa_secp521r1_sha512";
protected static final String[] CUSTOM_SS = new String[]{
"ecdsa_secp256r1_sha256",
"ecdsa_secp384r1_sha384"};
protected static final List<String> REFERENCE_SS = Stream.of(
"ecdsa_secp256r1_sha256",
"ecdsa_secp384r1_sha384",
"ecdsa_secp521r1_sha512",
"ed25519",
"ed448",
"rsa_pss_rsae_sha256",
"rsa_pss_rsae_sha384",
"rsa_pss_rsae_sha512",
"rsa_pss_pss_sha256",
"rsa_pss_pss_sha384",
"rsa_pss_pss_sha512",
"rsa_pkcs1_sha256",
"rsa_pkcs1_sha384",
"rsa_pkcs1_sha512",
"dsa_sha256",
"ecdsa_sha224",
"rsa_sha224",
"dsa_sha224",
"ecdsa_sha1",
"rsa_pkcs1_sha1",
"dsa_sha1")
.sorted()
.toList();
protected DefaultSSLConfigSignatureSchemes() throws Exception {
super();
}
public static void main(String[] args) throws Exception {
SecurityUtils.addToDisabledTlsAlgs(DISABLED_SS);
var test = new DefaultSSLConfigSignatureSchemes();
var propertyClientSS =
System.getProperty("jdk.tls.client.SignatureSchemes");
var propertyServerSS =
System.getProperty("jdk.tls.server.SignatureSchemes");
// Test jdk.tls.client.SignatureSchemes system property.
if (propertyClientSS != null) {
comparePropertySSWithEngineSS(propertyClientSS, test.clientEngine);
}
// Test jdk.tls.server.SignatureSchemes system property.
if (propertyServerSS != null) {
comparePropertySSWithEngineSS(propertyServerSS, test.serverEngine);
}
// Test default signature schemes and custom values if no system
// properties are present.
if (propertyClientSS == null && propertyServerSS == null) {
for (SSLEngine engine :
new SSLEngine[]{test.serverEngine, test.clientEngine}) {
// Test default config signature schemes.
checkEngineDefaultSS(engine);
// Test custom values.
var sslParams = engine.getSSLParameters();
sslParams.setSignatureSchemes(CUSTOM_SS);
engine.setSSLParameters(sslParams);
assertTrue(Arrays.equals(CUSTOM_SS,
engine.getSSLParameters().getSignatureSchemes()));
// Set null custom value, default signature schemes should
// be returned.
sslParams.setSignatureSchemes(null);
engine.setSSLParameters(sslParams);
checkEngineDefaultSS(engine);
}
}
}
private static void comparePropertySSWithEngineSS(
String property, SSLEngine engine) {
var engineSS = Stream.of(engine
.getSSLParameters().getSignatureSchemes()).sorted().toList();
var propertySS = Stream.of(property.split(",")).sorted().toList();
assertTrue(engineSS.equals(propertySS), "Engine signature scheme: "
+ engineSS + "; Property signature scheme: " + propertySS);
}
private static void checkEngineDefaultSS(SSLEngine engine) {
var defaultConfigSS = new ArrayList<>(List.of(
engine.getSSLParameters().getSignatureSchemes()));
assertFalse(defaultConfigSS.contains(DISABLED_SS));
defaultConfigSS.add(DISABLED_SS);
assertTrue(REFERENCE_SS.equals(
defaultConfigSS.stream().sorted().toList()),
"Signature schemes returned by engine: " + defaultConfigSS);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2025, 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
@ -25,7 +25,7 @@ import java.io.IOException;
/*
* @test
* @bug 6994753 7123582 8305950 8281658 8310201 8311653 8343804 8351354
* @bug 6994753 7123582 8305950 8281658 8310201 8311653 8343804 8351354 8366364
* @summary tests -XshowSettings options
* @modules jdk.compiler
* jdk.zipfs
@ -84,6 +84,8 @@ public class Settings extends TestHelper {
private static final String TZDATA_SETTINGS = "tzdata version";
private static final String ERR_MSG = "Unrecognized showSettings option:";
private static final String ENABLED_GROUPS_SETTINGS = "Enabled Named Groups:";
private static final String ENABLED_SIG_SCHEMES_SETTINGS =
"Enabled Signature Schemes:";
/*
* "all" should print verbose settings
@ -107,6 +109,7 @@ public class Settings extends TestHelper {
checkNotContains(tr, METRICS_NOT_AVAILABLE_MSG);
}
checkContains(tr, ENABLED_GROUPS_SETTINGS);
checkContains(tr, ENABLED_SIG_SCHEMES_SETTINGS);
}
/*
* default (no options) should print non verbose
@ -237,6 +240,7 @@ public class Settings extends TestHelper {
// test a well known TLS config for sanity
checkContains(tr, "TLSv1.2");
checkContains(tr, ENABLED_GROUPS_SETTINGS);
checkContains(tr, ENABLED_SIG_SCHEMES_SETTINGS);
}
// ensure error message is printed when unrecognized option used