diff --git a/src/java.base/share/classes/sun/launcher/SecuritySettings.java b/src/java.base/share/classes/sun/launcher/SecuritySettings.java index e7ec70afcc3b3..2a73d0d1df8c1 100644 --- a/src/java.base/share/classes/sun/launcher/SecuritySettings.java +++ b/src/java.base/share/classes/sun/launcher/SecuritySettings.java @@ -146,6 +146,16 @@ private static void printSecurityTLSConfig(boolean verbose) { ostream.println(THREEINDENT + s); } } + + ostream.println("\n" + TWOINDENT + "Enabled Signature Schemes:"); + String[] schemes = ssls.getSSLParameters().getSignatureSchemes(); + if (schemes == null) { + ostream.println(THREEINDENT + ""); + } else { + for (String s : schemes) { + ostream.println(THREEINDENT + s); + } + } } ostream.println(); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java b/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java index aacac465027c4..6d1834ad2b721 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java @@ -38,6 +38,7 @@ 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 @@ void setSSLParameters(SSLParameters params) { // 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 @@ SSLExtension[] getEnabledExtensions( 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, diff --git a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java index 85dde5b0dbb2d..d50a9a10b76d1 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java @@ -297,7 +297,7 @@ List getDefaultCipherSuites(boolean roleIsServer) { * Return whether a protocol list is the original default enabled * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols() */ - boolean isDefaultProtocolVesions(List protocols) { + boolean isDefaultProtocolVersions(List protocols) { return (protocols == getServerDefaultProtocolVersions()) || (protocols == getClientDefaultProtocolVersions()); } diff --git a/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java index daf9098c399c4..1b959f982b9ee 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java @@ -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 @@ public void setUseClientMode(boolean useClientMode) { * default ones. */ if (sslConfig.isClientMode != useClientMode) { - if (sslContext.isDefaultProtocolVesions( + if (sslContext.isDefaultProtocolVersions( sslConfig.enabledProtocols)) { sslConfig.enabledProtocols = sslContext.getDefaultProtocolVersions(!useClientMode); diff --git a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java index 043a0d84c6120..5a8f103082b14 100644 --- a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java +++ b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java @@ -34,7 +34,6 @@ 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 @@ private static List getSupportedAlgorithms( List activeProtocols, Set scopes) { List supported = new LinkedList<>(); + List schemesToCheck; - List 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 @@ static List getSupportedAlgorithms( "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 @@ static String[] getAlgorithmNames(Collection schemes) { return new String[0]; } - private static List namesOfAvailable( - String[] signatureSchemes) { - - if (signatureSchemes == null || signatureSchemes.length == 0) { - return Collections.emptyList(); - } - - List 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 @@ private Signature getSigner(PrivateKey privateKey) { 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); + } } diff --git a/src/java.base/share/classes/sun/security/ssl/TransportContext.java b/src/java.base/share/classes/sun/security/ssl/TransportContext.java index 49fd664e9ed16..9595dc8b3fd49 100644 --- a/src/java.base/share/classes/sun/security/ssl/TransportContext.java +++ b/src/java.base/share/classes/sun/security/ssl/TransportContext.java @@ -471,7 +471,7 @@ void setUseClientMode(boolean useClientMode) { * default ones. */ if (sslConfig.isClientMode != useClientMode) { - if (sslContext.isDefaultProtocolVesions( + if (sslContext.isDefaultProtocolVersions( sslConfig.enabledProtocols)) { sslConfig.enabledProtocols = sslContext.getDefaultProtocolVersions(!useClientMode); diff --git a/test/jdk/sun/security/ssl/SignatureScheme/DefaultSSLConfigSignatureSchemes.java b/test/jdk/sun/security/ssl/SignatureScheme/DefaultSSLConfigSignatureSchemes.java new file mode 100644 index 0000000000000..2be745595d85f --- /dev/null +++ b/test/jdk/sun/security/ssl/SignatureScheme/DefaultSSLConfigSignatureSchemes.java @@ -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 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); + } +} diff --git a/test/jdk/tools/launcher/Settings.java b/test/jdk/tools/launcher/Settings.java index d441d69084c73..4df08edc7edba 100644 --- a/test/jdk/tools/launcher/Settings.java +++ b/test/jdk/tools/launcher/Settings.java @@ -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 @@ /* * @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 @@ static void checkNotContains(TestResult tr, String str) { 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 @@ static void containsAllOptions(TestResult tr) { 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 @@ static void runTestOptionSecurityTLS() throws IOException { // 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