All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.tyrus.client.SslContextConfigurator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2007, 2021 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.tyrus.client;

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;

/**
 * Utility class, which helps to configure ssl context.
 * 

* Used to configure {@link SslEngineConfigurator}, which will be passed to client via configuration properties. * Example: *

 *      SslContextConfigurator sslContextConfigurator = new SslContextConfigurator();
 *      sslContextConfigurator.setTrustStoreFile("...");
 *      sslContextConfigurator.setTrustStorePassword("...");
 *      sslContextConfigurator.setTrustStoreType("...");
 *      sslContextConfigurator.setKeyStoreFile("...");
 *      sslContextConfigurator.setKeyStorePassword("...");
 *      sslContextConfigurator.setKeyStoreType("...");
 *      SslEngineConfigurator sslEngineConfigurator = new SslEngineConfigurator(sslContextConfigurator, true, false,
 * false);
 *      client.getProperties().put(ClientManager.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator);
 * 
* * @author Alexey Stashok * @author Hubert Iwaniuk * @author Bruno Harbulot * @author Marek Potociar */ public class SslContextConfigurator { /** * Trust store provider name. *

* The value MUST be a {@code String} representing the name of a trust store provider. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String TRUST_STORE_PROVIDER = "javax.net.ssl.trustStoreProvider"; /** * Key store provider name. *

* The value MUST be a {@code String} representing the name of a trust store provider. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String KEY_STORE_PROVIDER = "javax.net.ssl.keyStoreProvider"; /** * Trust store file name. *

* The value MUST be a {@code String} representing the name of a trust store file. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String TRUST_STORE_FILE = "javax.net.ssl.trustStore"; /** * Key store file name. *

* The value MUST be a {@code String} representing the name of a key store file. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String KEY_STORE_FILE = "javax.net.ssl.keyStore"; /** * Trust store file password - the password used to unlock the trust store file. *

* The value MUST be a {@code String} representing the trust store file password. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword"; /** * Key store file password - the password used to unlock the trust store file. *

* The value MUST be a {@code String} representing the key store file password. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword"; /** * Trust store type (see {@link java.security.KeyStore#getType()} for more info). *

* The value MUST be a {@code String} representing the trust store type name. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String TRUST_STORE_TYPE = "javax.net.ssl.trustStoreType"; /** * Key store type (see {@link java.security.KeyStore#getType()} for more info). *

* The value MUST be a {@code String} representing the key store type name. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String KEY_STORE_TYPE = "javax.net.ssl.keyStoreType"; /** * Key manager factory algorithm name. *

* The value MUST be a {@code String} representing the key manager factory algorithm name. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String KEY_FACTORY_MANAGER_ALGORITHM = "ssl.KeyManagerFactory.algorithm"; /** * Trust manager factory algorithm name. *

* The value MUST be a {@code String} representing the trust manager factory algorithm name. *

* No default value is set. *

* The name of the configuration property is {@value}. */ public static final String TRUST_FACTORY_MANAGER_ALGORITHM = "ssl.TrustManagerFactory.algorithm"; /** * Default Logger. */ private static final Logger LOGGER = Logger.getLogger(SslContextConfigurator.class.getName()); /** * 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[] trustStorePassword; private char[] keyStorePassword; private char[] keyPassword; 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. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setTrustStoreProvider(String trustStoreProvider) { this.trustStoreProvider = trustStoreProvider; return this; } /** * Sets the key store provider name. * * @param keyStoreProvider Key store provider to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyStoreProvider(String keyStoreProvider) { this.keyStoreProvider = keyStoreProvider; return this; } /** * Type of trust store. * * @param trustStoreType Type of trust store to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setTrustStoreType(String trustStoreType) { this.trustStoreType = trustStoreType; return this; } /** * Type of key store. * * @param keyStoreType Type of key store to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyStoreType(String keyStoreType) { this.keyStoreType = keyStoreType; return this; } /** * Password of trust store. * * @param trustStorePassword Password of trust store to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setTrustStorePassword(String trustStorePassword) { this.trustStorePassword = trustStorePassword.toCharArray(); return this; } /** * Password of key store. * * @param keyStorePassword Password of key store to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyStorePassword(String keyStorePassword) { this.keyStorePassword = keyStorePassword.toCharArray(); return this; } /** * Password of key store. * * @param keyStorePassword Password of key store to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyStorePassword(char[] keyStorePassword) { this.keyStorePassword = keyStorePassword.clone(); return this; } /** * Password of the key in the key store. * * @param keyPassword Password of key to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyPassword(String keyPassword) { this.keyPassword = keyPassword.toCharArray(); return this; } /** * Password of the key in the key store. * * @param keyPassword Password of key to set. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyPassword(char[] keyPassword) { this.keyPassword = keyPassword.clone(); return this; } /** * 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. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setTrustStoreFile(String trustStoreFile) { this.trustStoreFile = trustStoreFile; this.trustStoreBytes = null; return this; } /** * 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. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setTrustStoreBytes(byte[] trustStoreBytes) { this.trustStoreBytes = trustStoreBytes.clone(); this.trustStoreFile = null; return this; } /** * 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. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyStoreFile(String keyStoreFile) { this.keyStoreFile = keyStoreFile; this.keyStoreBytes = null; return this; } /** * 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. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyStoreBytes(byte[] keyStoreBytes) { this.keyStoreBytes = keyStoreBytes.clone(); this.keyStoreFile = null; return this; } /** * Sets the trust manager factory algorithm. * * @param trustManagerFactoryAlgorithm the trust manager factory algorithm. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setTrustManagerFactoryAlgorithm( String trustManagerFactoryAlgorithm) { this.trustManagerFactoryAlgorithm = trustManagerFactoryAlgorithm; return this; } /** * Sets the key manager factory algorithm. * * @param keyManagerFactoryAlgorithm the key manager factory algorithm. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setKeyManagerFactoryAlgorithm(String keyManagerFactoryAlgorithm) { this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm; return this; } /** * Sets the SSLContext protocol. The default value is TLS if * this is null. * * @param securityProtocol Protocol for {@link javax.net.ssl.SSLContext#getProtocol()}. * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator setSecurityProtocol(String securityProtocol) { this.securityProtocol = securityProtocol; return this; } /** * Validates {@link SslContextConfigurator} configuration. * * @return true if configuration is valid, else * false. */ 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. */ 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()); } InputStream keyStoreInputStream = null; try { if (keyStoreBytes != null) { keyStoreInputStream = new ByteArrayInputStream(keyStoreBytes); } else if (!keyStoreFile.equals("NONE")) { keyStoreInputStream = new FileInputStream(keyStoreFile); } keyStore.load(keyStoreInputStream, keyStorePassword); } finally { try { if (keyStoreInputStream != null) { keyStoreInputStream.close(); } } catch (IOException e) { LOGGER.log(Level.FINEST, "Could not close key store file", e); } } String kmfAlgorithm = keyManagerFactoryAlgorithm; if (kmfAlgorithm == null) { kmfAlgorithm = System.getProperty(KEY_FACTORY_MANAGER_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm()); } KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(kmfAlgorithm); keyManagerFactory.init(keyStore, keyPassword != null ? keyPassword : keyStorePassword); } 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()); } InputStream trustStoreInputStream = null; try { if (trustStoreBytes != null) { trustStoreInputStream = new ByteArrayInputStream(trustStoreBytes); } else if (!trustStoreFile.equals("NONE")) { trustStoreInputStream = new FileInputStream(trustStoreFile); } trustStore.load(trustStoreInputStream, trustStorePassword); } finally { try { if (trustStoreInputStream != null) { trustStoreInputStream.close(); } } catch (IOException e) { LOGGER.log(Level.FINEST, "Could not close key store file", e); } } 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 {@link SSLContext} from current configuration. * * @return created {@link SSLContext}. */ public SSLContext createSSLContext() { 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()); } InputStream keyStoreInputStream = null; try { if (keyStoreBytes != null) { keyStoreInputStream = new ByteArrayInputStream(keyStoreBytes); } else if (!keyStoreFile.equals("NONE")) { keyStoreInputStream = new FileInputStream(keyStoreFile); } keyStore.load(keyStoreInputStream, keyStorePassword); } finally { try { if (keyStoreInputStream != null) { keyStoreInputStream.close(); } } catch (IOException e) { LOGGER.log(Level.FINEST, "Could not close key store file", e); } } String kmfAlgorithm = keyManagerFactoryAlgorithm; if (kmfAlgorithm == null) { kmfAlgorithm = System.getProperty(KEY_FACTORY_MANAGER_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm()); } keyManagerFactory = KeyManagerFactory.getInstance(kmfAlgorithm); keyManagerFactory.init(keyStore, keyPassword != null ? keyPassword : keyStorePassword); } catch (KeyStoreException e) { LOGGER.log(Level.FINE, "Error initializing key store", e); } catch (CertificateException e) { LOGGER.log(Level.FINE, "Key store certificate exception.", e); } catch (UnrecoverableKeyException e) { LOGGER.log(Level.FINE, "Key store unrecoverable exception.", e); } catch (FileNotFoundException e) { LOGGER.log(Level.FINE, "Can't find key store file: " + keyStoreFile, e); } catch (IOException e) { LOGGER.log(Level.FINE, "Error loading key store from file: " + keyStoreFile, e); } catch (NoSuchAlgorithmException e) { LOGGER.log(Level.FINE, "Error initializing key manager factory (no such algorithm)", 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()); } InputStream trustStoreInputStream = null; try { if (trustStoreBytes != null) { trustStoreInputStream = new ByteArrayInputStream(trustStoreBytes); } else if (!trustStoreFile.equals("NONE")) { trustStoreInputStream = new FileInputStream(trustStoreFile); } trustStore.load(trustStoreInputStream, trustStorePassword); } finally { try { if (trustStoreInputStream != null) { trustStoreInputStream.close(); } } catch (IOException e) { LOGGER.log(Level.FINEST, "Could not close trust store file", e); } } 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); } catch (CertificateException e) { LOGGER.log(Level.FINE, "Trust store certificate exception.", e); } catch (FileNotFoundException e) { LOGGER.log(Level.FINE, "Can't find trust store file: " + trustStoreFile, e); } catch (IOException e) { LOGGER.log(Level.FINE, "Error loading trust store from file: " + trustStoreFile, e); } catch (NoSuchAlgorithmException e) { LOGGER.log(Level.FINE, "Error initializing trust manager factory (no such algorithm)", e); } catch (NoSuchProviderException e) { LOGGER.log(Level.FINE, "Error initializing trust store (no such provider)", 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); } catch (NoSuchAlgorithmException e) { LOGGER.log(Level.FINE, "Error initializing algorithm.", e); } return sslContext; } /** * Retrieve settings from (system) properties. * * @param props property map (usually taken from {@link System#getProperties()}). * @return updated {@link SslContextConfigurator} instance. */ public SslContextConfigurator 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) { trustStorePassword = props.getProperty(TRUST_STORE_PASSWORD).toCharArray(); } else { trustStorePassword = null; } if (props.getProperty(KEY_STORE_PASSWORD) != null) { keyStorePassword = props.getProperty(KEY_STORE_PASSWORD).toCharArray(); } else { keyStorePassword = null; } trustStoreFile = props.getProperty(TRUST_STORE_FILE); keyStoreFile = props.getProperty(KEY_STORE_FILE); trustStoreBytes = null; keyStoreBytes = null; securityProtocol = "TLS"; return this; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy