
org.glassfish.grizzly.ssl.SSLContextConfigurator Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.grizzly.ssl;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.glassfish.grizzly.Grizzly;
/**
* Utility class, which helps to configure {@link SSLContext}.
*
* @author Alexey Stashok
* @author Hubert Iwaniuk
* @author Bruno Harbulot
*/
public class SSLContextConfigurator {
public static final String TRUST_STORE_PROVIDER = "javax.net.ssl.trustStoreProvider";
public static final String KEY_STORE_PROVIDER = "javax.net.ssl.keyStoreProvider";
public static final String TRUST_STORE_FILE = "javax.net.ssl.trustStore";
public static final String KEY_STORE_FILE = "javax.net.ssl.keyStore";
public static final String TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
public static final String KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
public static final String TRUST_STORE_TYPE = "javax.net.ssl.trustStoreType";
public static final String KEY_STORE_TYPE = "javax.net.ssl.keyStoreType";
public static final String KEY_FACTORY_MANAGER_ALGORITHM = "ssl.KeyManagerFactory.algorithm";
public static final String TRUST_FACTORY_MANAGER_ALGORITHM = "ssl.TrustManagerFactory.algorithm";
/**
* Default Logger.
*/
private static final Logger LOGGER = Grizzly.logger(SSLContextConfigurator.class);
/**
* Default SSL configuration. If you have changed any of {@link System#getProperties()} of javax.net.ssl family you
* should refresh this configuration by calling {@link #retrieve(java.util.Properties)}.
*/
public static final SSLContextConfigurator DEFAULT_CONFIG = new SSLContextConfigurator();
private String trustStoreProvider;
private String keyStoreProvider;
private String trustStoreType;
private String keyStoreType;
private char[] trustStorePass;
private char[] keyStorePass;
private char[] keyPass;
private String trustStoreFile;
private String keyStoreFile;
private byte[] trustStoreBytes;
private byte[] keyStoreBytes;
private String trustManagerFactoryAlgorithm;
private String keyManagerFactoryAlgorithm;
private String securityProtocol = "TLS";
/**
* Default constructor. Reads configuration properties from {@link System#getProperties()}. Calls
* {@link #SSLContextConfigurator(boolean)} with true
.
*/
public SSLContextConfigurator() {
this(true);
}
/**
* Constructor that allows you creating empty configuration.
*
* @param readSystemProperties If true
populates configuration from {@link System#getProperties()}, else
* you have empty configuration.
*/
public SSLContextConfigurator(boolean readSystemProperties) {
if (readSystemProperties) {
retrieve(System.getProperties());
}
}
/**
* Sets the trust store provider name.
*
* @param trustStoreProvider Trust store provider to set.
*/
public void setTrustStoreProvider(String trustStoreProvider) {
this.trustStoreProvider = trustStoreProvider;
}
/**
* Sets the key store provider name.
*
* @param keyStoreProvider Key store provider to set.
*/
public void setKeyStoreProvider(String keyStoreProvider) {
this.keyStoreProvider = keyStoreProvider;
}
/**
* Type of trust store.
*
* @param trustStoreType Type of trust store to set.
*/
public void setTrustStoreType(String trustStoreType) {
this.trustStoreType = trustStoreType;
}
/**
* Type of key store.
*
* @param keyStoreType Type of key store to set.
*/
public void setKeyStoreType(String keyStoreType) {
this.keyStoreType = keyStoreType;
}
/**
* Password of trust store.
*
* @param trustStorePass Password of trust store to set.
*/
public void setTrustStorePass(String trustStorePass) {
this.trustStorePass = trustStorePass.toCharArray();
}
/**
* Password of key store.
*
* @param keyStorePass Password of key store to set.
*/
public void setKeyStorePass(String keyStorePass) {
this.keyStorePass = keyStorePass.toCharArray();
}
/**
* Password of key store.
*
* @param keyStorePass Password of key store to set.
*/
public void setKeyStorePass(char[] keyStorePass) {
this.keyStorePass = keyStorePass;
}
/**
* Password of the key in the key store.
*
* @param keyPass Password of key to set.
*/
public void setKeyPass(String keyPass) {
this.keyPass = keyPass.toCharArray();
}
/**
* Password of the key in the key store.
*
* @param keyPass Password of key to set.
*/
public void setKeyPass(char[] keyPass) {
this.keyPass = keyPass;
}
/**
* Sets trust store file name, also makes sure that if other trust store configuration parameters are not set to set
* them to default values. Method resets trust store bytes if any have been set before via
* {@link #setTrustStoreBytes(byte[])}.
*
* @param trustStoreFile File name of trust store.
*/
public void setTrustStoreFile(String trustStoreFile) {
this.trustStoreFile = trustStoreFile;
this.trustStoreBytes = null;
}
/**
* Sets trust store payload as byte array. Method resets trust store file if any has been set before via
* {@link #setTrustStoreFile(java.lang.String)}.
*
* @param trustStoreBytes trust store payload.
*/
public void setTrustStoreBytes(byte[] trustStoreBytes) {
this.trustStoreBytes = trustStoreBytes;
this.trustStoreFile = null;
}
/**
* Sets key store file name, also makes sure that if other key store configuration parameters are not set to set them to
* default values. Method resets key store bytes if any have been set before via {@link #setKeyStoreBytes(byte[])}.
*
* @param keyStoreFile File name of key store.
*/
public void setKeyStoreFile(String keyStoreFile) {
this.keyStoreFile = keyStoreFile;
this.keyStoreBytes = null;
}
/**
* Sets key store payload as byte array. Method resets key store file if any has been set before via
* {@link #setKeyStoreFile(java.lang.String)}.
*
* @param keyStoreBytes key store payload.
*/
public void setKeyStoreBytes(byte[] keyStoreBytes) {
this.keyStoreBytes = keyStoreBytes;
this.keyStoreFile = null;
}
/**
* Sets the trust manager factory algorithm.
*
* @param trustManagerFactoryAlgorithm the trust manager factory algorithm.
*/
public void setTrustManagerFactoryAlgorithm(String trustManagerFactoryAlgorithm) {
this.trustManagerFactoryAlgorithm = trustManagerFactoryAlgorithm;
}
/**
* Sets the key manager factory algorithm.
*
* @param keyManagerFactoryAlgorithm the key manager factory algorithm.
*/
public void setKeyManagerFactoryAlgorithm(String keyManagerFactoryAlgorithm) {
this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm;
}
/**
* Sets the SSLContext protocol. The default value is TLS
if this is null.
*
* @param securityProtocol Protocol for {@link javax.net.ssl.SSLContext#getProtocol()}.
*/
public void setSecurityProtocol(String securityProtocol) {
this.securityProtocol = securityProtocol;
}
/**
* Validates {@link SSLContextConfigurator} configuration.
*
* @return true
if configuration is valid, else false
.
*
* @deprecated Use {@link #createSSLContext(boolean)}.
*/
@Deprecated
public boolean validateConfiguration() {
return validateConfiguration(false);
}
/**
* Validates {@link SSLContextConfigurator} configuration.
*
* @param needsKeyStore forces failure if no keystore is specified.
* @return true
if configuration is valid, else false
.
*
* @deprecated Use {@link #createSSLContext(boolean)}.
*/
@Deprecated
public boolean validateConfiguration(boolean needsKeyStore) {
boolean valid = true;
if (keyStoreBytes != null || keyStoreFile != null) {
try {
KeyStore keyStore;
if (keyStoreProvider != null) {
keyStore = KeyStore.getInstance(keyStoreType != null ? keyStoreType : KeyStore.getDefaultType(), keyStoreProvider);
} else {
keyStore = KeyStore.getInstance(keyStoreType != null ? keyStoreType : KeyStore.getDefaultType());
}
loadBytes(keyStoreBytes, keyStoreFile, keyStorePass, keyStore);
String kmfAlgorithm = keyManagerFactoryAlgorithm;
if (kmfAlgorithm == null) {
kmfAlgorithm = System.getProperty(KEY_FACTORY_MANAGER_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
}
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(kmfAlgorithm);
keyManagerFactory.init(keyStore, keyPass != null ? keyPass : keyStorePass);
} catch (KeyStoreException e) {
LOGGER.log(Level.FINE, "Error initializing key store", e);
valid = false;
} catch (CertificateException e) {
LOGGER.log(Level.FINE, "Key store certificate exception.", e);
valid = false;
} catch (UnrecoverableKeyException e) {
LOGGER.log(Level.FINE, "Key store unrecoverable exception.", e);
valid = false;
} catch (FileNotFoundException e) {
LOGGER.log(Level.FINE, "Can't find key store file: " + keyStoreFile, e);
valid = false;
} catch (IOException e) {
LOGGER.log(Level.FINE, "Error loading key store from file: " + keyStoreFile, e);
valid = false;
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.FINE, "Error initializing key manager factory (no such algorithm)", e);
valid = false;
} catch (NoSuchProviderException e) {
LOGGER.log(Level.FINE, "Error initializing key store (no such provider)", e);
valid = false;
}
} else {
valid = !needsKeyStore;
}
if (trustStoreBytes != null || trustStoreFile != null) {
try {
KeyStore trustStore;
if (trustStoreProvider != null) {
trustStore = KeyStore.getInstance(trustStoreType != null ? trustStoreType : KeyStore.getDefaultType(), trustStoreProvider);
} else {
trustStore = KeyStore.getInstance(trustStoreType != null ? trustStoreType : KeyStore.getDefaultType());
}
loadBytes(trustStoreBytes, trustStoreFile, trustStorePass, trustStore);
String tmfAlgorithm = trustManagerFactoryAlgorithm;
if (tmfAlgorithm == null) {
tmfAlgorithm = System.getProperty(TRUST_FACTORY_MANAGER_ALGORITHM, TrustManagerFactory.getDefaultAlgorithm());
}
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm);
trustManagerFactory.init(trustStore);
} catch (KeyStoreException e) {
LOGGER.log(Level.FINE, "Error initializing trust store", e);
valid = false;
} catch (CertificateException e) {
LOGGER.log(Level.FINE, "Trust store certificate exception.", e);
valid = false;
} catch (FileNotFoundException e) {
LOGGER.log(Level.FINE, "Can't find trust store file: " + trustStoreFile, e);
valid = false;
} catch (IOException e) {
LOGGER.log(Level.FINE, "Error loading trust store from file: " + trustStoreFile, e);
valid = false;
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.FINE, "Error initializing trust manager factory (no such algorithm)", e);
valid = false;
} catch (NoSuchProviderException e) {
LOGGER.log(Level.FINE, "Error initializing trust store (no such provider)", e);
valid = false;
}
}
return valid;
}
/**
* Create a new {@link SSLContext}. Note that if there are any problems with the key or trust stores, that no exception
* will be thrown.
*
* @return a new {@link SSLContext}
*
* @deprecated Use {@link #createSSLContext(boolean)}.
*/
@Deprecated
public SSLContext createSSLContext() {
return createSSLContext(false);
}
/**
* Create a new {@link SSLContext}. If the {@link SSLContext} cannot be created for whatever reason, a
* {@link GenericStoreException} will be raised containing the root cause of the failure.
*
* @param throwException true
if an exception should be raised upon failure.
*
* @return a new {@link SSLContext}
*
* @throws GenericStoreException throwException
is true
and the SSLContext cannot be created
*
* @since 2.3.28
*/
public SSLContext createSSLContext(final boolean throwException) {
SSLContext sslContext = null;
try {
TrustManagerFactory trustManagerFactory = null;
KeyManagerFactory keyManagerFactory = null;
if (keyStoreBytes != null || keyStoreFile != null) {
try {
KeyStore keyStore;
if (keyStoreProvider != null) {
keyStore = KeyStore.getInstance(keyStoreType != null ? keyStoreType : KeyStore.getDefaultType(), keyStoreProvider);
} else {
keyStore = KeyStore.getInstance(keyStoreType != null ? keyStoreType : KeyStore.getDefaultType());
}
loadBytes(keyStoreBytes, keyStoreFile, keyStorePass, keyStore);
String kmfAlgorithm = keyManagerFactoryAlgorithm;
if (kmfAlgorithm == null) {
kmfAlgorithm = System.getProperty(KEY_FACTORY_MANAGER_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
}
keyManagerFactory = KeyManagerFactory.getInstance(kmfAlgorithm);
keyManagerFactory.init(keyStore, keyPass != null ? keyPass : keyStorePass);
} catch (KeyStoreException e) {
LOGGER.log(Level.FINE, "Error initializing key store", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (CertificateException e) {
LOGGER.log(Level.FINE, "Key store certificate exception.", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (UnrecoverableKeyException e) {
LOGGER.log(Level.FINE, "Key store unrecoverable exception.", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (FileNotFoundException e) {
LOGGER.log(Level.FINE, "Can't find key store file: " + keyStoreFile, e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (IOException e) {
LOGGER.log(Level.FINE, "Error loading key store from file: " + keyStoreFile, e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.FINE, "Error initializing key manager factory (no such algorithm)", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (NoSuchProviderException e) {
LOGGER.log(Level.FINE, "Error initializing key store (no such provider)", e);
}
}
if (trustStoreBytes != null || trustStoreFile != null) {
try {
KeyStore trustStore;
if (trustStoreProvider != null) {
trustStore = KeyStore.getInstance(trustStoreType != null ? trustStoreType : KeyStore.getDefaultType(), trustStoreProvider);
} else {
trustStore = KeyStore.getInstance(trustStoreType != null ? trustStoreType : KeyStore.getDefaultType());
}
loadBytes(trustStoreBytes, trustStoreFile, trustStorePass, trustStore);
String tmfAlgorithm = trustManagerFactoryAlgorithm;
if (tmfAlgorithm == null) {
tmfAlgorithm = System.getProperty(TRUST_FACTORY_MANAGER_ALGORITHM, TrustManagerFactory.getDefaultAlgorithm());
}
trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm);
trustManagerFactory.init(trustStore);
} catch (KeyStoreException e) {
LOGGER.log(Level.FINE, "Error initializing trust store", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (CertificateException e) {
LOGGER.log(Level.FINE, "Trust store certificate exception.", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (FileNotFoundException e) {
LOGGER.log(Level.FINE, "Can't find trust store file: " + trustStoreFile, e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (IOException e) {
LOGGER.log(Level.FINE, "Error loading trust store from file: " + trustStoreFile, e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.FINE, "Error initializing trust manager factory (no such algorithm)", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (NoSuchProviderException e) {
LOGGER.log(Level.FINE, "Error initializing trust store (no such provider)", e);
if (throwException) {
throw new GenericStoreException(e);
}
}
}
String secProtocol = "TLS";
if (securityProtocol != null) {
secProtocol = securityProtocol;
}
sslContext = SSLContext.getInstance(secProtocol);
sslContext.init(keyManagerFactory != null ? keyManagerFactory.getKeyManagers() : null,
trustManagerFactory != null ? trustManagerFactory.getTrustManagers() : null, null);
} catch (KeyManagementException e) {
LOGGER.log(Level.FINE, "Key management error.", e);
if (throwException) {
throw new GenericStoreException(e);
}
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.FINE, "Error initializing algorithm.", e);
if (throwException) {
throw new GenericStoreException(e);
}
}
return sslContext;
}
public void retrieve(Properties props) {
trustStoreProvider = props.getProperty(TRUST_STORE_PROVIDER);
keyStoreProvider = props.getProperty(KEY_STORE_PROVIDER);
trustStoreType = props.getProperty(TRUST_STORE_TYPE);
keyStoreType = props.getProperty(KEY_STORE_TYPE);
if (props.getProperty(TRUST_STORE_PASSWORD) != null) {
trustStorePass = props.getProperty(TRUST_STORE_PASSWORD).toCharArray();
} else {
trustStorePass = null;
}
if (props.getProperty(KEY_STORE_PASSWORD) != null) {
keyStorePass = props.getProperty(KEY_STORE_PASSWORD).toCharArray();
} else {
keyStorePass = null;
}
trustStoreFile = props.getProperty(TRUST_STORE_FILE);
keyStoreFile = props.getProperty(KEY_STORE_FILE);
trustStoreBytes = null;
keyStoreBytes = null;
securityProtocol = "TLS";
}
private static void loadBytes(final byte[] bytes, final String storeFile, final char[] password, final KeyStore store)
throws IOException, CertificateException, NoSuchAlgorithmException {
InputStream inputStream = null;
try {
if (bytes != null) {
inputStream = new ByteArrayInputStream(bytes);
} else if (!"NONE".equals(storeFile)) {
inputStream = new FileInputStream(storeFile);
}
store.load(inputStream, password);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException ignored) {
}
}
}
public static final class GenericStoreException extends RuntimeException {
public GenericStoreException(Throwable cause) {
super(cause);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy