src/java.base/share/classes/sun/security/ssl/SignatureScheme.java
changeset 57718 a93b7b28f644
parent 55452 1170b6d92d1c
child 58679 9c3209ff7550
child 58951 d6e682e8fcc3
--- a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java	Mon Aug 12 23:37:48 2019 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java	Mon Aug 12 21:36:29 2019 -0700
@@ -38,7 +38,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
-import sun.security.ssl.NamedGroup.NamedGroupType;
+import sun.security.ssl.NamedGroup.NamedGroupSpec;
 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
 import sun.security.ssl.X509Authentication.X509Possession;
 import sun.security.util.KeyUtil;
@@ -149,7 +149,7 @@
     final String name;                  // literal name
     private final String algorithm;     // signature algorithm
     final String keyAlgorithm;          // signature key algorithm
-    private final AlgorithmParameterSpec signAlgParameter;
+    private final SigAlgParamSpec signAlgParams;    // signature parameters
     private final NamedGroup namedGroup;    // associated named group
 
     // The minimal required key size in bits.
@@ -184,21 +184,25 @@
         RSA_PSS_SHA384 ("SHA-384", 48),
         RSA_PSS_SHA512 ("SHA-512", 64);
 
-        final private AlgorithmParameterSpec parameterSpec;
-        final boolean isAvailable;
+        private final AlgorithmParameterSpec parameterSpec;
+        private final AlgorithmParameters parameters;
+        private final boolean isAvailable;
 
         SigAlgParamSpec(String hash, int saltLength) {
             // See RFC 8017
             PSSParameterSpec pssParamSpec =
                     new PSSParameterSpec(hash, "MGF1",
                             new MGF1ParameterSpec(hash), saltLength, 1);
+            AlgorithmParameters pssParams = null;
 
             boolean mediator = true;
             try {
                 Signature signer = Signature.getInstance("RSASSA-PSS");
                 signer.setParameter(pssParamSpec);
+                pssParams = signer.getParameters();
             } catch (InvalidAlgorithmParameterException |
-                    NoSuchAlgorithmException exp) {
+                    NoSuchAlgorithmException | RuntimeException exp) {
+                // Signature.getParameters() may throw RuntimeException.
                 mediator = false;
                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
                     SSLLogger.warning(
@@ -209,10 +213,7 @@
 
             this.isAvailable = mediator;
             this.parameterSpec = mediator ? pssParamSpec : null;
-        }
-
-        AlgorithmParameterSpec getParameterSpec() {
-            return parameterSpec;
+            this.parameters = mediator ? pssParams : null;
         }
     }
 
@@ -255,7 +256,7 @@
 
     private SignatureScheme(int id, String name,
             String algorithm, String keyAlgorithm,
-            SigAlgParamSpec signAlgParamSpec,
+            SigAlgParamSpec signAlgParams,
             NamedGroup namedGroup, int minimalKeySize,
             ProtocolVersion[] supportedProtocols,
             ProtocolVersion[] handshakeSupportedProtocols) {
@@ -263,8 +264,7 @@
         this.name = name;
         this.algorithm = algorithm;
         this.keyAlgorithm = keyAlgorithm;
-        this.signAlgParameter =
-            signAlgParamSpec != null ? signAlgParamSpec.parameterSpec : null;
+        this.signAlgParams = signAlgParams;
         this.namedGroup = namedGroup;
         this.minimalKeySize = minimalKeySize;
         this.supportedProtocols = Arrays.asList(supportedProtocols);
@@ -272,8 +272,8 @@
                 Arrays.asList(handshakeSupportedProtocols);
 
         boolean mediator = true;
-        if (signAlgParamSpec != null) {
-            mediator = signAlgParamSpec.isAvailable;
+        if (signAlgParams != null) {
+            mediator = signAlgParams.isAvailable;
         } else {
             try {
                 Signature.getInstance(algorithm);
@@ -331,6 +331,18 @@
         return 2;
     }
 
+    private boolean isPermitted(AlgorithmConstraints constraints) {
+        return constraints.permits(SIGNATURE_PRIMITIVE_SET,
+                        this.name, null) &&
+               constraints.permits(SIGNATURE_PRIMITIVE_SET,
+                        this.keyAlgorithm, null) &&
+               constraints.permits(SIGNATURE_PRIMITIVE_SET,
+                        this.algorithm, (signAlgParams != null ?
+                                signAlgParams.parameters : null)) &&
+               (namedGroup != null ?
+                        namedGroup.isPermitted(constraints) : true);
+    }
+
     // Get local supported algorithm collection complying to algorithm
     // constraints.
     static List<SignatureScheme> getSupportedAlgorithms(
@@ -351,8 +363,7 @@
             }
 
             if (isMatch) {
-                if (constraints.permits(
-                        SIGNATURE_PRIMITIVE_SET, ss.algorithm, null)) {
+                if (ss.isPermitted(constraints)) {
                     supported.add(ss);
                 } else if (SSLLogger.isOn &&
                         SSLLogger.isOn("ssl,handshake,verbose")) {
@@ -383,8 +394,7 @@
                 }
             } else if (ss.isAvailable &&
                     ss.supportedProtocols.contains(protocolVersion) &&
-                    constraints.permits(SIGNATURE_PRIMITIVE_SET,
-                           ss.algorithm, null)) {
+                    ss.isPermitted(constraints)) {
                 supported.add(ss);
             } else {
                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -398,6 +408,7 @@
     }
 
     static SignatureScheme getPreferableAlgorithm(
+            AlgorithmConstraints constraints,
             List<SignatureScheme> schemes,
             SignatureScheme certScheme,
             ProtocolVersion version) {
@@ -405,8 +416,8 @@
         for (SignatureScheme ss : schemes) {
             if (ss.isAvailable &&
                     ss.handshakeSupportedProtocols.contains(version) &&
-                    certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
-
+                    certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm) &&
+                    ss.isPermitted(constraints)) {
                 return ss;
             }
         }
@@ -415,6 +426,7 @@
     }
 
     static SignatureScheme getPreferableAlgorithm(
+            AlgorithmConstraints constraints,
             List<SignatureScheme> schemes,
             X509Possession x509Possession,
             ProtocolVersion version) {
@@ -432,9 +444,10 @@
         for (SignatureScheme ss : schemes) {
             if (ss.isAvailable && (keySize >= ss.minimalKeySize) &&
                     ss.handshakeSupportedProtocols.contains(version) &&
-                    keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
-                if ((ss.namedGroup != null) && (ss.namedGroup.type ==
-                        NamedGroupType.NAMED_GROUP_ECDHE)) {
+                    keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm) &&
+                    ss.isPermitted(constraints)) {
+                if ((ss.namedGroup != null) && (ss.namedGroup.spec ==
+                        NamedGroupSpec.NAMED_GROUP_ECDHE)) {
                     ECParameterSpec params =
                             x509Possession.getECParameterSpec();
                     if (params != null &&
@@ -505,10 +518,13 @@
         Signature signer = Signature.getInstance(algorithm);
         if (key instanceof PublicKey) {
             SignatureUtil.initVerifyWithParam(signer, (PublicKey)key,
-                    signAlgParameter);
+                    (signAlgParams != null ?
+                            signAlgParams.parameterSpec : null));
         } else {
             SignatureUtil.initSignWithParam(signer, (PrivateKey)key,
-                    signAlgParameter, null);
+                    (signAlgParams != null ?
+                            signAlgParams.parameterSpec : null),
+                    null);
         }
 
         return signer;