--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java Tue Dec 22 21:32:29 2015 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java Wed Dec 23 03:51:35 2015 +0000
@@ -77,12 +77,6 @@
// minimum priority for default enabled CipherSuites
static final int DEFAULT_SUITES_PRIORITY = 300;
- // Flag indicating if CipherSuite availability can change dynamically.
- // This is the case when we rely on a JCE cipher implementation that
- // may not be available in the installed JCE providers.
- // It is true because we might not have an ECC implementation.
- static final boolean DYNAMIC_AVAILABILITY = true;
-
private static final boolean ALLOW_ECC = Debug.getBooleanProperty
("com.sun.net.ssl.enableECC", true);
@@ -176,9 +170,6 @@
* Return whether this CipherSuite is available for use. A
* CipherSuite may be unavailable even if it is supported
* (i.e. allowed == true) if the required JCE cipher is not installed.
- * In some configuration, this situation may change over time, call
- * CipherSuiteList.clearAvailableCache() before this method to obtain
- * the most current status.
*/
boolean isAvailable() {
return allowed && keyExchange.isAvailable() && cipher.isAvailable();
@@ -471,10 +462,6 @@
B_AES_128_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 16, 12, 4, true),
B_AES_256_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 32, 12, 4, true);
- // Map BulkCipher -> Boolean(available)
- private static final Map<BulkCipher,Boolean> availableCache =
- new HashMap<>(8);
-
// descriptive name including key size, e.g. AES/128
final String description;
@@ -518,6 +505,9 @@
// The secure random used to detect the cipher availability.
private static final SecureRandom secureRandom;
+ // runtime availability
+ private final boolean isAvailable;
+
static {
try {
secureRandom = JsseJce.getSecureRandom();
@@ -542,6 +532,17 @@
this.expandedKeySize = expandedKeySize;
this.exportable = true;
+
+ // 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;
}
BulkCipher(String transformation, CipherType cipherType, int keySize,
@@ -558,6 +559,17 @@
this.expandedKeySize = keySize;
this.exportable = false;
+
+ // 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;
}
/**
@@ -575,84 +587,27 @@
/**
* Test if this bulk cipher is available. For use by CipherSuite.
- *
- * 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, and AEAD is unavailable when the underlying providers
- * do not support AEAD/GCM mode.
*/
boolean isAvailable() {
- if (allowed == false) {
- return false;
- }
-
- if ((this == B_AES_256) ||
- (this.cipherType == CipherType.AEAD_CIPHER)) {
- return isAvailable(this);
- }
-
- // always available
- return true;
- }
-
- // for use by CipherSuiteList.clearAvailableCache();
- static synchronized void clearAvailableCache() {
- if (DYNAMIC_AVAILABILITY) {
- availableCache.clear();
- }
+ return this.isAvailable;
}
- private static synchronized boolean isAvailable(BulkCipher cipher) {
- Boolean b = availableCache.get(cipher);
- if (b == null) {
- int keySizeInBits = cipher.keySize * 8;
- if (keySizeInBits > 128) { // need the JCE unlimited
- // strength jurisdiction policy
- try {
- if (Cipher.getMaxAllowedKeyLength(
- cipher.transformation) < keySizeInBits) {
- b = Boolean.FALSE;
- }
- } catch (Exception e) {
- b = Boolean.FALSE;
- }
- }
+ private static boolean isUnlimited(int keySize, String transformation) {
+ int keySizeInBits = keySize * 8;
+ if (keySizeInBits > 128) { // need the JCE unlimited
+ // strength jurisdiction policy
+ try {
+ if (Cipher.getMaxAllowedKeyLength(
+ transformation) < keySizeInBits) {
- if (b == null) {
- b = Boolean.FALSE; // may be reset to TRUE if
- // the cipher is available
- CipherBox temporary = null;
- try {
- SecretKey key = new SecretKeySpec(
- new byte[cipher.expandedKeySize],
- cipher.algorithm);
- IvParameterSpec iv;
- if (cipher.cipherType == CipherType.AEAD_CIPHER) {
- iv = new IvParameterSpec(
- new byte[cipher.fixedIvSize]);
- } else {
- iv = new IvParameterSpec(new byte[cipher.ivSize]);
- }
- temporary = cipher.newCipher(
- ProtocolVersion.DEFAULT_TLS,
- key, iv, secureRandom, true);
- b = temporary.isAvailable();
- } catch (NoSuchAlgorithmException e) {
- // not available
- } finally {
- if (temporary != null) {
- temporary.dispose();
- }
+ return false;
}
+ } catch (Exception e) {
+ return false;
}
-
- availableCache.put(cipher, b);
}
- return b.booleanValue();
+ return true;
}
@Override