META-INF.modules.java.base.classes.sun.security.ssl.SSLContextImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java.base Show documentation
Show all versions of java.base Show documentation
Bytecoder java.base Module
/*
* Copyright (c) 1999, 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.ssl;
import java.io.*;
import java.net.Socket;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import javax.net.ssl.*;
import sun.security.action.GetPropertyAction;
import sun.security.provider.certpath.AlgorithmChecker;
import sun.security.validator.Validator;
/**
* Implementation of an SSLContext.
*
* Implementation note: Instances of this class and the child classes are
* immutable, except that the context initialization (SSLContext.init()) may
* reset the key, trust managers and source of secure random.
*/
public abstract class SSLContextImpl extends SSLContextSpi {
private final EphemeralKeyManager ephemeralKeyManager;
private final SSLSessionContextImpl clientCache;
private final SSLSessionContextImpl serverCache;
private boolean isInitialized;
private X509ExtendedKeyManager keyManager;
private X509TrustManager trustManager;
private SecureRandom secureRandom;
// DTLS cookie exchange manager
private volatile HelloCookieManager.Builder helloCookieManagerBuilder;
private final boolean clientEnableStapling = Utilities.getBooleanProperty(
"jdk.tls.client.enableStatusRequestExtension", true);
private final boolean serverEnableStapling = Utilities.getBooleanProperty(
"jdk.tls.server.enableStatusRequestExtension", false);
private static final Collection clientCustomizedCipherSuites =
getCustomizedCipherSuites("jdk.tls.client.cipherSuites");
private static final Collection serverCustomizedCipherSuites =
getCustomizedCipherSuites("jdk.tls.server.cipherSuites");
private volatile StatusResponseManager statusResponseManager;
SSLContextImpl() {
ephemeralKeyManager = new EphemeralKeyManager();
clientCache = new SSLSessionContextImpl();
serverCache = new SSLSessionContextImpl();
}
@Override
protected void engineInit(KeyManager[] km, TrustManager[] tm,
SecureRandom sr) throws KeyManagementException {
isInitialized = false;
keyManager = chooseKeyManager(km);
if (tm == null) {
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore)null);
tm = tmf.getTrustManagers();
} catch (Exception e) {
// eat
}
}
trustManager = chooseTrustManager(tm);
if (sr == null) {
secureRandom = JsseJce.getSecureRandom();
} else {
if (SunJSSE.isFIPS() &&
(sr.getProvider() != SunJSSE.cryptoProvider)) {
throw new KeyManagementException
("FIPS mode: SecureRandom must be from provider "
+ SunJSSE.cryptoProvider.getName());
}
secureRandom = sr;
}
/*
* The initial delay of seeding the random number generator
* could be long enough to cause the initial handshake on our
* first connection to timeout and fail. Make sure it is
* primed and ready by getting some initial output from it.
*/
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.finest("trigger seeding of SecureRandom");
}
secureRandom.nextInt();
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.finest("done seeding of SecureRandom");
}
isInitialized = true;
}
private X509TrustManager chooseTrustManager(TrustManager[] tm)
throws KeyManagementException {
// We only use the first instance of X509TrustManager passed to us.
for (int i = 0; tm != null && i < tm.length; i++) {
if (tm[i] instanceof X509TrustManager) {
if (SunJSSE.isFIPS() &&
!(tm[i] instanceof X509TrustManagerImpl)) {
throw new KeyManagementException
("FIPS mode: only SunJSSE TrustManagers may be used");
}
if (tm[i] instanceof X509ExtendedTrustManager) {
return (X509TrustManager)tm[i];
} else {
return new AbstractTrustManagerWrapper(
(X509TrustManager)tm[i]);
}
}
}
// nothing found, return a dummy X509TrustManager.
return DummyX509TrustManager.INSTANCE;
}
private X509ExtendedKeyManager chooseKeyManager(KeyManager[] kms)
throws KeyManagementException {
for (int i = 0; kms != null && i < kms.length; i++) {
KeyManager km = kms[i];
if (!(km instanceof X509KeyManager)) {
continue;
}
if (SunJSSE.isFIPS()) {
// In FIPS mode, require that one of SunJSSE's own keymanagers
// is used. Otherwise, we cannot be sure that only keys from
// the FIPS token are used.
if ((km instanceof X509KeyManagerImpl)
|| (km instanceof SunX509KeyManagerImpl)) {
return (X509ExtendedKeyManager)km;
} else {
// throw exception, we don't want to silently use the
// dummy keymanager without telling the user.
throw new KeyManagementException
("FIPS mode: only SunJSSE KeyManagers may be used");
}
}
if (km instanceof X509ExtendedKeyManager) {
return (X509ExtendedKeyManager)km;
}
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.warning(
"X509KeyManager passed to SSLContext.init(): need an " +
"X509ExtendedKeyManager for SSLEngine use");
}
return new AbstractKeyManagerWrapper((X509KeyManager)km);
}
// nothing found, return a dummy X509ExtendedKeyManager
return DummyX509KeyManager.INSTANCE;
}
abstract SSLEngine createSSLEngineImpl();
abstract SSLEngine createSSLEngineImpl(String host, int port);
@Override
protected SSLEngine engineCreateSSLEngine() {
if (!isInitialized) {
throw new IllegalStateException("SSLContext is not initialized");
}
return createSSLEngineImpl();
}
@Override
protected SSLEngine engineCreateSSLEngine(String host, int port) {
if (!isInitialized) {
throw new IllegalStateException("SSLContext is not initialized");
}
return createSSLEngineImpl(host, port);
}
@Override
protected SSLSocketFactory engineGetSocketFactory() {
if (!isInitialized) {
throw new IllegalStateException("SSLContext is not initialized");
}
if (isDTLS()) {
throw new UnsupportedOperationException(
"DTLS not supported with SSLSocket");
}
return new SSLSocketFactoryImpl(this);
}
@Override
protected SSLServerSocketFactory engineGetServerSocketFactory() {
if (!isInitialized) {
throw new IllegalStateException("SSLContext is not initialized");
}
if (isDTLS()) {
throw new UnsupportedOperationException(
"DTLS not supported with SSLServerSocket");
}
return new SSLServerSocketFactoryImpl(this);
}
@Override
protected SSLSessionContext engineGetClientSessionContext() {
return clientCache;
}
@Override
protected SSLSessionContext engineGetServerSessionContext() {
return serverCache;
}
SecureRandom getSecureRandom() {
return secureRandom;
}
X509ExtendedKeyManager getX509KeyManager() {
return keyManager;
}
X509TrustManager getX509TrustManager() {
return trustManager;
}
EphemeralKeyManager getEphemeralKeyManager() {
return ephemeralKeyManager;
}
// Used for DTLS in server mode only.
HelloCookieManager getHelloCookieManager(ProtocolVersion protocolVersion) {
if (helloCookieManagerBuilder == null) {
synchronized (this) {
if (helloCookieManagerBuilder == null) {
helloCookieManagerBuilder =
new HelloCookieManager.Builder(secureRandom);
}
}
}
return helloCookieManagerBuilder.valueOf(protocolVersion);
}
StatusResponseManager getStatusResponseManager() {
if (serverEnableStapling && statusResponseManager == null) {
synchronized (this) {
if (statusResponseManager == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.finest(
"Initializing StatusResponseManager");
}
statusResponseManager = new StatusResponseManager();
}
}
}
return statusResponseManager;
}
// Get supported protocols.
abstract List getSupportedProtocolVersions();
// Get default protocols for server mode.
abstract List getServerDefaultProtocolVersions();
// Get default protocols for client mode.
abstract List getClientDefaultProtocolVersions();
// Get supported CipherSuite list.
abstract List getSupportedCipherSuites();
// Get default CipherSuite list for server mode.
abstract List getServerDefaultCipherSuites();
// Get default CipherSuite list for client mode.
abstract List getClientDefaultCipherSuites();
// Is the context for DTLS protocols?
abstract boolean isDTLS();
// Get default protocols.
List getDefaultProtocolVersions(boolean roleIsServer) {
return roleIsServer ? getServerDefaultProtocolVersions()
: getClientDefaultProtocolVersions();
}
// Get default CipherSuite list.
List getDefaultCipherSuites(boolean roleIsServer) {
return roleIsServer ? getServerDefaultCipherSuites()
: getClientDefaultCipherSuites();
}
/**
* Return whether a protocol list is the original default enabled
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultProtocolVesions(List protocols) {
return (protocols == getServerDefaultProtocolVersions()) ||
(protocols == getClientDefaultProtocolVersions());
}
/**
* Return whether a protocol list is the original default enabled
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultCipherSuiteList(List cipherSuites) {
return (cipherSuites == getServerDefaultCipherSuites()) ||
(cipherSuites == getClientDefaultCipherSuites());
}
/**
* Return whether client or server side stapling has been enabled
* for this SSLContextImpl
* @param isClient true if the caller is operating in a client side role,
* false if acting as a server.
* @return true if stapling has been enabled for the specified role, false
* otherwise.
*/
boolean isStaplingEnabled(boolean isClient) {
return isClient ? clientEnableStapling : serverEnableStapling;
}
/*
* Return the list of all available CipherSuites that are supported
* using currently installed providers.
*/
private static List getApplicableSupportedCipherSuites(
List protocols) {
return getApplicableCipherSuites(
CipherSuite.allowedCipherSuites(), protocols);
}
/*
* Return the list of all available CipherSuites that are default enabled
* in client or server side.
*/
private static List getApplicableEnabledCipherSuites(
List protocols, boolean isClient) {
if (isClient) {
if (!clientCustomizedCipherSuites.isEmpty()) {
return getApplicableCipherSuites(
clientCustomizedCipherSuites, protocols);
}
} else {
if (!serverCustomizedCipherSuites.isEmpty()) {
return getApplicableCipherSuites(
serverCustomizedCipherSuites, protocols);
}
}
return getApplicableCipherSuites(
CipherSuite.defaultCipherSuites(), protocols);
}
/*
* Return the list of available CipherSuites which are applicable to
* the specified protocols.
*/
private static List getApplicableCipherSuites(
Collection allowedCipherSuites,
List protocols) {
TreeSet suites = new TreeSet<>();
if (protocols != null && (!protocols.isEmpty())) {
for (CipherSuite suite : allowedCipherSuites) {
if (!suite.isAvailable()) {
continue;
}
boolean isSupported = false;
for (ProtocolVersion protocol : protocols) {
if (!suite.supports(protocol)) {
continue;
}
if (SSLAlgorithmConstraints.DEFAULT.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
suite.name, null)) {
suites.add(suite);
isSupported = true;
} else if (SSLLogger.isOn &&
SSLLogger.isOn("ssl,sslctx,verbose")) {
SSLLogger.fine(
"Ignore disabled cipher suite: " + suite.name);
}
break;
}
if (!isSupported && SSLLogger.isOn &&
SSLLogger.isOn("ssl,sslctx,verbose")) {
SSLLogger.finest(
"Ignore unsupported cipher suite: " + suite);
}
}
}
return new ArrayList<>(suites);
}
/*
* Get the customized cipher suites specified by the given system property.
*/
private static Collection getCustomizedCipherSuites(
String propertyName) {
String property = GetPropertyAction.privilegedGetProperty(propertyName);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.fine(
"System property " + propertyName + " is set to '" +
property + "'");
}
if (property != null && !property.isEmpty()) {
// remove double quote marks from beginning/end of the property
if (property.length() > 1 && property.charAt(0) == '"' &&
property.charAt(property.length() - 1) == '"') {
property = property.substring(1, property.length() - 1);
}
}
if (property != null && !property.isEmpty()) {
String[] cipherSuiteNames = property.split(",");
Collection cipherSuites =
new ArrayList<>(cipherSuiteNames.length);
for (int i = 0; i < cipherSuiteNames.length; i++) {
cipherSuiteNames[i] = cipherSuiteNames[i].trim();
if (cipherSuiteNames[i].isEmpty()) {
continue;
}
CipherSuite suite;
try {
suite = CipherSuite.nameOf(cipherSuiteNames[i]);
} catch (IllegalArgumentException iae) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.fine(
"Unknown or unsupported cipher suite name: " +
cipherSuiteNames[i]);
}
continue;
}
if (suite != null && suite.isAvailable()) {
cipherSuites.add(suite);
} else {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.fine(
"The current installed providers do not " +
"support cipher suite: " + cipherSuiteNames[i]);
}
}
}
return cipherSuites;
}
return Collections.emptyList();
}
private static List getAvailableProtocols(
ProtocolVersion[] protocolCandidates) {
List availableProtocols =
Collections.emptyList();
if (protocolCandidates != null && protocolCandidates.length != 0) {
availableProtocols = new ArrayList<>(protocolCandidates.length);
for (ProtocolVersion p : protocolCandidates) {
if (p.isAvailable) {
availableProtocols.add(p);
}
}
}
return availableProtocols;
}
/*
* The SSLContext implementation for SSL/(D)TLS algorithm
*
* SSL/TLS protocols specify the forward compatibility and version
* roll-back attack protections, however, a number of SSL/TLS server
* vendors did not implement these aspects properly, and some current
* SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
*
* Considering above interoperability issues, SunJSSE will not set
* TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
*
* For SSL/TLS servers, there is no such interoperability issues as
* SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
* enabled protocols for server by default.
*
* We may change the behavior when popular TLS/SSL vendors support TLS
* forward compatibility properly.
*
* SSLv2Hello is no longer necessary. This interoperability option was
* put in place in the late 90's when SSLv3/TLS1.0 were relatively new
* and there were a fair number of SSLv2-only servers deployed. Because
* of the security issues in SSLv2, it is rarely (if ever) used, as
* deployments should now be using SSLv3 and TLSv1.
*
* Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
* by default. Applications still can use it by enabling SSLv2Hello with
* the series of setEnabledProtocols APIs.
*/
/*
* The base abstract SSLContext implementation for the Transport Layer
* Security (TLS) protocols.
*
* This abstract class encapsulates supported and the default server
* SSL/TLS parameters.
*
* @see SSLContext
*/
private abstract static class AbstractTLSContext extends SSLContextImpl {
private static final List supportedProtocols;
private static final List serverDefaultProtocols;
private static final List supportedCipherSuites;
private static final List serverDefaultCipherSuites;
static {
if (SunJSSE.isFIPS()) {
supportedProtocols = Arrays.asList(
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
);
serverDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
});
} else {
supportedProtocols = Arrays.asList(
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10,
ProtocolVersion.SSL30,
ProtocolVersion.SSL20Hello
);
serverDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10,
ProtocolVersion.SSL30,
ProtocolVersion.SSL20Hello
});
}
supportedCipherSuites = getApplicableSupportedCipherSuites(
supportedProtocols);
serverDefaultCipherSuites = getApplicableEnabledCipherSuites(
serverDefaultProtocols, false);
}
@Override
List getSupportedProtocolVersions() {
return supportedProtocols;
}
@Override
List getSupportedCipherSuites() {
return supportedCipherSuites;
}
@Override
List getServerDefaultProtocolVersions() {
return serverDefaultProtocols;
}
@Override
List getServerDefaultCipherSuites() {
return serverDefaultCipherSuites;
}
@Override
SSLEngine createSSLEngineImpl() {
return new SSLEngineImpl(this);
}
@Override
SSLEngine createSSLEngineImpl(String host, int port) {
return new SSLEngineImpl(this, host, port);
}
@Override
boolean isDTLS() {
return false;
}
static ProtocolVersion[] getSupportedProtocols() {
if (SunJSSE.isFIPS()) {
return new ProtocolVersion[] {
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
};
} else {
return new ProtocolVersion[]{
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10,
ProtocolVersion.SSL30,
ProtocolVersion.SSL20Hello
};
}
}
}
/*
* The SSLContext implementation for SSLv3 and TLS10 algorithm
*
* @see SSLContext
*/
public static final class TLS10Context extends AbstractTLSContext {
private static final List clientDefaultProtocols;
private static final List clientDefaultCipherSuites;
static {
if (SunJSSE.isFIPS()) {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS10
});
} else {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.SSL30
});
}
clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
clientDefaultProtocols, true);
}
@Override
List getClientDefaultProtocolVersions() {
return clientDefaultProtocols;
}
@Override
List getClientDefaultCipherSuites() {
return clientDefaultCipherSuites;
}
}
/*
* The SSLContext implementation for TLS11 algorithm
*
* @see SSLContext
*/
public static final class TLS11Context extends AbstractTLSContext {
private static final List clientDefaultProtocols;
private static final List clientDefaultCipherSuites;
static {
if (SunJSSE.isFIPS()) {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
});
} else {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS11,
ProtocolVersion.TLS10,
ProtocolVersion.SSL30
});
}
clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
clientDefaultProtocols, true);
}
@Override
List getClientDefaultProtocolVersions() {
return clientDefaultProtocols;
}
@Override
List getClientDefaultCipherSuites() {
return clientDefaultCipherSuites;
}
}
/*
* The SSLContext implementation for TLS12 algorithm
*
* @see SSLContext
*/
public static final class TLS12Context extends AbstractTLSContext {
private static final List clientDefaultProtocols;
private static final List clientDefaultCipherSuites;
static {
if (SunJSSE.isFIPS()) {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
});
} else {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10,
ProtocolVersion.SSL30
});
}
clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
clientDefaultProtocols, true);
}
@Override
List getClientDefaultProtocolVersions() {
return clientDefaultProtocols;
}
@Override
List getClientDefaultCipherSuites() {
return clientDefaultCipherSuites;
}
}
/*
* The SSLContext implementation for TLS1.3 algorithm
*
* @see SSLContext
*/
public static final class TLS13Context extends AbstractTLSContext {
private static final List clientDefaultProtocols;
private static final List clientDefaultCipherSuites;
static {
if (SunJSSE.isFIPS()) {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
});
} else {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10,
ProtocolVersion.SSL30
});
}
clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
clientDefaultProtocols, true);
}
@Override
List getClientDefaultProtocolVersions() {
return clientDefaultProtocols;
}
@Override
List getClientDefaultCipherSuites() {
return clientDefaultCipherSuites;
}
}
/*
* The interface for the customized SSL/(D)TLS SSLContext.
*
* @see SSLContext
*/
private static class CustomizedSSLProtocols {
private static final String JDK_TLS_CLIENT_PROTOCOLS =
"jdk.tls.client.protocols";
private static final String JDK_TLS_SERVER_PROTOCOLS =
"jdk.tls.server.protocols";
static IllegalArgumentException reservedException = null;
static final ArrayList customizedClientProtocols =
new ArrayList<>();
static final ArrayList customizedServerProtocols =
new ArrayList<>();
// Don't want a java.lang.LinkageError for illegal system property.
//
// Please don't throw exception in this static block. Otherwise,
// java.lang.LinkageError may be thrown during the instantiation of
// the provider service. Instead, please handle the initialization
// exception in the caller's constructor.
static {
populate(JDK_TLS_CLIENT_PROTOCOLS, customizedClientProtocols);
populate(JDK_TLS_SERVER_PROTOCOLS, customizedServerProtocols);
}
private static void populate(String propname,
ArrayList arrayList) {
String property = GetPropertyAction.privilegedGetProperty(propname);
if (property == null) {
return;
}
if (!property.isEmpty()) {
// remove double quote marks from beginning/end of the property
if (property.length() > 1 && property.charAt(0) == '"' &&
property.charAt(property.length() - 1) == '"') {
property = property.substring(1, property.length() - 1);
}
}
if (!property.isEmpty()) {
String[] protocols = property.split(",");
for (int i = 0; i < protocols.length; i++) {
protocols[i] = protocols[i].trim();
// Is it a supported protocol name?
ProtocolVersion pv =
ProtocolVersion.nameOf(protocols[i]);
if (pv == null) {
reservedException = new IllegalArgumentException(
propname + ": " + protocols[i] +
" is not a supported SSL protocol name");
}
if (SunJSSE.isFIPS() &&
((pv == ProtocolVersion.SSL30) ||
(pv == ProtocolVersion.SSL20Hello))) {
reservedException = new IllegalArgumentException(
propname + ": " + pv +
" is not FIPS compliant");
break;
}
// ignore duplicated protocols
if (!arrayList.contains(pv)) {
arrayList.add(pv);
}
}
}
}
}
/*
* The SSLContext implementation for customized TLS protocols
*
* @see SSLContext
*/
private static class CustomizedTLSContext extends AbstractTLSContext {
private static final List clientDefaultProtocols;
private static final List serverDefaultProtocols;
private static final List clientDefaultCipherSuites;
private static final List serverDefaultCipherSuites;
private static final IllegalArgumentException reservedException;
// Don't want a java.lang.LinkageError for illegal system property.
//
// Please don't throw exception in this static block. Otherwise,
// java.lang.LinkageError may be thrown during the instantiation of
// the provider service. Instead, let's handle the initialization
// exception in constructor.
static {
reservedException = CustomizedSSLProtocols.reservedException;
if (reservedException == null) {
clientDefaultProtocols = customizedProtocols(true,
CustomizedSSLProtocols.customizedClientProtocols);
serverDefaultProtocols = customizedProtocols(false,
CustomizedSSLProtocols.customizedServerProtocols);
clientDefaultCipherSuites =
getApplicableEnabledCipherSuites(
clientDefaultProtocols, true);
serverDefaultCipherSuites =
getApplicableEnabledCipherSuites(
serverDefaultProtocols, false);
} else {
// unlikely to be used
clientDefaultProtocols = null;
serverDefaultProtocols = null;
clientDefaultCipherSuites = null;
serverDefaultCipherSuites = null;
}
}
private static List customizedProtocols(
boolean client, List customized) {
List refactored = new ArrayList<>();
for (ProtocolVersion pv : customized) {
if (!pv.isDTLS) {
refactored.add(pv);
}
}
// Use the default enabled protocols if no customization
ProtocolVersion[] candidates;
if (refactored.isEmpty()) {
if (client) {
candidates = getProtocols();
} else {
candidates = getSupportedProtocols();
}
} else {
// Use the customized TLS protocols.
candidates =
refactored.toArray(new ProtocolVersion[refactored.size()]);
}
return getAvailableProtocols(candidates);
}
static ProtocolVersion[] getProtocols() {
if (SunJSSE.isFIPS()) {
return new ProtocolVersion[]{
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
};
} else {
return new ProtocolVersion[]{
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10,
ProtocolVersion.SSL30
};
}
}
protected CustomizedTLSContext() {
if (reservedException != null) {
throw reservedException;
}
}
@Override
List getClientDefaultProtocolVersions() {
return clientDefaultProtocols;
}
@Override
List getServerDefaultProtocolVersions() {
return serverDefaultProtocols;
}
@Override
List getClientDefaultCipherSuites() {
return clientDefaultCipherSuites;
}
@Override
List getServerDefaultCipherSuites() {
return serverDefaultCipherSuites;
}
}
/*
* The SSLContext implementation for default "TLS" algorithm
*
* @see SSLContext
*/
public static final class TLSContext extends CustomizedTLSContext {
// use the default constructor and methods
}
// 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 final TrustManager[] trustManagers;
private static final KeyManager[] keyManagers;
private static final Exception reservedException;
static {
Exception reserved = null;
TrustManager[] tmMediator;
try {
tmMediator = getTrustManagers();
} catch (Exception e) {
reserved = e;
tmMediator = new TrustManager[0];
}
trustManagers = tmMediator;
if (reserved == null) {
KeyManager[] kmMediator;
try {
kmMediator = getKeyManagers();
} catch (Exception e) {
reserved = e;
kmMediator = new KeyManager[0];
}
keyManagers = kmMediator;
} else {
keyManagers = new KeyManager[0];
}
reservedException = reserved;
}
private static TrustManager[] getTrustManagers() throws Exception {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
if ("SunJSSE".equals(tmf.getProvider().getName())) {
// The implementation will load the default KeyStore
// automatically. Cached trust materials may be used
// for performance improvement.
tmf.init((KeyStore)null);
} else {
// Use the explicitly specified KeyStore for third party's
// TrustManagerFactory implementation.
KeyStore ks = TrustStoreManager.getTrustedKeyStore();
tmf.init(ks);
}
return tmf.getTrustManagers();
}
private static KeyManager[] getKeyManagers() throws Exception {
final Map props = new HashMap<>();
AccessController.doPrivileged(
new PrivilegedExceptionAction
© 2015 - 2025 Weber Informatics LLC | Privacy Policy