Coverage Report - org.owasp.dependencycheck.utils.SSLSocketFactoryEx
 
Classes in this File Line Coverage Branch Coverage Complexity
SSLSocketFactoryEx
0%
0/62
0%
0/6
1.4
 
 1  
 package org.owasp.dependencycheck.utils;
 2  
 
 3  
 import java.io.IOException;
 4  
 import java.net.InetAddress;
 5  
 import java.net.Socket;
 6  
 import java.security.KeyManagementException;
 7  
 import java.security.NoSuchAlgorithmException;
 8  
 import java.security.SecureRandom;
 9  
 import java.util.ArrayList;
 10  
 import java.util.Arrays;
 11  
 import java.util.List;
 12  
 import javax.net.ssl.KeyManager;
 13  
 import javax.net.ssl.SSLContext;
 14  
 import javax.net.ssl.SSLSocket;
 15  
 import javax.net.ssl.SSLSocketFactory;
 16  
 import javax.net.ssl.TrustManager;
 17  
 import org.slf4j.Logger;
 18  
 import org.slf4j.LoggerFactory;
 19  
 
 20  
 /**
 21  
  * This class is used to enable additional ciphers used by the SSL Socket. This
 22  
  * is specifically because the NVD stopped supporting TLS 1.0 and Java 6 and 7
 23  
  * clients by default were unable to connect to download the NVD data feeds.
 24  
  *
 25  
  * The following code was copied from
 26  
  * http://stackoverflow.com/questions/1037590/which-cipher-suites-to-enable-for-ssl-socket/23365536#23365536
 27  
  *
 28  
  * @author <a href="http://stackoverflow.com/users/608639/jww">jww</a>
 29  
  */
 30  
 public class SSLSocketFactoryEx extends SSLSocketFactory {
 31  
 
 32  
     /**
 33  
      * The Logger for use throughout the class.
 34  
      */
 35  0
     private static final Logger LOGGER = LoggerFactory.getLogger(SSLSocketFactoryEx.class);
 36  
 
 37  
     /**
 38  
      * Constructs a new SSLSocketFactory.
 39  
      *
 40  
      * @throws NoSuchAlgorithmException thrown when an algorithm is not
 41  
      * supported
 42  
      * @throws KeyManagementException thrown if initialization fails
 43  
      */
 44  0
     public SSLSocketFactoryEx() throws NoSuchAlgorithmException, KeyManagementException {
 45  0
         initSSLSocketFactoryEx(null, null, null);
 46  0
     }
 47  
 
 48  
     /**
 49  
      * Constructs a new SSLSocketFactory.
 50  
      *
 51  
      * @param km the key manager
 52  
      * @param tm the trust manager
 53  
      * @param random secure random
 54  
      * @throws NoSuchAlgorithmException thrown when an algorithm is not
 55  
      * supported
 56  
      * @throws KeyManagementException thrown if initialization fails
 57  
      */
 58  0
     public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
 59  0
         initSSLSocketFactoryEx(km, tm, random);
 60  0
     }
 61  
 
 62  
     /**
 63  
      * Constructs a new SSLSocketFactory.
 64  
      *
 65  
      * @param ctx the SSL context
 66  
      * @throws NoSuchAlgorithmException thrown when an algorithm is not
 67  
      * supported
 68  
      * @throws KeyManagementException thrown if initialization fails
 69  
      */
 70  0
     public SSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException {
 71  0
         initSSLSocketFactoryEx(ctx);
 72  0
     }
 73  
 
 74  
     /**
 75  
      * Returns the default cipher suites.
 76  
      *
 77  
      * @return the default cipher suites
 78  
      */
 79  
     @Override
 80  
     public String[] getDefaultCipherSuites() {
 81  0
         return sslCtxt.getSocketFactory().getDefaultCipherSuites();
 82  
     }
 83  
 
 84  
     /**
 85  
      * Returns the supported cipher suites.
 86  
      *
 87  
      * @return the supported cipher suites
 88  
      */
 89  
     @Override
 90  
     public String[] getSupportedCipherSuites() {
 91  0
         return sslCtxt.getSocketFactory().getSupportedCipherSuites();
 92  
     }
 93  
 
 94  
     /**
 95  
      * Returns the default protocols.
 96  
      *
 97  
      * @return the default protocols
 98  
      */
 99  
     public String[] getDefaultProtocols() {
 100  0
         return Arrays.copyOf(protocols, protocols.length);
 101  
     }
 102  
 
 103  
     /**
 104  
      * Returns the supported protocols.
 105  
      *
 106  
      * @return the supported protocols
 107  
      */
 108  
     public String[] getSupportedProtocols() {
 109  0
         return Arrays.copyOf(protocols, protocols.length);
 110  
     }
 111  
 
 112  
     /**
 113  
      * Creates an SSL Socket.
 114  
      *
 115  
      * @param s the base socket
 116  
      * @param host the host
 117  
      * @param port the port
 118  
      * @param autoClose if the socket should auto-close
 119  
      * @return the SSL Socket
 120  
      * @throws IOException thrown if the creation fails
 121  
      */
 122  
     @Override
 123  
     public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
 124  0
         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
 125  0
         final SSLSocket ss = (SSLSocket) factory.createSocket(s, host, port, autoClose);
 126  
 
 127  0
         ss.setEnabledProtocols(protocols);
 128  
 
 129  0
         return ss;
 130  
     }
 131  
 
 132  
     /**
 133  
      * Creates a new SSL Socket.
 134  
      *
 135  
      * @param address the address to connect to
 136  
      * @param port the port number
 137  
      * @param localAddress the local address
 138  
      * @param localPort the local port
 139  
      * @return the SSL Socket
 140  
      * @throws IOException thrown if the creation fails
 141  
      */
 142  
     @Override
 143  
     public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
 144  0
         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
 145  0
         final SSLSocket ss = (SSLSocket) factory.createSocket(address, port, localAddress, localPort);
 146  
 
 147  0
         ss.setEnabledProtocols(protocols);
 148  
 
 149  0
         return ss;
 150  
     }
 151  
 
 152  
     /**
 153  
      * Creates a new SSL Socket.
 154  
      *
 155  
      * @param host the host to connect to
 156  
      * @param port the port to connect to
 157  
      * @param localHost the local host
 158  
      * @param localPort the local port
 159  
      * @return the SSL Socket
 160  
      * @throws IOException thrown if the creation fails
 161  
      */
 162  
     @Override
 163  
     public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
 164  0
         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
 165  0
         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port, localHost, localPort);
 166  
 
 167  0
         ss.setEnabledProtocols(protocols);
 168  
 
 169  0
         return ss;
 170  
     }
 171  
 
 172  
     /**
 173  
      * Creates a new SSL Socket.
 174  
      *
 175  
      * @param host the host to connect to
 176  
      * @param port the port to connect to
 177  
      * @return the SSL Socket
 178  
      * @throws IOException thrown if the creation fails
 179  
      */
 180  
     @Override
 181  
     public Socket createSocket(InetAddress host, int port) throws IOException {
 182  0
         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
 183  0
         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
 184  
 
 185  0
         ss.setEnabledProtocols(protocols);
 186  
 
 187  0
         return ss;
 188  
     }
 189  
 
 190  
     /**
 191  
      * Creates a new SSL Socket.
 192  
      *
 193  
      * @param host the host to connect to
 194  
      * @param port the port to connect to
 195  
      * @return the SSL Socket
 196  
      * @throws IOException thrown if the creation fails
 197  
      */
 198  
     @Override
 199  
     public Socket createSocket(String host, int port) throws IOException {
 200  0
         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
 201  0
         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
 202  
 
 203  0
         ss.setEnabledProtocols(protocols);
 204  
 
 205  0
         return ss;
 206  
     }
 207  
 
 208  
     /**
 209  
      * Initializes the SSL Socket Factory Extension.
 210  
      *
 211  
      * @param km the key managers
 212  
      * @param tm the trust managers
 213  
      * @param random the secure random number generator
 214  
      * @throws NoSuchAlgorithmException thrown when an algorithm is not
 215  
      * supported
 216  
      * @throws KeyManagementException thrown if initialization fails
 217  
      */
 218  
     private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)
 219  
             throws NoSuchAlgorithmException, KeyManagementException {
 220  0
         sslCtxt = SSLContext.getInstance("TLS");
 221  0
         sslCtxt.init(km, tm, random);
 222  
 
 223  0
         protocols = getProtocolList();
 224  0
     }
 225  
 
 226  
     /**
 227  
      * Initializes the SSL Socket Factory Extension.
 228  
      *
 229  
      * @param ctx the SSL context
 230  
      * @throws NoSuchAlgorithmException thrown when an algorithm is not
 231  
      * supported
 232  
      * @throws KeyManagementException thrown if initialization fails
 233  
      */
 234  
     private void initSSLSocketFactoryEx(SSLContext ctx)
 235  
             throws NoSuchAlgorithmException, KeyManagementException {
 236  0
         sslCtxt = ctx;
 237  0
         protocols = getProtocolList();
 238  0
     }
 239  
 
 240  
     /**
 241  
      * Returns the protocol list.
 242  
      *
 243  
      * @return the protocol list
 244  
      */
 245  
     protected String[] getProtocolList() {
 246  0
         final String[] preferredProtocols = {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};
 247  0
         String[] availableProtocols = null;
 248  
 
 249  0
         SSLSocket socket = null;
 250  
 
 251  
         try {
 252  0
             final SSLSocketFactory factory = sslCtxt.getSocketFactory();
 253  0
             socket = (SSLSocket) factory.createSocket();
 254  
 
 255  0
             availableProtocols = socket.getSupportedProtocols();
 256  0
             Arrays.sort(availableProtocols);
 257  0
         } catch (Exception ex) {
 258  0
             LOGGER.debug("Error getting protocol list, using TLSv1", ex);
 259  0
             return new String[]{"TLSv1"};
 260  
         } finally {
 261  0
             if (socket != null) {
 262  
                 try {
 263  0
                     socket.close();
 264  0
                 } catch (IOException ex) {
 265  0
                     LOGGER.trace("Error closing socket", ex);
 266  0
                 }
 267  
             }
 268  
         }
 269  
 
 270  0
         final List<String> aa = new ArrayList<String>();
 271  0
         for (String preferredProtocol : preferredProtocols) {
 272  0
             final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
 273  0
             if (idx >= 0) {
 274  0
                 aa.add(preferredProtocol);
 275  
             }
 276  
         }
 277  
 
 278  0
         return aa.toArray(new String[0]);
 279  
     }
 280  
 
 281  
     /**
 282  
      * The SSL context.
 283  
      */
 284  
     private SSLContext sslCtxt;
 285  
     /**
 286  
      * The protocols.
 287  
      */
 288  
     private String[] protocols;
 289  
 }