--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Tue Dec 22 21:32:29 2015 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Wed Dec 23 03:51:35 2015 +0000
@@ -1105,41 +1105,6 @@
return fragLen;
}
-
- /*
- * Is this cipher available?
- *
- * This method can only be called by CipherSuite.BulkCipher.isAvailable()
- * to test the availability of a cipher suites. Please DON'T use it in
- * other places, otherwise, the behavior may be unexpected because we may
- * initialize AEAD cipher improperly in the method.
- */
- Boolean isAvailable() {
- // We won't know whether a cipher for a particular key size is
- // available until the cipher is successfully initialized.
- //
- // We do not initialize AEAD cipher in the constructor. Need to
- // initialize the cipher to ensure that the AEAD mode for a
- // particular key size is supported.
- if (cipherType == AEAD_CIPHER) {
- try {
- Authenticator authenticator =
- new Authenticator(protocolVersion);
- byte[] nonce = authenticator.sequenceNumber();
- byte[] iv = Arrays.copyOf(fixedIv,
- fixedIv.length + nonce.length);
- System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
- GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
-
- cipher.init(mode, key, spec, random);
- } catch (Exception e) {
- return Boolean.FALSE;
- }
- } // Otherwise, we have initialized the cipher in the constructor.
-
- return Boolean.TRUE;
- }
-
/**
* Sanity check the length of a fragment before decryption.
*
--- 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
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java Tue Dec 22 21:32:29 2015 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java Wed Dec 23 03:51:35 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,24 +74,12 @@
throw new IllegalArgumentException("CipherSuites may not be null");
}
cipherSuites = new ArrayList<CipherSuite>(names.length);
- // refresh available cache once if a CipherSuite is not available
- // (maybe new JCE providers have been installed)
- boolean refreshed = false;
for (int i = 0; i < names.length; i++) {
String suiteName = names[i];
CipherSuite suite = CipherSuite.valueOf(suiteName);
if (suite.isAvailable() == false) {
- if (refreshed == false) {
- // clear the cache so that the isAvailable() call below
- // does a full check
- clearAvailableCache();
- refreshed = true;
- }
- // still missing?
- if (suite.isAvailable() == false) {
- throw new IllegalArgumentException("Cannot support "
- + suiteName + " with currently installed providers");
- }
+ throw new IllegalArgumentException("Cannot support "
+ + suiteName + " with currently installed providers");
}
cipherSuites.add(suite);
}
@@ -195,16 +183,4 @@
}
s.putBytes16(suiteBytes);
}
-
- /**
- * Clear cache of available ciphersuites. If we support all ciphers
- * internally, there is no need to clear the cache and calling this
- * method has no effect.
- */
- static synchronized void clearAvailableCache() {
- if (CipherSuite.DYNAMIC_AVAILABILITY) {
- CipherSuite.BulkCipher.clearAvailableCache();
- JsseJce.clearEcAvailable();
- }
- }
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Tue Dec 22 21:32:29 2015 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java Wed Dec 23 03:51:35 2015 +0000
@@ -55,11 +55,6 @@
private static final ProviderList fipsProviderList;
- // Flag indicating whether EC crypto is available.
- // If null, then we have not checked yet.
- // If yes, then all the EC based crypto we need is available.
- private static Boolean ecAvailable;
-
// Flag indicating whether Kerberos crypto is available.
// If true, then all the Kerberos-based crypto we need is available.
private static final boolean kerberosAvailable;
@@ -180,24 +175,8 @@
// no instantiation of this class
}
- static synchronized boolean isEcAvailable() {
- if (ecAvailable == null) {
- try {
- JsseJce.getSignature(SIGNATURE_ECDSA);
- JsseJce.getSignature(SIGNATURE_RAWECDSA);
- JsseJce.getKeyAgreement("ECDH");
- JsseJce.getKeyFactory("EC");
- JsseJce.getKeyPairGenerator("EC");
- ecAvailable = true;
- } catch (Exception e) {
- ecAvailable = false;
- }
- }
- return ecAvailable;
- }
-
- static synchronized void clearEcAvailable() {
- ecAvailable = null;
+ static boolean isEcAvailable() {
+ return EcAvailability.isAvailable;
}
static boolean isKerberosAvailable() {
@@ -399,4 +378,27 @@
}
}
+
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static class EcAvailability {
+ // Is EC crypto available?
+ private final static boolean isAvailable;
+
+ static {
+ boolean mediator = true;
+ try {
+ JsseJce.getSignature(SIGNATURE_ECDSA);
+ JsseJce.getSignature(SIGNATURE_RAWECDSA);
+ JsseJce.getKeyAgreement("ECDH");
+ JsseJce.getKeyFactory("EC");
+ JsseJce.getKeyPairGenerator("EC");
+ } catch (Exception e) {
+ mediator = false;
+ }
+
+ isAvailable = mediator;
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Tue Dec 22 21:32:29 2015 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Wed Dec 23 03:51:35 2015 +0000
@@ -52,18 +52,8 @@
private X509TrustManager trustManager;
private SecureRandom secureRandom;
- // supported and default protocols
- private ProtocolList defaultServerProtocolList;
- private ProtocolList defaultClientProtocolList;
- private ProtocolList supportedProtocolList;
-
- // supported and default cipher suites
- private CipherSuiteList defaultServerCipherSuiteList;
- private CipherSuiteList defaultClientCipherSuiteList;
- private CipherSuiteList supportedCipherSuiteList;
-
// DTLS cookie exchange manager
- private HelloCookieManager helloCookieManager;
+ private volatile HelloCookieManager helloCookieManager;
private StatusResponseManager statusResponseManager;
@@ -117,6 +107,7 @@
if (debug != null && Debug.isOn("sslctx")) {
System.out.println("done seeding SecureRandom");
}
+
isInitialized = true;
}
@@ -242,13 +233,20 @@
return ephemeralKeyManager;
}
+ // Used for DTLS in server mode only, see ServerHandshaker.
HelloCookieManager getHelloCookieManager() {
if (!isInitialized) {
throw new IllegalStateException("SSLContext is not initialized");
}
- if (helloCookieManager == null) {
- helloCookieManager = getHelloCookieManager(secureRandom);
+ if (helloCookieManager != null) {
+ return helloCookieManager;
+ }
+
+ synchronized (this) {
+ if (helloCookieManager == null) {
+ helloCookieManager = getHelloCookieManager(secureRandom);
+ }
}
return helloCookieManager;
@@ -263,78 +261,34 @@
return statusResponseManager;
}
- abstract SSLParameters getDefaultServerSSLParams();
- abstract SSLParameters getDefaultClientSSLParams();
- abstract SSLParameters getSupportedSSLParams();
+ // Get supported ProtocolList.
+ abstract ProtocolList getSuportedProtocolList();
+
+ // Get default ProtocolList for server mode.
+ abstract ProtocolList getServerDefaultProtocolList();
+
+ // Get default ProtocolList for client mode.
+ abstract ProtocolList getClientDefaultProtocolList();
- // Get supported ProtocolList.
- ProtocolList getSuportedProtocolList() {
- if (supportedProtocolList == null) {
- supportedProtocolList =
- new ProtocolList(getSupportedSSLParams().getProtocols());
- }
+ // Get supported CipherSuiteList.
+ abstract CipherSuiteList getSupportedCipherSuiteList();
- return supportedProtocolList;
- }
+ // Get default CipherSuiteList for server mode.
+ abstract CipherSuiteList getServerDefaultCipherSuiteList();
+
+ // Get default CipherSuiteList for client mode.
+ abstract CipherSuiteList getClientDefaultCipherSuiteList();
// Get default ProtocolList.
ProtocolList getDefaultProtocolList(boolean roleIsServer) {
- if (roleIsServer) {
- if (defaultServerProtocolList == null) {
- defaultServerProtocolList = new ProtocolList(
- getDefaultServerSSLParams().getProtocols());
- }
-
- return defaultServerProtocolList;
- } else {
- if (defaultClientProtocolList == null) {
- defaultClientProtocolList = new ProtocolList(
- getDefaultClientSSLParams().getProtocols());
- }
-
- return defaultClientProtocolList;
- }
- }
-
- // Get supported CipherSuiteList.
- CipherSuiteList getSupportedCipherSuiteList() {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (supportedCipherSuiteList == null) {
- supportedCipherSuiteList = getApplicableCipherSuiteList(
- getSuportedProtocolList(), false);
- }
-
- return supportedCipherSuiteList;
- }
+ return roleIsServer ? getServerDefaultProtocolList()
+ : getClientDefaultProtocolList();
}
// Get default CipherSuiteList.
CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (roleIsServer) {
- if (defaultServerCipherSuiteList == null) {
- defaultServerCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(true), true);
- }
-
- return defaultServerCipherSuiteList;
- } else {
- if (defaultClientCipherSuiteList == null) {
- defaultClientCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(false), true);
- }
-
- return defaultClientCipherSuiteList;
- }
- }
+ return roleIsServer ? getServerDefaultCipherSuiteList()
+ : getClientDefaultCipherSuiteList();
}
/**
@@ -342,8 +296,8 @@
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultProtocolList(ProtocolList protocols) {
- return (protocols == defaultServerProtocolList) ||
- (protocols == defaultClientProtocolList);
+ return (protocols == getServerDefaultProtocolList()) ||
+ (protocols == getClientDefaultProtocolList());
}
/**
@@ -351,8 +305,8 @@
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
- return (cipherSuites == defaultClientCipherSuiteList) ||
- (cipherSuites == defaultServerCipherSuiteList);
+ return (cipherSuites == getServerDefaultCipherSuiteList()) ||
+ (cipherSuites == getClientDefaultCipherSuiteList());
}
/*
@@ -405,24 +359,6 @@
return new CipherSuiteList(suites);
}
- /**
- * Clear cache of available ciphersuites. If we support all ciphers
- * internally, there is no need to clear the cache and calling this
- * method has no effect.
- *
- * Note that every call to clearAvailableCache() and the maintenance of
- * cipher suites need to be synchronized with this instance.
- */
- private void clearAvailableCache() {
- if (CipherSuite.DYNAMIC_AVAILABILITY) {
- supportedCipherSuiteList = null;
- defaultServerCipherSuiteList = null;
- defaultClientCipherSuiteList = null;
- CipherSuite.BulkCipher.clearAvailableCache();
- JsseJce.clearEcAvailable();
- }
- }
-
private static String[] getAvailableProtocols(
ProtocolVersion[] protocolCandidates) {
@@ -479,31 +415,28 @@
* @see SSLContext
*/
private abstract static class AbstractTLSContext extends SSLContextImpl {
- // parameters
- private static final SSLParameters defaultServerSSLParams;
- private static final SSLParameters supportedSSLParams;
+ private static final ProtocolList supportedProtocolList;
+ private static final ProtocolList serverDefaultProtocolList;
+
+ private static final CipherSuiteList supportedCipherSuiteList;
+ private static final CipherSuiteList serverDefaultCipherSuiteList;
static {
- // supported SSL parameters
- supportedSSLParams = new SSLParameters();
-
- // candidates for available protocols
- ProtocolVersion[] candidates;
-
if (SunJSSE.isFIPS()) {
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.TLS10.name,
ProtocolVersion.TLS11.name,
ProtocolVersion.TLS12.name
});
- candidates = new ProtocolVersion[] {
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
} else {
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.SSL20Hello.name,
ProtocolVersion.SSL30.name,
ProtocolVersion.TLS10.name,
@@ -511,28 +444,40 @@
ProtocolVersion.TLS12.name
});
- candidates = new ProtocolVersion[] {
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL20Hello,
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
}
- defaultServerSSLParams = new SSLParameters();
- defaultServerSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ supportedCipherSuiteList = getApplicableCipherSuiteList(
+ supportedProtocolList, false); // all supported
+ serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ serverDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultServerSSLParams() {
- return defaultServerSSLParams;
+ ProtocolList getSuportedProtocolList() {
+ return supportedProtocolList;
}
@Override
- SSLParameters getSupportedSSLParams() {
- return supportedSSLParams;
+ CipherSuiteList getSupportedCipherSuiteList() {
+ return supportedCipherSuiteList;
+ }
+
+ @Override
+ ProtocolList getServerDefaultProtocolList() {
+ return serverDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getServerDefaultCipherSuiteList() {
+ return serverDefaultCipherSuiteList;
}
@Override
@@ -552,30 +497,35 @@
* @see SSLContext
*/
public static final class TLS10Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -585,32 +535,37 @@
* @see SSLContext
*/
public static final class TLS11Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -620,34 +575,39 @@
* @see SSLContext
*/
public static final class TLS12Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -719,7 +679,9 @@
*/
private static class CustomizedTLSContext extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
+
private static IllegalArgumentException reservedException = null;
// Don't want a java.lang.LinkageError for illegal system property.
@@ -766,11 +728,13 @@
candidates = customizedTLSProtocols.toArray(candidates);
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
+ clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
} else {
- defaultClientSSLParams = null; // unlikely to be used
+ clientDefaultProtocolList = null; // unlikely to be used
+ clientDefaultCipherSuiteList = null; // unlikely to be used
}
}
@@ -781,8 +745,13 @@
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -795,71 +764,53 @@
// use the default constructor and methods
}
- /*
- * The SSLContext implementation for default "Default" algorithm
- *
- * @see SSLContext
- */
- public static final class DefaultSSLContext extends CustomizedTLSContext {
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static final class DefaultManagersHolder {
private static final String NONE = "NONE";
private static final String P11KEYSTORE = "PKCS11";
- private static volatile SSLContextImpl defaultImpl;
+ private static final TrustManager[] trustManagers;
+ private static final KeyManager[] keyManagers;
- private static TrustManager[] defaultTrustManagers;
- private static KeyManager[] defaultKeyManagers;
+ static Exception reservedException = null;
- public DefaultSSLContext() throws Exception {
+ static {
+ TrustManager[] tmMediator;
try {
- super.engineInit(getDefaultKeyManager(),
- getDefaultTrustManager(), null);
+ tmMediator = getTrustManagers();
} catch (Exception e) {
- if (debug != null && Debug.isOn("defaultctx")) {
- System.out.println("default context init failed: " + e);
+ reservedException = e;
+ tmMediator = new TrustManager[0];
+ }
+ trustManagers = tmMediator;
+
+ if (reservedException == null) {
+ KeyManager[] kmMediator;
+ try {
+ kmMediator = getKeyManagers();
+ } catch (Exception e) {
+ reservedException = e;
+ kmMediator = new KeyManager[0];
}
- throw e;
- }
-
- if (defaultImpl == null) {
- defaultImpl = this;
+ keyManagers = kmMediator;
+ } else {
+ keyManagers = new KeyManager[0];
}
}
- @Override
- protected void engineInit(KeyManager[] km, TrustManager[] tm,
- SecureRandom sr) throws KeyManagementException {
- throw new KeyManagementException
- ("Default SSLContext is initialized automatically");
- }
-
- static synchronized SSLContextImpl getDefaultImpl() throws Exception {
- if (defaultImpl == null) {
- new DefaultSSLContext();
- }
- return defaultImpl;
- }
-
- private static synchronized TrustManager[] getDefaultTrustManager()
- throws Exception {
- if (defaultTrustManagers != null) {
- return defaultTrustManagers;
- }
-
+ private static TrustManager[] getTrustManagers() throws Exception {
KeyStore ks =
TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
- defaultTrustManagers = tmf.getTrustManagers();
- return defaultTrustManagers;
+ return tmf.getTrustManagers();
}
- private static synchronized KeyManager[] getDefaultKeyManager()
- throws Exception {
- if (defaultKeyManagers != null) {
- return defaultKeyManagers;
- }
+ private static KeyManager[] getKeyManagers() throws Exception {
final Map<String,String> props = new HashMap<>();
AccessController.doPrivileged(
@@ -956,8 +907,71 @@
kmf.init(ks, passwd);
}
- defaultKeyManagers = kmf.getKeyManagers();
- return defaultKeyManagers;
+ return kmf.getKeyManagers();
+ }
+ }
+
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static final class DefaultSSLContextHolder {
+
+ private static final SSLContextImpl sslContext;
+ static Exception reservedException = null;
+
+ static {
+ SSLContextImpl mediator = null;
+ if (DefaultManagersHolder.reservedException != null) {
+ reservedException = DefaultManagersHolder.reservedException;
+ } else {
+ try {
+ mediator = new DefaultSSLContext();
+ } catch (Exception e) {
+ reservedException = e;
+ }
+ }
+
+ sslContext = mediator;
+ }
+ }
+
+ /*
+ * The SSLContext implementation for default "Default" algorithm
+ *
+ * @see SSLContext
+ */
+ public static final class DefaultSSLContext extends CustomizedTLSContext {
+
+ // public constructor for SSLContext.getInstance("Default")
+ public DefaultSSLContext() throws Exception {
+ if (DefaultManagersHolder.reservedException != null) {
+ throw DefaultManagersHolder.reservedException;
+ }
+
+ try {
+ super.engineInit(DefaultManagersHolder.keyManagers,
+ DefaultManagersHolder.trustManagers, null);
+ } catch (Exception e) {
+ if (debug != null && Debug.isOn("defaultctx")) {
+ System.out.println("default context init failed: " + e);
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ protected void engineInit(KeyManager[] km, TrustManager[] tm,
+ SecureRandom sr) throws KeyManagementException {
+ throw new KeyManagementException
+ ("Default SSLContext is initialized automatically");
+ }
+
+ static SSLContextImpl getDefaultImpl() throws Exception {
+ if (DefaultSSLContextHolder.reservedException != null) {
+ throw DefaultSSLContextHolder.reservedException;
+ }
+
+ return DefaultSSLContextHolder.sslContext;
}
}
@@ -971,39 +985,50 @@
* @see SSLContext
*/
private abstract static class AbstractDTLSContext extends SSLContextImpl {
- // parameters
- private static final SSLParameters defaultServerSSLParams;
- private static final SSLParameters supportedSSLParams;
+ private static final ProtocolList supportedProtocolList;
+ private static final ProtocolList serverDefaultProtocolList;
+
+ private static final CipherSuiteList supportedCipherSuiteList;
+ private static final CipherSuiteList serverDefaultCipherSuiteList;
static {
- // supported SSL parameters
- supportedSSLParams = new SSLParameters();
-
// Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.DTLS10.name,
ProtocolVersion.DTLS12.name
});
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for server mode
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10,
ProtocolVersion.DTLS12
- };
+ }));
- defaultServerSSLParams = new SSLParameters();
- defaultServerSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ supportedCipherSuiteList = getApplicableCipherSuiteList(
+ supportedProtocolList, false); // all supported
+ serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ serverDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultServerSSLParams() {
- return defaultServerSSLParams;
+ ProtocolList getSuportedProtocolList() {
+ return supportedProtocolList;
}
@Override
- SSLParameters getSupportedSSLParams() {
- return supportedSSLParams;
+ CipherSuiteList getSupportedCipherSuiteList() {
+ return supportedCipherSuiteList;
+ }
+
+ @Override
+ ProtocolList getServerDefaultProtocolList() {
+ return serverDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getServerDefaultCipherSuiteList() {
+ return serverDefaultCipherSuiteList;
}
@Override
@@ -1028,22 +1053,28 @@
* @see SSLContext
*/
public static final class DTLS10Context extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for client mode
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10
- };
+ }));
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -1053,23 +1084,29 @@
* @see SSLContext
*/
public static final class DTLS12Context extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for client mode
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10,
ProtocolVersion.DTLS12
- };
+ }));
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -1079,7 +1116,9 @@
* @see SSLContext
*/
private static class CustomizedDTLSContext extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
+
private static IllegalArgumentException reservedException = null;
// Don't want a java.lang.LinkageError for illegal system property.
@@ -1119,11 +1158,13 @@
candidates = customizedDTLSProtocols.toArray(candidates);
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
+ clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
} else {
- defaultClientSSLParams = null; // unlikely to be used
+ clientDefaultProtocolList = null; // unlikely to be used
+ clientDefaultCipherSuiteList = null; // unlikely to be used
}
}
@@ -1134,8 +1175,13 @@
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}