static { String[] enabledCiphers = null; String[] enabledProtocols = null; try { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, null, new SecureRandom()); SSLSocketFactory sf = sslContext.getSocketFactory(); SSLSocket sock = (SSLSocket) sf.createSocket(); enabledCiphers = sock.getEnabledCipherSuites(); enabledProtocols = sock.getEnabledProtocols(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (KeyManagementException kme) { kme.printStackTrace(); } catch (NoSuchAlgorithmException nsae) { nsae.printStackTrace(); } ENABLED_CIPHERS = (enabledCiphers == null) ? null : reorder(enabledCiphers, ORDERED_KNOWN_CIPHERS, BLACKLISTED_CIPHERS); ENABLED_PROTOCOLS = (enabledProtocols == null) ? null : reorder(enabledProtocols, ORDERED_KNOWN_PROTOCOLS, null); }
/** Inits supported and enabled protocol versions. */ private void initSupportedProtocols() { try { SSLSocket ssl_socket = (SSLSocket) ssl_factory.createSocket(); if (supported_protocols == null) supported_protocols = ssl_socket.getSupportedProtocols(); if (enabled_protocols == null) enabled_protocols = ssl_socket.getEnabledProtocols(); ssl_socket.close(); } catch (Exception e) { e.printStackTrace(); } }
/** * Returns a copy of this that omits cipher suites and TLS versions not enabled by {@code * sslSocket}. */ private ConnectionSpec supportedSpec(SSLSocket sslSocket, boolean isFallback) { String[] cipherSuitesIntersection = cipherSuites != null ? Util.intersect(String.class, cipherSuites, sslSocket.getEnabledCipherSuites()) : sslSocket.getEnabledCipherSuites(); String[] tlsVersionsIntersection = tlsVersions != null ? Util.intersect(String.class, tlsVersions, sslSocket.getEnabledProtocols()) : sslSocket.getEnabledProtocols(); // In accordance with https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00 // the SCSV cipher is added to signal that a protocol fallback has taken place. if (isFallback && contains(sslSocket.getSupportedCipherSuites(), "TLS_FALLBACK_SCSV")) { cipherSuitesIntersection = concat(cipherSuitesIntersection, "TLS_FALLBACK_SCSV"); } return new Builder(this) .cipherSuites(cipherSuitesIntersection) .tlsVersions(tlsVersionsIntersection) .build(); }
/** * Returns {@code true} if the socket, as currently configured, supports this connection spec. In * order for a socket to be compatible the enabled cipher suites and protocols must intersect. * * <p>For cipher suites, at least one of the {@link #cipherSuites() required cipher suites} must * match the socket's enabled cipher suites. If there are no required cipher suites the socket * must have at least one cipher suite enabled. * * <p>For protocols, at least one of the {@link #tlsVersions() required protocols} must match the * socket's enabled protocols. */ public boolean isCompatible(SSLSocket socket) { if (!tls) { return false; } if (tlsVersions != null && !nonEmptyIntersection(tlsVersions, socket.getEnabledProtocols())) { return false; } if (cipherSuites != null && !nonEmptyIntersection(cipherSuites, socket.getEnabledCipherSuites())) { return false; } return true; }
/** {@inheritDoc} Used to enforce the preferred TLS protocol during SSL handshake. */ @Override protected final void prepareSocket(final SSLSocket socket) { String[] supported = socket.getSupportedProtocols(); String[] enabled = socket.getEnabledProtocols(); if (LOG.isDebugEnabled()) { LOG.debug( "socket.getSupportedProtocols(): " + Arrays.toString(supported) + ", socket.getEnabledProtocols(): " + Arrays.toString(enabled)); } List<String> target = new ArrayList<String>(); if (supported != null) { // Append the preferred protocols in descending order of preference // but only do so if the protocols are supported TLSProtocol[] values = TLSProtocol.values(); for (int i = 0; i < values.length; i++) { final String pname = values[i].getProtocolName(); if (existsIn(pname, supported)) { target.add(pname); } } } if (enabled != null) { // Append the rest of the already enabled protocols to the end // if not already included in the list for (String pname : enabled) { if (!target.contains(pname)) { target.add(pname); } } } if (target.size() > 0) { String[] enabling = target.toArray(new String[target.size()]); socket.setEnabledProtocols(enabling); if (LOG.isDebugEnabled()) { LOG.debug("TLS protocol enabled for SSL handshake: " + Arrays.toString(enabling)); } } }
@Test public void tls_defaultCiphers_withFallbackIndicator() throws Exception { ConnectionSpec tlsSpec = new ConnectionSpec.Builder(true) .tlsVersions(TlsVersion.TLS_1_2) .supportsTlsExtensions(false) .build(); SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); socket.setEnabledCipherSuites( new String[] { CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName, }); socket.setEnabledProtocols( new String[] { TlsVersion.TLS_1_2.javaName, TlsVersion.TLS_1_1.javaName, }); Route route = new Route( HTTPS_ADDRESS, PROXY, INET_SOCKET_ADDRESS, tlsSpec, true /* shouldSendTlsFallbackIndicator */); tlsSpec.apply(socket, route); assertEquals(createSet(TlsVersion.TLS_1_2.javaName), createSet(socket.getEnabledProtocols())); Set<String> expectedCipherSet = createSet( CipherSuite.TLS_RSA_WITH_RC4_128_MD5.javaName, CipherSuite.TLS_RSA_WITH_RC4_128_SHA.javaName); if (Arrays.asList(socket.getSupportedCipherSuites()).contains("TLS_FALLBACK_SCSV")) { expectedCipherSet.add("TLS_FALLBACK_SCSV"); } assertEquals(expectedCipherSet, expectedCipherSet); }
public String[] getEnabledProtocols() { return delegate.getEnabledProtocols(); }
@Override public Socket createSocket(final String host, final int port) throws IOException { SSLSocket socket = (SSLSocket) ssf.createSocket(host, port); socket.setEnabledProtocols(SSLUtils.getSupportedProtocols(socket.getEnabledProtocols())); return socket; }
public void testSecureSocketProtocolsFilter() throws Exception { SSLContext controlContext = SSLContext.getInstance("TLS"); controlContext.init(null, null, null); SSLEngine controlEngine = controlContext.createSSLEngine(); SSLSocket controlSocket = (SSLSocket) controlContext.getSocketFactory().createSocket(); SSLServerSocket controlServerSocket = (SSLServerSocket) controlContext.getServerSocketFactory().createServerSocket(); // default SSLContextParameters scp = new SSLContextParameters(); SSLContext context = scp.createSSLContext(); SSLEngine engine = context.createSSLEngine(); SSLSocket socket = (SSLSocket) context.getSocketFactory().createSocket(); SSLServerSocket serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue(Arrays.equals(controlEngine.getEnabledProtocols(), engine.getEnabledProtocols())); assertTrue(Arrays.equals(controlSocket.getEnabledProtocols(), socket.getEnabledProtocols())); checkProtocols(controlServerSocket.getEnabledProtocols(), serverSocket.getEnabledProtocols()); // empty filter FilterParameters filter = new FilterParameters(); scp.setSecureSocketProtocolsFilter(filter); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertEquals(0, engine.getEnabledProtocols().length); assertEquals(0, socket.getEnabledProtocols().length); assertEquals(0, serverSocket.getEnabledProtocols().length); // explicit filter filter.getInclude().add(".*"); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue(Arrays.equals(controlEngine.getEnabledProtocols(), engine.getEnabledProtocols())); assertTrue(Arrays.equals(controlSocket.getEnabledProtocols(), socket.getEnabledProtocols())); checkProtocols(controlServerSocket.getEnabledProtocols(), serverSocket.getEnabledProtocols()); // explicit filter with excludes (excludes overrides) filter.getExclude().add(".*"); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertEquals(0, engine.getEnabledProtocols().length); assertEquals(0, socket.getEnabledProtocols().length); assertEquals(0, serverSocket.getEnabledProtocols().length); // explicit filter single include filter.getInclude().clear(); filter.getExclude().clear(); filter.getInclude().add("TLS.*"); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); // not all platforms/JDKs have these cipher suites if (!isPlatform("aix")) { assertTrue(engine.getEnabledProtocols().length >= 1); assertStartsWith(engine.getEnabledProtocols(), "TLS"); assertTrue(socket.getEnabledProtocols().length >= 1); assertStartsWith(socket.getEnabledProtocols(), "TLS"); assertTrue(socket.getEnabledProtocols().length >= 1); assertStartsWith(serverSocket.getEnabledProtocols(), "TLS"); } }
public void testSecureSocketProtocols() throws Exception { SSLContext controlContext = SSLContext.getInstance("TLS"); controlContext.init(null, null, null); SSLEngine controlEngine = controlContext.createSSLEngine(); SSLSocket controlSocket = (SSLSocket) controlContext.getSocketFactory().createSocket(); SSLServerSocket controlServerSocket = (SSLServerSocket) controlContext.getServerSocketFactory().createServerSocket(); // default SSLContextParameters scp = new SSLContextParameters(); SSLContext context = scp.createSSLContext(); SSLEngine engine = context.createSSLEngine(); SSLSocket socket = (SSLSocket) context.getSocketFactory().createSocket(); SSLServerSocket serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue(Arrays.equals(controlEngine.getEnabledProtocols(), engine.getEnabledProtocols())); assertTrue(Arrays.equals(controlSocket.getEnabledProtocols(), socket.getEnabledProtocols())); checkProtocols(controlServerSocket.getEnabledProtocols(), serverSocket.getEnabledProtocols()); // empty sspp SecureSocketProtocolsParameters sspp = new SecureSocketProtocolsParameters(); scp.setSecureSocketProtocols(sspp); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertEquals(0, engine.getEnabledProtocols().length); assertEquals(0, socket.getEnabledProtocols().length); assertEquals(0, serverSocket.getEnabledProtocols().length); // explicit sspp sspp.getSecureSocketProtocol().add("TLSv1"); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertEquals(1, engine.getEnabledProtocols().length); assertEquals("TLSv1", engine.getEnabledProtocols()[0]); assertEquals(1, socket.getEnabledProtocols().length); assertEquals("TLSv1", socket.getEnabledProtocols()[0]); assertEquals(1, serverSocket.getEnabledProtocols().length); assertEquals("TLSv1", serverSocket.getEnabledProtocols()[0]); // explicit sspp overrides filter FilterParameters filter = new FilterParameters(); filter.getInclude().add(".*"); scp.setSecureSocketProtocolsFilter(filter); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); // not all platforms/JDKs have these cipher suites if (!isPlatform("aix")) { assertEquals(1, engine.getEnabledProtocols().length); assertEquals("TLSv1", engine.getEnabledProtocols()[0]); assertEquals(1, socket.getEnabledProtocols().length); assertEquals("TLSv1", socket.getEnabledProtocols()[0]); assertEquals(1, socket.getEnabledProtocols().length); assertEquals("TLSv1", serverSocket.getEnabledProtocols()[0]); } }
public void testClientParameters() throws Exception { SSLContext controlContext = SSLContext.getInstance("TLS"); controlContext.init(null, null, null); SSLEngine controlEngine = controlContext.createSSLEngine(); SSLSocket controlSocket = (SSLSocket) controlContext.getSocketFactory().createSocket(); SSLServerSocket controlServerSocket = (SSLServerSocket) controlContext.getServerSocketFactory().createServerSocket(); SSLContextParameters scp = new SSLContextParameters(); SSLContextClientParameters sccp = new SSLContextClientParameters(); scp.setClientParameters(sccp); SSLContext context = scp.createSSLContext(); SSLEngine engine = context.createSSLEngine(); SSLSocket socket = (SSLSocket) context.getSocketFactory().createSocket(); SSLServerSocket serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue( Arrays.equals(controlEngine.getEnabledCipherSuites(), engine.getEnabledCipherSuites())); assertTrue( Arrays.equals(controlSocket.getEnabledCipherSuites(), socket.getEnabledCipherSuites())); assertTrue( Arrays.equals( this.getDefaultCipherSuiteIncludes(controlServerSocket.getSupportedCipherSuites()), serverSocket.getEnabledCipherSuites())); // No csp or filter on client params passes through shared config scp.setCipherSuites(new CipherSuitesParameters()); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertEquals(0, socket.getEnabledCipherSuites().length); // Csp on client params scp.setCipherSuites(null); CipherSuitesParameters csp = new CipherSuitesParameters(); sccp.setCipherSuites(csp); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue( Arrays.equals(controlEngine.getEnabledCipherSuites(), engine.getEnabledCipherSuites())); assertEquals(0, socket.getEnabledCipherSuites().length); assertTrue( Arrays.equals( this.getDefaultCipherSuiteIncludes(controlServerSocket.getSupportedCipherSuites()), serverSocket.getEnabledCipherSuites())); // Cipher suites filter on client params FilterParameters filter = new FilterParameters(); filter.getExclude().add(".*"); sccp.setCipherSuites(null); sccp.setCipherSuitesFilter(filter); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue( Arrays.equals(controlEngine.getEnabledCipherSuites(), engine.getEnabledCipherSuites())); assertEquals(0, socket.getEnabledCipherSuites().length); assertTrue( Arrays.equals( this.getDefaultCipherSuiteIncludes(controlServerSocket.getSupportedCipherSuites()), serverSocket.getEnabledCipherSuites())); // Csp on client overrides cipher suites filter on client filter.getInclude().add(".*"); filter.getExclude().clear(); sccp.setCipherSuites(csp); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue( Arrays.equals(controlEngine.getEnabledCipherSuites(), engine.getEnabledCipherSuites())); assertEquals(0, socket.getEnabledCipherSuites().length); assertTrue( Arrays.equals( this.getDefaultCipherSuiteIncludes(controlServerSocket.getSupportedCipherSuites()), serverSocket.getEnabledCipherSuites())); // Sspp on client params SecureSocketProtocolsParameters sspp = new SecureSocketProtocolsParameters(); sccp.setSecureSocketProtocols(sspp); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue(Arrays.equals(controlEngine.getEnabledProtocols(), engine.getEnabledProtocols())); assertEquals(0, socket.getEnabledProtocols().length); checkProtocols(controlServerSocket.getEnabledProtocols(), serverSocket.getEnabledProtocols()); // Secure socket protocols filter on client params filter = new FilterParameters(); filter.getExclude().add(".*"); sccp.setSecureSocketProtocols(null); sccp.setSecureSocketProtocolsFilter(filter); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue(Arrays.equals(controlEngine.getEnabledProtocols(), engine.getEnabledProtocols())); assertEquals(0, socket.getEnabledProtocols().length); checkProtocols(controlServerSocket.getEnabledProtocols(), serverSocket.getEnabledProtocols()); // Sspp on client params overrides secure socket protocols filter on client filter.getInclude().add(".*"); filter.getExclude().clear(); sccp.setSecureSocketProtocols(sspp); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertTrue(Arrays.equals(controlEngine.getEnabledProtocols(), engine.getEnabledProtocols())); assertEquals(0, socket.getEnabledProtocols().length); checkProtocols(controlServerSocket.getEnabledProtocols(), serverSocket.getEnabledProtocols()); // Client session timeout only affects client session configuration sccp.setSessionTimeout("12345"); context = scp.createSSLContext(); engine = context.createSSLEngine(); socket = (SSLSocket) context.getSocketFactory().createSocket(); serverSocket = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(); assertEquals( controlContext.getServerSessionContext().getSessionTimeout(), context.getServerSessionContext().getSessionTimeout()); assertEquals(12345, context.getClientSessionContext().getSessionTimeout()); }