Blob Blame History Raw
# HG changeset patch
# User mbalao
# Date 1559080898 10800
#      Tue May 28 19:01:38 2019 -0300
# Node ID 3ba9c532128b1feccf59ab8ce812b1fce2b6f681
# Parent  056a435ab5447c33aab61dd9179a67781e99c35d
8223482: Unsupported ciphersuites may be offered by a TLS client
Reviewed-by: andrew

diff --git openjdk.orig/jdk/src/share/classes/sun/security/ssl/CipherSuite.java openjdk/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
--- openjdk.orig/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
+++ openjdk/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
@@ -34,6 +34,7 @@
 import java.security.KeyManagementException;
 
 import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
@@ -69,6 +70,8 @@
  */
 final class CipherSuite implements Comparable<CipherSuite> {
 
+    private static final Debug debug = Debug.getInstance("ssl");
+
     // minimum priority for supported CipherSuites
     final static int SUPPORTED_SUITES_PRIORITY = 1;
 
@@ -451,6 +454,22 @@
             }
         }
 
+        private static boolean isTransformationAvailable(String transformation) {
+            if (transformation.equals("NULL")) {
+                return true;
+            }
+            try {
+                Cipher.getInstance(transformation);
+                return true;
+            } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+                if (debug != null && Debug.isOn("ssl")) {
+                    System.out.println("Transformation " + transformation + " is" +
+                            " not available.");
+                }
+            }
+            return false;
+        }
+
         BulkCipher(String transformation, CipherType cipherType, int keySize,
                 int expandedKeySize, int ivSize,
                 int fixedIvSize, boolean allowed) {
@@ -470,14 +489,10 @@
 
             // availability of this bulk cipher
             //
-            // Currently all supported ciphers except AES are always available
-            // via the JSSE internal implementations. We also assume AES/128 of
-            // CBC mode is always available since it is 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) : false;
+            // 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);
         }
 
         BulkCipher(String transformation, CipherType cipherType, int keySize,
@@ -497,14 +512,11 @@
 
             // availability of this bulk cipher
             //
-            // Currently all supported ciphers except AES are always available
-            // via the JSSE internal implementations. We also assume AES/128 of
-            // CBC mode is always available since it is shipped with the SunJCE
-            // provider.  However, AES/256 is unavailable when the default JCE
-            // policy jurisdiction files are installed because of key length
-            // restrictions.
+            // AES/256 is unavailable when the default JCE policy jurisdiction files
+            // are installed because of key length restrictions.
             this.isAvailable =
-                    allowed ? isUnlimited(keySize, transformation) : false;
+                    allowed ? isUnlimited(keySize, transformation) &&
+                            isTransformationAvailable(transformation) : false;
         }
 
         /**
diff --git openjdk.orig/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java openjdk/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java
--- openjdk.orig/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java
+++ openjdk/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java
@@ -339,7 +339,8 @@
 
                 if (suite.isAvailable() &&
                         suite.obsoleted > protocols.min.v &&
-                        suite.supported <= protocols.max.v) {
+                        suite.supported <= protocols.max.v &&
+                        suite.cipher.isAvailable()) {
                     if (SSLAlgorithmConstraints.DEFAULT.permits(
                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
                             suite.name, null)) {
diff --git openjdk.orig/jdk/test/sun/security/pkcs11/fips/TestTLS12.java openjdk/jdk/test/sun/security/pkcs11/fips/TestTLS12.java
--- openjdk.orig/jdk/test/sun/security/pkcs11/fips/TestTLS12.java
+++ openjdk/jdk/test/sun/security/pkcs11/fips/TestTLS12.java
@@ -372,15 +372,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;