| /* |
| * Copyright (c) 2011, 2012, 2015 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Teerawat Chaiyakijpichet (No Magic Asia Ltd.) - initial API and implementation |
| * Caspar De Groot (No Magic Asia Ltd.) - initial API and implementation |
| */ |
| package org.eclipse.net4j.tcp.ssl; |
| |
| import org.eclipse.net4j.internal.tcp.TCPAcceptorFactory; |
| import org.eclipse.net4j.internal.tcp.TCPConnectorFactory; |
| import org.eclipse.net4j.internal.tcp.ssl.SSLAcceptorFactory; |
| import org.eclipse.net4j.internal.tcp.ssl.SSLConnectorFactory; |
| import org.eclipse.net4j.internal.tcp.ssl.SSLProperties; |
| import org.eclipse.net4j.tcp.ITCPAcceptor; |
| import org.eclipse.net4j.tcp.ITCPConnector; |
| import org.eclipse.net4j.tcp.TCPUtil; |
| import org.eclipse.net4j.util.container.IManagedContainer; |
| import org.eclipse.net4j.util.io.IOUtil; |
| import org.eclipse.net4j.util.om.OMPlatform; |
| |
| import javax.net.ssl.KeyManager; |
| import javax.net.ssl.KeyManagerFactory; |
| import javax.net.ssl.SSLContext; |
| import javax.net.ssl.SSLEngine; |
| import javax.net.ssl.TrustManager; |
| import javax.net.ssl.TrustManagerFactory; |
| import javax.security.cert.X509Certificate; |
| |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.security.KeyStore; |
| import java.security.KeyStoreException; |
| import java.security.cert.Certificate; |
| import java.util.Enumeration; |
| |
| /** |
| * A utility class with various static factory and convenience methods for SSL transport. |
| * |
| * @author Teerawat Chaiyakijpichet (No Magic Asia Ltd.) |
| * @author Caspar De Groot (No Magic Asia Ltd.) |
| * @since 4.0 |
| */ |
| public class SSLUtil |
| { |
| /** |
| * The variable for SSL Engine |
| */ |
| private static final String PROTOCOL = "TLS"; |
| |
| /** |
| * The X.509 certificate type. |
| */ |
| private static final String X509_CERTIFICATE_TYPE = "X.509"; |
| |
| private static String configFile; |
| |
| private static String keyPathVar; |
| |
| private static String trustPathVar; |
| |
| private static String passPhraseVar; |
| |
| /** |
| * Default value of handshake timeout is 12 times. |
| */ |
| private static int handShakeTimeOutVar = 12; |
| |
| /** |
| * Default value of handshake wait time is 60 milliseconds. |
| */ |
| private static int handShakeWaitTimeVar = 60; |
| |
| public static synchronized void setDefaultSSLConfiguration(String keyPath, String trustPath, String passPhrase) |
| { |
| keyPathVar = keyPath; |
| trustPathVar = trustPath; |
| passPhraseVar = passPhrase; |
| } |
| |
| public static synchronized void setDefaultSSLConfiguration(String keyPath, String trustPath, String passPhrase, |
| int handShakeTimeOut, int handShakeWaitTime) |
| { |
| setDefaultSSLConfiguration(keyPath, trustPath, passPhrase); |
| |
| handShakeTimeOutVar = handShakeTimeOut; |
| handShakeWaitTimeVar = handShakeWaitTime; |
| } |
| |
| public static synchronized void setSSLConfigurationFile(String file) |
| { |
| configFile = file; |
| } |
| |
| public static synchronized void prepareContainer(IManagedContainer container) |
| { |
| TCPUtil.prepareContainer(container); |
| |
| // Prepare SSL |
| container.registerFactory(new SSLAcceptorFactory()); |
| container.registerFactory(new SSLConnectorFactory()); |
| } |
| |
| public static synchronized ITCPAcceptor getAcceptor(IManagedContainer container, String description) |
| { |
| return (ITCPAcceptor)container.getElement(TCPAcceptorFactory.PRODUCT_GROUP, SSLAcceptorFactory.TYPE, description); |
| } |
| |
| public static synchronized ITCPConnector getConnector(IManagedContainer container, String description) |
| { |
| return (ITCPConnector)container.getElement(TCPConnectorFactory.PRODUCT_GROUP, SSLConnectorFactory.TYPE, |
| description); |
| } |
| |
| public static synchronized SSLEngine createSSLEngine(boolean client, String host, int port) throws Exception |
| { |
| // Get values from the system properties. |
| SSLProperties sslProperties = new SSLProperties(); |
| String keyPath = sslProperties.getKeyPath(); |
| String trustPath = sslProperties.getTrustPath(); |
| String passPhrase = sslProperties.getPassPhrase(); |
| |
| if ((keyPath == null || trustPath == null || passPhrase == null) && configFile != null) |
| { |
| sslProperties.load(configFile); |
| } |
| |
| // In case, the system properties does not have the key path property. It will load from local config file. |
| if (keyPath == null) |
| { |
| keyPath = sslProperties.getKeyPath(); |
| if (keyPath == null) |
| { |
| keyPath = keyPathVar; |
| } |
| } |
| |
| // In case, the system properties does not have the trust path property. It will load from local config file. |
| if (trustPath == null) |
| { |
| trustPath = sslProperties.getTrustPath(); |
| if (trustPath == null) |
| { |
| trustPath = trustPathVar; |
| } |
| } |
| |
| // In case, the system properties does not have the passphrase property. It will load from local config file. |
| if (passPhrase == null) |
| { |
| passPhrase = sslProperties.getPassPhrase(); |
| if (passPhrase == null) |
| { |
| passPhrase = passPhraseVar; |
| } |
| } |
| |
| // Handle assign the value of handshake timeout and handshake timewait from local properties or system properties by |
| // giving the value form system properties is high priority. |
| String value = sslProperties.getHandShakeTimeOut(); |
| if (value != null) |
| { |
| handShakeTimeOutVar = Integer.parseInt(value); |
| } |
| |
| value = sslProperties.getHandShakeWaitTime(); |
| if (value != null) |
| { |
| handShakeWaitTimeVar = Integer.parseInt(value); |
| } |
| |
| if (keyPath == null && !client || trustPath == null && client || passPhrase == null) |
| { |
| if (client) |
| { |
| throw new KeyStoreException("Trust Store[" + (trustPath != null) + "] or Pass Phrase[" + (passPhrase != null) |
| + "] is not provided. [false] means it does not exist."); |
| } |
| |
| throw new KeyStoreException("Key Store[" + (keyPath != null) + "] or Pass Phrase[" + (passPhrase != null) |
| + "] is not provided. [false] means it does not exist."); |
| } |
| |
| char[] pass = passPhrase.toCharArray(); |
| |
| KeyManager[] keyManagers = null; |
| TrustManager[] trustManagers = null; |
| String checkValidity = OMPlatform.INSTANCE.getProperty(SSLProperties.CHECK_VALIDITY_CERTIFICATE); |
| boolean checkValidtyStatus = checkValidity == null || Boolean.valueOf(checkValidity); |
| if (client) |
| { |
| // Initial key material(private key) for the client. |
| KeyStore ksTrust = createKeyStore(trustPath, pass, checkValidtyStatus); |
| // Initial the trust manager factory |
| TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
| tmf.init(ksTrust); |
| |
| trustManagers = tmf.getTrustManagers(); |
| } |
| else |
| { |
| // Initial key material (private key) for the server. |
| KeyStore ksKeys = createKeyStore(keyPath, pass, checkValidtyStatus); |
| |
| // Initial the key manager factory. |
| KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); |
| kmf.init(ksKeys, pass); |
| |
| keyManagers = kmf.getKeyManagers(); |
| } |
| |
| SSLContext sslContext = SSLContext.getInstance(PROTOCOL); |
| sslContext.init(keyManagers, trustManagers, null); |
| |
| SSLEngine sslEngine = sslContext.createSSLEngine(host, port); |
| sslEngine.setUseClientMode(client); |
| return sslEngine; |
| } |
| |
| private static KeyStore createKeyStore(String path, char[] password, boolean checkValidity) throws Exception |
| { |
| // Initial key material |
| KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| |
| InputStream in = null; |
| |
| try |
| { |
| in = new URL(path).openStream(); |
| keyStore.load(in, password); |
| |
| if (checkValidity) |
| { |
| // Check validity license key |
| Enumeration<String> aliasesIter = keyStore.aliases(); |
| while (aliasesIter.hasMoreElements()) |
| { |
| String alias = aliasesIter.nextElement(); |
| Certificate cert = keyStore.getCertificate(alias); |
| if (cert.getType() == X509_CERTIFICATE_TYPE) |
| { |
| X509Certificate x509cert = X509Certificate.getInstance(cert.getEncoded()); |
| x509cert.checkValidity(); |
| } |
| } |
| } |
| } |
| finally |
| { |
| IOUtil.close(in); |
| } |
| |
| return keyStore; |
| } |
| |
| public static synchronized int getHandShakeTimeOut() |
| { |
| return handShakeTimeOutVar; |
| } |
| |
| public static synchronized int getHandShakeWaitTime() |
| { |
| return handShakeWaitTimeVar; |
| } |
| } |