changeset 14922:bfadd8e82337

8242141: New System Properties to configure the TLS signature schemes Reviewed-by: ascarpino, jnimeh, mullan, andrew
author xuelei
date Wed, 22 Apr 2020 10:51:16 -0700
parents 46d30306b027
children 941a82f69e91
files src/share/classes/sun/security/ssl/CertSignAlgsExtension.java src/share/classes/sun/security/ssl/CertificateRequest.java src/share/classes/sun/security/ssl/PreSharedKeyExtension.java src/share/classes/sun/security/ssl/SSLConfiguration.java src/share/classes/sun/security/ssl/SSLServerSocketImpl.java src/share/classes/sun/security/ssl/ServerHello.java src/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java src/share/classes/sun/security/ssl/SignatureScheme.java src/share/classes/sun/security/ssl/TransportContext.java test/sun/security/ssl/SignatureScheme/CustomizedClientSchemes.java test/sun/security/ssl/SignatureScheme/CustomizedServerSchemes.java
diffstat 11 files changed, 236 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/CertSignAlgsExtension.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/CertSignAlgsExtension.java	Wed Apr 22 10:51:16 2020 -0700
@@ -101,6 +101,7 @@
             if (chc.localSupportedSignAlgs == null) {
                 chc.localSupportedSignAlgs =
                     SignatureScheme.getSupportedAlgorithms(
+                            chc.sslConfig,
                             chc.algorithmConstraints, chc.activeProtocols);
             }
 
@@ -194,6 +195,7 @@
             // update the context
             List<SignatureScheme> schemes =
                     SignatureScheme.getSupportedAlgorithms(
+                            shc.sslConfig,
                             shc.algorithmConstraints, shc.negotiatedProtocol,
                             spec.signatureSchemes);
             shc.peerRequestedCertSignSchemes = schemes;
@@ -248,7 +250,9 @@
             protocols = Collections.unmodifiableList(protocols);
             List<SignatureScheme> sigAlgs =
                     SignatureScheme.getSupportedAlgorithms(
-                            shc.algorithmConstraints, protocols);
+                            shc.sslConfig,
+                            shc.algorithmConstraints,
+                            protocols);
 
             int vectorLen = SignatureScheme.sizeInRecord() * sigAlgs.size();
             byte[] extData = new byte[vectorLen + 2];
@@ -338,6 +342,7 @@
             // update the context
             List<SignatureScheme> schemes =
                     SignatureScheme.getSupportedAlgorithms(
+                            chc.sslConfig,
                             chc.algorithmConstraints, chc.negotiatedProtocol,
                             spec.signatureSchemes);
             chc.peerRequestedCertSignSchemes = schemes;
--- a/src/share/classes/sun/security/ssl/CertificateRequest.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/CertificateRequest.java	Wed Apr 22 10:51:16 2020 -0700
@@ -601,6 +601,7 @@
             if (shc.localSupportedSignAlgs == null) {
                 shc.localSupportedSignAlgs =
                     SignatureScheme.getSupportedAlgorithms(
+                            shc.sslConfig,
                             shc.algorithmConstraints, shc.activeProtocols);
             }
 
--- a/src/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Wed Apr 22 10:51:16 2020 -0700
@@ -420,6 +420,7 @@
         if (shc.localSupportedSignAlgs == null) {
             shc.localSupportedSignAlgs =
                     SignatureScheme.getSupportedAlgorithms(
+                            shc.sslConfig,
                             shc.algorithmConstraints, shc.activeProtocols);
         }
 
--- a/src/share/classes/sun/security/ssl/SSLConfiguration.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/SSLConfiguration.java	Wed Apr 22 10:51:16 2020 -0700
@@ -45,6 +45,7 @@
 import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLSocket;
 import sun.security.action.GetIntegerAction;
+import sun.security.action.GetPropertyAction;
 import sun.security.ssl.SSLExtension.ClientExtensions;
 import sun.security.ssl.SSLExtension.ServerExtensions;
 
@@ -64,6 +65,10 @@
     boolean                     preferLocalCipherSuites;
     int                         maximumPacketSize = 0;
 
+    // The configured signature schemes for "signature_algorithms" and
+    // "signature_algorithms_cert" extensions
+    List<SignatureScheme>       signatureSchemes;
+
     // the maximum protocol version of enabled protocols
     ProtocolVersion             maximumProtocolVersion;
 
@@ -140,6 +145,9 @@
 
         this.applicationProtocols = new String[0];
 
+        this.signatureSchemes = isClientMode ?
+                CustomizedClientSignatureSchemes.signatureSchemes :
+                CustomizedServerSignatureSchemes.signatureSchemes;
         this.maximumProtocolVersion = ProtocolVersion.NONE;
         for (ProtocolVersion pv : enabledProtocols) {
             if (pv.compareTo(maximumProtocolVersion) > 0) {
@@ -386,6 +394,15 @@
         return extensions.toArray(new SSLExtension[0]);
     }
 
+    void toggleClientMode() {
+        this.isClientMode ^= true;
+
+        // reset the signature schemes
+        this.signatureSchemes = isClientMode ?
+                CustomizedClientSignatureSchemes.signatureSchemes :
+                CustomizedServerSignatureSchemes.signatureSchemes;
+    }
+
     @Override
     @SuppressWarnings({"unchecked", "CloneDeclaresCloneNotSupported"})
     public Object clone() {
@@ -405,4 +422,72 @@
 
         return null;    // unlikely
     }
+
+
+    // lazy initialization holder class idiom for static default parameters
+    //
+    // See Effective Java Second Edition: Item 71.
+    private static final class CustomizedClientSignatureSchemes {
+        private static List<SignatureScheme> signatureSchemes =
+                getCustomizedSignatureScheme("jdk.tls.client.SignatureSchemes");
+    }
+
+    // lazy initialization holder class idiom for static default parameters
+    //
+    // See Effective Java Second Edition: Item 71.
+    private static final class CustomizedServerSignatureSchemes {
+        private static List<SignatureScheme> signatureSchemes =
+                getCustomizedSignatureScheme("jdk.tls.server.SignatureSchemes");
+    }
+
+    /*
+     * Get the customized signature schemes specified by the given
+     * system property.
+     */
+    private static List<SignatureScheme> getCustomizedSignatureScheme(
+            String propertyName) {
+
+        String property = GetPropertyAction.privilegedGetProperty(propertyName);
+        if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+            SSLLogger.fine(
+                    "System property " + propertyName + " is set to '" +
+                    property + "'");
+        }
+        if (property != null && !property.isEmpty()) {
+            // remove double quote marks from beginning/end of the property
+            if (property.length() > 1 && property.charAt(0) == '"' &&
+                    property.charAt(property.length() - 1) == '"') {
+                property = property.substring(1, property.length() - 1);
+            }
+        }
+
+        if (property != null && !property.isEmpty()) {
+            String[] signatureSchemeNames = property.split(",");
+            List<SignatureScheme> signatureSchemes =
+                        new ArrayList<>(signatureSchemeNames.length);
+            for (int i = 0; i < signatureSchemeNames.length; i++) {
+                signatureSchemeNames[i] = signatureSchemeNames[i].trim();
+                if (signatureSchemeNames[i].isEmpty()) {
+                    continue;
+                }
+
+                SignatureScheme scheme =
+                    SignatureScheme.nameOf(signatureSchemeNames[i]);
+                if (scheme != null && scheme.isAvailable) {
+                    signatureSchemes.add(scheme);
+                } else {
+                    if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+                        SSLLogger.fine(
+                                "The current installed providers do not " +
+                                "support signature scheme: " +
+                                signatureSchemeNames[i]);
+                    }
+                }
+            }
+
+            return signatureSchemes;
+        }
+
+        return Collections.emptyList();
+    }
 }
--- a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Wed Apr 22 10:51:16 2020 -0700
@@ -62,7 +62,6 @@
         super();
         this.sslContext = sslContext;
         this.sslConfig = new SSLConfiguration(sslContext, false);
-        this.sslConfig.isClientMode = false;
     }
 
     SSLServerSocketImpl(SSLContextImpl sslContext,
@@ -71,7 +70,6 @@
         super(port, backlog);
         this.sslContext = sslContext;
         this.sslConfig = new SSLConfiguration(sslContext, false);
-        this.sslConfig.isClientMode = false;
     }
 
     SSLServerSocketImpl(SSLContextImpl sslContext,
@@ -80,7 +78,6 @@
         super(port, backlog, address);
         this.sslContext = sslContext;
         this.sslConfig = new SSLConfiguration(sslContext, false);
-        this.sslConfig.isClientMode = false;
     }
 
     @Override
@@ -166,7 +163,7 @@
                         sslContext.getDefaultCipherSuites(!useClientMode);
             }
 
-            sslConfig.isClientMode = useClientMode;
+            sslConfig.toggleClientMode();
         }
     }
 
--- a/src/share/classes/sun/security/ssl/ServerHello.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/ServerHello.java	Wed Apr 22 10:51:16 2020 -0700
@@ -276,6 +276,7 @@
                 if (shc.localSupportedSignAlgs == null) {
                     shc.localSupportedSignAlgs =
                         SignatureScheme.getSupportedAlgorithms(
+                                shc.sslConfig,
                                 shc.algorithmConstraints, shc.activeProtocols);
                 }
 
@@ -504,6 +505,7 @@
                 if (shc.localSupportedSignAlgs == null) {
                     shc.localSupportedSignAlgs =
                         SignatureScheme.getSupportedAlgorithms(
+                                shc.sslConfig,
                                 shc.algorithmConstraints, shc.activeProtocols);
                 }
 
--- a/src/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java	Wed Apr 22 10:51:16 2020 -0700
@@ -186,6 +186,7 @@
             if (chc.localSupportedSignAlgs == null) {
                 chc.localSupportedSignAlgs =
                     SignatureScheme.getSupportedAlgorithms(
+                            chc.sslConfig,
                             chc.algorithmConstraints, chc.activeProtocols);
             }
 
@@ -278,6 +279,7 @@
             // update the context
             List<SignatureScheme> sss =
                     SignatureScheme.getSupportedAlgorithms(
+                            shc.sslConfig,
                             shc.algorithmConstraints, shc.negotiatedProtocol,
                             spec.signatureSchemes);
             shc.peerRequestedSignatureSchemes = sss;
@@ -413,7 +415,9 @@
             protocols = Collections.unmodifiableList(protocols);
             List<SignatureScheme> sigAlgs =
                     SignatureScheme.getSupportedAlgorithms(
-                            shc.algorithmConstraints, protocols);
+                            shc.sslConfig,
+                            shc.algorithmConstraints,
+                            protocols);
 
             int vectorLen = SignatureScheme.sizeInRecord() * sigAlgs.size();
             byte[] extData = new byte[vectorLen + 2];
@@ -512,6 +516,7 @@
             // update the context
             List<SignatureScheme> sss =
                     SignatureScheme.getSupportedAlgorithms(
+                            chc.sslConfig,
                             chc.algorithmConstraints, chc.negotiatedProtocol,
                             spec.signatureSchemes);
             chc.peerRequestedSignatureSchemes = sss;
--- a/src/share/classes/sun/security/ssl/SignatureScheme.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/SignatureScheme.java	Wed Apr 22 10:51:16 2020 -0700
@@ -341,6 +341,17 @@
         return signName + "_" + hashName;
     }
 
+    // Note: the signatureSchemeName is not case-sensitive.
+    static SignatureScheme nameOf(String signatureSchemeName) {
+        for (SignatureScheme ss: SignatureScheme.values()) {
+            if (ss.name.equalsIgnoreCase(signatureSchemeName)) {
+                return ss;
+            }
+        }
+
+        return null;
+    }
+
     // Return the size of a SignatureScheme structure in TLS record
     static int sizeInRecord() {
         return 2;
@@ -349,11 +360,19 @@
     // Get local supported algorithm collection complying to algorithm
     // constraints.
     static List<SignatureScheme> getSupportedAlgorithms(
+            SSLConfiguration config,
             AlgorithmConstraints constraints,
             List<ProtocolVersion> activeProtocols) {
         List<SignatureScheme> supported = new LinkedList<>();
         for (SignatureScheme ss: SignatureScheme.values()) {
-            if (!ss.isAvailable) {
+            if (!ss.isAvailable ||
+                    (!config.signatureSchemes.isEmpty() &&
+                        !config.signatureSchemes.contains(ss))) {
+                if (SSLLogger.isOn &&
+                        SSLLogger.isOn("ssl,handshake,verbose")) {
+                    SSLLogger.finest(
+                        "Ignore unsupported signature scheme: " + ss.name);
+                }
                 continue;
             }
 
@@ -385,6 +404,7 @@
     }
 
     static List<SignatureScheme> getSupportedAlgorithms(
+            SSLConfiguration config,
             AlgorithmConstraints constraints,
             ProtocolVersion protocolVersion, int[] algorithmIds) {
         List<SignatureScheme> supported = new LinkedList<>();
@@ -398,6 +418,8 @@
                 }
             } else if (ss.isAvailable &&
                     ss.supportedProtocols.contains(protocolVersion) &&
+                    (config.signatureSchemes.isEmpty() ||
+                        config.signatureSchemes.contains(ss)) &&
                     constraints.permits(SIGNATURE_PRIMITIVE_SET,
                            ss.algorithm, null)) {
                 supported.add(ss);
--- a/src/share/classes/sun/security/ssl/TransportContext.java	Wed Jan 20 01:23:10 2021 +0000
+++ b/src/share/classes/sun/security/ssl/TransportContext.java	Wed Apr 22 10:51:16 2020 -0700
@@ -426,7 +426,7 @@
                         sslContext.getDefaultCipherSuites(!useClientMode);
             }
 
-            sslConfig.isClientMode = useClientMode;
+            sslConfig.toggleClientMode();
         }
 
         isUnsureMode = false;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/SignatureScheme/CustomizedClientSchemes.java	Wed Apr 22 10:51:16 2020 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8242141
+ * @summary New System Properties to configure the default signature schemes
+ * @library /javax/net/ssl/templates
+ * @run main/othervm CustomizedClientSchemes
+ */
+
+import javax.net.ssl.SSLException;
+
+public class CustomizedClientSchemes extends SSLSocketTemplate {
+
+    public static void main(String[] args) throws Exception {
+        System.setProperty("jdk.tls.client.SignatureSchemes", "rsa_pkcs1_sha1");
+
+        try {
+            new CustomizedClientSchemes().run();
+            throw new Exception(
+                "The jdk.tls.client.SignatureSchemes System Property " +
+                "does not work");
+        } catch (SSLException e) {
+            // Got the expected exception.
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/SignatureScheme/CustomizedServerSchemes.java	Wed Apr 22 10:51:16 2020 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8242141
+ * @summary New System Properties to configure the default signature schemes
+ * @library /javax/net/ssl/templates
+ * @run main/othervm CustomizedServerSchemes
+ */
+
+import javax.net.ssl.SSLException;
+
+public class CustomizedServerSchemes extends SSLSocketTemplate {
+
+    public static void main(String[] args) throws Exception {
+        System.setProperty("jdk.tls.server.SignatureSchemes", "rsa_pkcs1_sha1");
+
+        try {
+            new CustomizedServerSchemes().run();
+            throw new Exception(
+                "The jdk.tls.server.SignatureSchemes System Property " +
+                "does not work");
+        } catch (SSLException e) {
+            // Got the expected exception.
+        }
+    }
+}