8223482: Unsupported ciphersuites may be offered by a TLS client
Reviewed-by: xuelei, andrew
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java
index 338c4ac..13917d2 100644
--- a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java
+++ b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java
@@ -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;
@@ -465,16 +466,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 {
+ JsseJce.getCipher(transformation);
+ return true;
+ } catch (NoSuchAlgorithmException 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,
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 6302fc1..7dd7bfa6 100644
--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
+++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
@@ -387,7 +387,8 @@
boolean isSupported = false;
for (ProtocolVersion protocol : protocols) {
- if (!suite.supports(protocol)) {
+ if (!suite.supports(protocol) ||
+ !suite.bulkCipher.isAvailable()) {
continue;
}
diff --git a/test/jdk/sun/security/pkcs11/fips/TestTLS12.java b/test/jdk/sun/security/pkcs11/fips/TestTLS12.java
index 73f9fb1..47655d8 100644
--- a/test/jdk/sun/security/pkcs11/fips/TestTLS12.java
+++ b/test/jdk/sun/security/pkcs11/fips/TestTLS12.java
@@ -376,15 +376,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;