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 qbicc-rt-java.base Show documentation
Show all versions of qbicc-rt-java.base Show documentation
The Qbicc builder for the java.base JDK module
/*
* Copyright (c) 1999, 2021, 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.FileInputStream;
import java.net.Socket;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
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;
private final ReentrantLock contextLock = new ReentrantLock();
final HashMap keyHashMap = new HashMap<>();
SSLContextImpl() {
ephemeralKeyManager = new EphemeralKeyManager();
clientCache = new SSLSessionContextImpl(false);
serverCache = new SSLSessionContextImpl(true);
}
@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 = new SecureRandom();
} else {
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 (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 (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) {
contextLock.lock();
try {
if (helloCookieManagerBuilder == null) {
helloCookieManagerBuilder =
new HelloCookieManager.Builder(secureRandom);
}
} finally {
contextLock.unlock();
}
}
return helloCookieManagerBuilder.valueOf(protocolVersion);
}
StatusResponseManager getStatusResponseManager() {
if (serverEnableStapling && statusResponseManager == null) {
contextLock.lock();
try {
if (statusResponseManager == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.finest(
"Initializing StatusResponseManager");
}
statusResponseManager = new StatusResponseManager();
}
} finally {
contextLock.unlock();
}
}
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) {
LinkedHashSet suites = new LinkedHashSet<>();
if (protocols != null && (!protocols.isEmpty())) {
for (CipherSuite suite : allowedCipherSuites) {
if (!suite.isAvailable()) {
continue;
}
boolean isSupported = false;
for (ProtocolVersion protocol : protocols) {
if (!suite.supports(protocol) ||
!suite.bulkCipher.isAvailable()) {
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 {
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
});
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;
}
}
/*
* 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 {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS10
});
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 {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
});
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 {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
});
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 {
clientDefaultProtocols = getAvailableProtocols(
new ProtocolVersion[] {
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
});
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");
}
// 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()) {
// Client and server use the same default protocols.
candidates = new ProtocolVersion[] {
ProtocolVersion.TLS13,
ProtocolVersion.TLS12,
ProtocolVersion.TLS11,
ProtocolVersion.TLS10
};
} else {
// Use the customized TLS protocols.
candidates =
refactored.toArray(new ProtocolVersion[0]);
}
return getAvailableProtocols(candidates);
}
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 = null;
try {
tmMediator = getTrustManagers();
} catch (Exception e) {
reserved = e;
if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
SSLLogger.warning(
"Failed to load default trust managers", e);
}
}
KeyManager[] kmMediator = null;
if (reserved == null) {
try {
kmMediator = getKeyManagers();
} catch (Exception e) {
reserved = e;
if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
SSLLogger.warning(
"Failed to load default key managers", e);
}
}
}
if (reserved != null) {
trustManagers = new TrustManager[0];
keyManagers = new KeyManager[0];
// Important note: please don't reserve the original exception
// object, which may be not garbage collection friendly as
// 'reservedException' is a static filed.
reservedException =
new KeyManagementException(reserved.getMessage());
} else {
trustManagers = tmMediator;
keyManagers = kmMediator;
reservedException = null;
}
}
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();
}
@SuppressWarnings("removal")
private static KeyManager[] getKeyManagers() throws Exception {
final Map props = new HashMap<>();
AccessController.doPrivileged(
new PrivilegedExceptionAction
© 2015 - 2025 Weber Informatics LLC | Privacy Policy