8223482: Unsupported ciphersuites may be offered by a TLS client
authormbalao
Tue, 28 May 2019 19:01:38 -0300
changeset 55072 d0f73fccf5f3
parent 55071 4e62485d2b18
child 55073 f4702c8c9b3f
8223482: Unsupported ciphersuites may be offered by a TLS client Reviewed-by: xuelei
src/java.base/share/classes/sun/security/ssl/SSLCipher.java
src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java
--- a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java	Wed May 29 07:49:06 2019 +0530
+++ b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java	Tue May 28 19:01:38 2019 -0300
@@ -31,6 +31,7 @@
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.Key;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivilegedAction;
 import java.security.SecureRandom;
 import java.security.Security;
@@ -42,6 +43,7 @@
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
 import javax.crypto.SecretKey;
 import javax.crypto.ShortBufferException;
 import javax.crypto.spec.GCMParameterSpec;
@@ -491,16 +493,31 @@
 
         // availability of this bulk cipher
         //
-        // We assume all supported ciphers are always available since they are
-        // shipped with the SunJCE  provider.  However, AES/256 is unavailable
-        // when the default JCE policy jurisdiction files are installed because
-        // of key length restrictions.
-        this.isAvailable = allowed && isUnlimited(keySize, transformation);
+        // AES/256 is unavailable when the default JCE policy jurisdiction files
+        // are installed because of key length restrictions.
+        this.isAvailable = allowed && isUnlimited(keySize, transformation) &&
+                isTransformationAvailable(transformation);
 
         this.readCipherGenerators = readCipherGenerators;
         this.writeCipherGenerators = writeCipherGenerators;
     }
 
+    private static boolean isTransformationAvailable(String transformation) {
+        if (transformation.equals("NULL")) {
+            return true;
+        }
+        try {
+            Cipher.getInstance(transformation);
+            return true;
+        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+            if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
+                SSLLogger.fine("Transformation " + transformation + " is" +
+                        " not available.");
+            }
+        }
+        return false;
+    }
+
     SSLReadCipher createReadCipher(Authenticator authenticator,
             ProtocolVersion protocolVersion,
             SecretKey key, IvParameterSpec iv,
--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Wed May 29 07:49:06 2019 +0530
+++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Tue May 28 19:01:38 2019 -0300
@@ -379,7 +379,8 @@
 
                 boolean isSupported = false;
                 for (ProtocolVersion protocol : protocols) {
-                    if (!suite.supports(protocol)) {
+                    if (!suite.supports(protocol) ||
+                            !suite.bulkCipher.isAvailable()) {
                         continue;
                     }
 
--- a/test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java	Wed May 29 07:49:06 2019 +0530
+++ b/test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java	Tue May 28 19:01:38 2019 -0300
@@ -379,15 +379,20 @@
 
         private static SSLEngine[][] getSSLEnginesToTest() throws Exception {
             SSLEngine[][] enginesToTest = new SSLEngine[2][2];
+            // TLS_RSA_WITH_AES_128_GCM_SHA256 ciphersuite is available but
+            // must not be chosen for the TLS connection if not supported.
+            // See JDK-8222937.
             String[][] preferredSuites = new String[][]{ new String[] {
+                    "TLS_RSA_WITH_AES_128_GCM_SHA256",
                     "TLS_RSA_WITH_AES_128_CBC_SHA256"
             },  new String[] {
+                    "TLS_RSA_WITH_AES_128_GCM_SHA256",
                     "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"
             }};
             for (int i = 0; i < enginesToTest.length; i++) {
                 enginesToTest[i][0] = createSSLEngine(true);
                 enginesToTest[i][1] = createSSLEngine(false);
-                enginesToTest[i][0].setEnabledCipherSuites(preferredSuites[i]);
+                // All CipherSuites enabled for the client.
                 enginesToTest[i][1].setEnabledCipherSuites(preferredSuites[i]);
             }
             return enginesToTest;
@@ -459,13 +464,10 @@
         Security.addProvider(sunPKCS11NSSProvider);
         for (Provider p : installedProviders){
             String providerName = p.getName();
-            if (providerName.equals("SunJSSE") ||
-                    providerName.equals("SUN") ||
-                    providerName.equals("SunJCE")) {
+            if (providerName.equals("SunJSSE") || providerName.equals("SUN")) {
                 Security.addProvider(p);
-                if (providerName.equals("SunJCE")) {
-                    sunJCEProvider = p;
-                }
+            } else if (providerName.equals("SunJCE")) {
+                sunJCEProvider = p;
             }
         }