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

org.owasp.dependencycheck.utils.SSLSocketFactoryEx Maven / Gradle / Ivy

Go to download

dependency-check-utils is a collection of common utility classes used within dependency-check that might be useful in other projects.

There is a newer version: 11.1.1
Show newest version
package org.owasp.dependencycheck.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.apache.commons.lang3.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * TODO - is this class needed anymore as we do not support Java 6 and 7.
 *
 * This class is used to enable additional ciphers used by the SSL Socket. This
 * is specifically because the NVD stopped supporting TLS 1.0 and Java 6 and 7
 * clients by default were unable to connect to download the NVD data feeds.
 * 

* The following code was copied from * http://stackoverflow.com/questions/1037590/which-cipher-suites-to-enable-for-ssl-socket/23365536#23365536 * * @author jww * @version $Id: $Id */ public class SSLSocketFactoryEx extends SSLSocketFactory { /** * The Logger for use throughout the class. */ private static final Logger LOGGER = LoggerFactory.getLogger(SSLSocketFactoryEx.class); /** * The SSL context. */ private SSLContext sslCtxt; /** * The protocols. */ private String[] protocols; /** * The configured settings. */ private final Settings settings; /** * Simple boolean flag to prevent logging the protocols repeatedly. */ private static boolean protocolsLogged = false; /** * Constructs a new SSLSocketFactory. * * @param settings reference to the configured settings * @throws java.security.NoSuchAlgorithmException thrown when an algorithm * is not supported * @throws java.security.KeyManagementException thrown if initialization * fails */ public SSLSocketFactoryEx(Settings settings) throws NoSuchAlgorithmException, KeyManagementException { this.settings = settings; final KeyManager[] km = getKeyManagers(); final TrustManager[] tm = getTrustManagers(); initSSLSocketFactoryEx(km, tm, null); } /** * Constructs a new SSLSocketFactory. * * @param km the key manager * @param tm the trust manager * @param random secure random * @param settings reference to the configured settings * @throws java.security.NoSuchAlgorithmException thrown when an algorithm * is not supported * @throws java.security.KeyManagementException thrown if initialization * fails */ public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random, Settings settings) throws NoSuchAlgorithmException, KeyManagementException { this.settings = settings; initSSLSocketFactoryEx(km, tm, random); } /** * Constructs a new SSLSocketFactory. * * @param ctx the SSL context * @param settings reference to the configured settings * @throws java.security.NoSuchAlgorithmException thrown when an algorithm * is not supported * @throws java.security.KeyManagementException thrown if initialization * fails */ public SSLSocketFactoryEx(SSLContext ctx, Settings settings) throws NoSuchAlgorithmException, KeyManagementException { this.settings = settings; initSSLSocketFactoryEx(ctx); } /** * {@inheritDoc} *

* Returns the default cipher suites. */ @Override public String[] getDefaultCipherSuites() { return sslCtxt.getSocketFactory().getDefaultCipherSuites(); } /** * {@inheritDoc} *

* Returns the supported cipher suites. */ @Override public String[] getSupportedCipherSuites() { return sslCtxt.getSocketFactory().getSupportedCipherSuites(); } /** * Returns the default protocols. * * @return the default protocols */ public String[] getDefaultProtocols() { return Arrays.copyOf(protocols, protocols.length); } /** * Returns the supported protocols. * * @return the supported protocols */ public String[] getSupportedProtocols() { return Arrays.copyOf(protocols, protocols.length); } /** * {@inheritDoc} *

* Creates an SSL Socket. */ @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { final SSLSocketFactory factory = sslCtxt.getSocketFactory(); final SSLSocket ss = (SSLSocket) factory.createSocket(s, host, port, autoClose); ss.setEnabledProtocols(protocols); return ss; } /** * {@inheritDoc} *

* Creates a new SSL Socket. */ @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { final SSLSocketFactory factory = sslCtxt.getSocketFactory(); final SSLSocket ss = (SSLSocket) factory.createSocket(address, port, localAddress, localPort); ss.setEnabledProtocols(protocols); return ss; } /** * {@inheritDoc} *

* Creates a new SSL Socket. */ @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { final SSLSocketFactory factory = sslCtxt.getSocketFactory(); final SSLSocket ss = (SSLSocket) factory.createSocket(host, port, localHost, localPort); ss.setEnabledProtocols(protocols); return ss; } /** * {@inheritDoc} *

* Creates a new SSL Socket. */ @Override public Socket createSocket(InetAddress host, int port) throws IOException { final SSLSocketFactory factory = sslCtxt.getSocketFactory(); final SSLSocket ss = (SSLSocket) factory.createSocket(host, port); ss.setEnabledProtocols(protocols); return ss; } /** * {@inheritDoc} *

* Creates a new SSL Socket. */ @Override public Socket createSocket(String host, int port) throws IOException { final SSLSocketFactory factory = sslCtxt.getSocketFactory(); final SSLSocket ss = (SSLSocket) factory.createSocket(host, port); ss.setEnabledProtocols(protocols); return ss; } /** * Initializes the SSL Socket Factory Extension. * * @param km the key managers * @param tm the trust managers * @param random the secure random number generator * @throws NoSuchAlgorithmException thrown when an algorithm is not * supported * @throws KeyManagementException thrown if initialization fails */ private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException { sslCtxt = SSLContext.getInstance("TLS"); sslCtxt.init(km, tm, random); protocols = getProtocolList(); } /** * Initializes the SSL Socket Factory Extension. * * @param ctx the SSL context * @throws NoSuchAlgorithmException thrown when an algorithm is not * supported * @throws KeyManagementException thrown if initialization fails */ private void initSSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException { sslCtxt = ctx; protocols = getProtocolList(); } /** * Returns the protocol list. * * @return the protocol list */ @SuppressWarnings("StringSplitter") protected String[] getProtocolList() { SSLSocket socket = null; final String[] availableProtocols; final String[] preferredProtocols = settings.getString( Settings.KEYS.DOWNLOADER_TLS_PROTOCOL_LIST, "TLSv1.1,TLSv1.2,TLSv1.3") .split(","); try { final SSLSocketFactory factory = sslCtxt.getSocketFactory(); socket = (SSLSocket) factory.createSocket(); availableProtocols = socket.getSupportedProtocols(); Arrays.sort(availableProtocols); if (LOGGER.isDebugEnabled() && !protocolsLogged) { protocolsLogged = true; LOGGER.debug("Available Protocols:"); for (String p : availableProtocols) { LOGGER.debug(p); } } } catch (Exception ex) { LOGGER.debug("Error getting protocol list, using TLSv1.1-1.3", ex); return new String[]{"TLSv1.1", "TLSv1.2", "TLSv1.3"}; } finally { if (socket != null) { try { socket.close(); } catch (IOException ex) { LOGGER.trace("Error closing socket", ex); } } } final List aa = new ArrayList<>(); for (String preferredProtocol : preferredProtocols) { final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol); if (idx >= 0) { aa.add(preferredProtocol); } } return aa.toArray(new String[0]); } private KeyManager[] getKeyManagers() { KeyManager[] km = null; final String ksPath = System.getProperty("javax.net.ssl.keyStore"); final String ksType = System.getProperty("javax.net.ssl.keyStoreType"); final String ksPass = System.getProperty("javax.net.ssl.keyStorePassword"); if (!StringUtils.isAnyEmpty(ksPath, ksType, ksPass)) { try (FileInputStream fis = new FileInputStream(ksPath)) { final KeyStore ks = KeyStore.getInstance(ksType); ks.load(fis, ksPass.toCharArray()); final KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, ksPass.toCharArray()); km = kmf.getKeyManagers(); } catch (KeyStoreException | IOException | CertificateException | UnrecoverableKeyException | NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } } return km; } private TrustManager[] getTrustManagers() { TrustManager[] tm = null; final String ksType = System.getProperty("javax.net.ssl.keyStoreType"); final String tsPath = System.getProperty("javax.net.ssl.trustStore"); final String tsPass = System.getProperty("javax.net.ssl.trustStorePassword"); if (!StringUtils.isAnyEmpty(tsPath, ksType, tsPass)) { try (FileInputStream fis = new FileInputStream(tsPath)) { final KeyStore ts = KeyStore.getInstance(ksType); ts.load(fis, tsPass.toCharArray()); final TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ts); tm = tmf.getTrustManagers(); } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } } return tm; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy