HADOOP-16661. Support TLS 1.3 (#1880)

This commit is contained in:
Wei-Chiu Chuang 2020-03-16 10:56:30 -07:00 committed by GitHub
parent ea688631b0
commit f197f05cff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 13 deletions

View File

@ -2974,6 +2974,7 @@
<description> <description>
The supported SSL protocols. The parameter will only be used from The supported SSL protocols. The parameter will only be used from
DatanodeHttpServer. DatanodeHttpServer.
Starting from Hadoop 3.3.0, TLSv1.3 is supported with Java 11 Runtime.
</description> </description>
</property> </property>

View File

@ -41,6 +41,7 @@
import org.apache.hadoop.security.ssl.KeyStoreTestUtil; import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
import org.apache.hadoop.security.ssl.SSLFactory; import org.apache.hadoop.security.ssl.SSLFactory;
import org.apache.hadoop.test.GenericTestUtils; import org.apache.hadoop.test.GenericTestUtils;
import org.apache.hadoop.util.Shell;
import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.util.StringUtils;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -86,9 +87,11 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5,\t \n" + "SSL_RSA_EXPORT_WITH_RC4_40_MD5,\t \n"
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA," + "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,"
+ "SSL_RSA_WITH_RC4_128_MD5 \t"; + "SSL_RSA_WITH_RC4_128_MD5 \t";
private static final String ONE_ENABLED_CIPHERS = EXCLUDED_CIPHERS private static final String ONE_ENABLED_CIPHERS_TLS1_2 = EXCLUDED_CIPHERS
+ ",TLS_RSA_WITH_AES_128_CBC_SHA"; + ",TLS_RSA_WITH_AES_128_CBC_SHA";
private static final String EXCLUSIVE_ENABLED_CIPHERS private static final String ONE_ENABLED_CIPHERS_TLS1_3 = EXCLUDED_CIPHERS
+ ",TLS_AES_128_GCM_SHA256";
private static final String EXCLUSIVE_ENABLED_CIPHERS_TLS1_2
= "\tTLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, \n" = "\tTLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, \n"
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,"
+ "TLS_RSA_WITH_AES_128_CBC_SHA," + "TLS_RSA_WITH_AES_128_CBC_SHA,"
@ -96,8 +99,12 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
+ "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,"
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\t\n " + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\t\n "
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
private static final String EXCLUSIVE_ENABLED_CIPHERS_TLS1_3 =
EXCLUSIVE_ENABLED_CIPHERS_TLS1_2 + ",TLS_AES_128_GCM_SHA256";
static final String INCLUDED_PROTOCOLS = "SSLv2Hello,TLSv1.1";
static final String INCLUDED_PROTOCOLS = "TLSv1.2";
static final String INCLUDED_PROTOCOLS_JDK11 = "TLSv1.3,TLSv1.2";
@BeforeClass @BeforeClass
public static void setup() throws Exception { public static void setup() throws Exception {
@ -291,22 +298,41 @@ public void testExcludedCiphers() throws Exception {
@Test @Test
public void testIncludedProtocols() throws Exception { public void testIncludedProtocols() throws Exception {
URL url = new URL(baseUrl, SERVLET_PATH_ECHO + "?a=b&c=d"); URL url = new URL(baseUrl, SERVLET_PATH_ECHO + "?a=b&c=d");
String includedProtocols = INCLUDED_PROTOCOLS;
if (Shell.isJavaVersionAtLeast(11)) {
includedProtocols = INCLUDED_PROTOCOLS_JDK11;
}
HttpsURLConnection conn = HttpsURLConnection conn =
getConnectionWithPreferredProtocolSSLSocketFactory(url, getConnectionWithPreferredProtocolSSLSocketFactory(url,
INCLUDED_PROTOCOLS); includedProtocols);
assertFalse("included protocol list is empty", assertFalse("included protocol list is empty",
INCLUDED_PROTOCOLS.isEmpty()); includedProtocols.isEmpty());
readFromConnection(conn); readFromConnection(conn);
PreferredProtocolSSLSocketFactory factory =
(PreferredProtocolSSLSocketFactory)conn.getSSLSocketFactory();
if (Shell.isJavaVersionAtLeast(11)) {
assertEquals("TLSv1.3", factory.getSocket().getSession().getProtocol());
} else {
assertEquals("TLSv1.2", factory.getSocket().getSession().getProtocol());
}
} }
/** Test that verified that additionally included cipher /** Test that verified that additionally included cipher
* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is only available cipher for working * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (TLS 1.2) or
* TLS_AES_128_GCM_SHA256 (TLS 1.3) is only available cipher for working
* TLS connection from client to server disabled for all other common ciphers. * TLS connection from client to server disabled for all other common ciphers.
*/ */
@Test @Test
public void testOneEnabledCiphers() throws Exception { public void testOneEnabledCiphers() throws Exception {
testEnabledCiphers(ONE_ENABLED_CIPHERS); if (Shell.isJavaVersionAtLeast(11)) {
testEnabledCiphers(ONE_ENABLED_CIPHERS_TLS1_3);
} else {
testEnabledCiphers(ONE_ENABLED_CIPHERS_TLS1_2);
}
} }
/** Test verifies that mutually exclusive server's disabled cipher suites and /** Test verifies that mutually exclusive server's disabled cipher suites and
@ -314,7 +340,11 @@ public void testOneEnabledCiphers() throws Exception {
*/ */
@Test @Test
public void testExclusiveEnabledCiphers() throws Exception { public void testExclusiveEnabledCiphers() throws Exception {
testEnabledCiphers(EXCLUSIVE_ENABLED_CIPHERS); if (Shell.isJavaVersionAtLeast(11)) {
testEnabledCiphers(EXCLUSIVE_ENABLED_CIPHERS_TLS1_3);
} else {
testEnabledCiphers(EXCLUSIVE_ENABLED_CIPHERS_TLS1_2);
}
} }
private void testEnabledCiphers(String ciphers) throws private void testEnabledCiphers(String ciphers) throws
@ -405,6 +435,7 @@ private void setEnabledCipherSuites(SSLSocket sslSocket) {
private class PreferredProtocolSSLSocketFactory extends SSLSocketFactory { private class PreferredProtocolSSLSocketFactory extends SSLSocketFactory {
private final SSLSocketFactory delegateSocketFactory; private final SSLSocketFactory delegateSocketFactory;
private final String[] enabledProtocols; private final String[] enabledProtocols;
private SSLSocket sslSocket;
PreferredProtocolSSLSocketFactory(SSLSocketFactory sslSocketFactory, PreferredProtocolSSLSocketFactory(SSLSocketFactory sslSocketFactory,
String[] enabledProtocols) { String[] enabledProtocols) {
@ -416,6 +447,10 @@ private class PreferredProtocolSSLSocketFactory extends SSLSocketFactory {
} }
} }
public SSLSocket getSocket() {
return sslSocket;
}
@Override @Override
public String[] getDefaultCipherSuites() { public String[] getDefaultCipherSuites() {
return delegateSocketFactory.getDefaultCipherSuites(); return delegateSocketFactory.getDefaultCipherSuites();
@ -429,7 +464,7 @@ public String[] getSupportedCipherSuites() {
@Override @Override
public Socket createSocket(Socket socket, String string, int i, boolean bln) public Socket createSocket(Socket socket, String string, int i, boolean bln)
throws IOException { throws IOException {
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket( sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
socket, string, i, bln); socket, string, i, bln);
setEnabledProtocols(sslSocket); setEnabledProtocols(sslSocket);
return sslSocket; return sslSocket;
@ -437,7 +472,7 @@ public Socket createSocket(Socket socket, String string, int i, boolean bln)
@Override @Override
public Socket createSocket(String string, int i) throws IOException { public Socket createSocket(String string, int i) throws IOException {
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket( sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
string, i); string, i);
setEnabledProtocols(sslSocket); setEnabledProtocols(sslSocket);
return sslSocket; return sslSocket;
@ -446,7 +481,7 @@ public Socket createSocket(String string, int i) throws IOException {
@Override @Override
public Socket createSocket(String string, int i, InetAddress ia, int i1) public Socket createSocket(String string, int i, InetAddress ia, int i1)
throws IOException { throws IOException {
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket( sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
string, i, ia, i1); string, i, ia, i1);
setEnabledProtocols(sslSocket); setEnabledProtocols(sslSocket);
return sslSocket; return sslSocket;
@ -454,7 +489,7 @@ public Socket createSocket(String string, int i, InetAddress ia, int i1)
@Override @Override
public Socket createSocket(InetAddress ia, int i) throws IOException { public Socket createSocket(InetAddress ia, int i) throws IOException {
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia, sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia,
i); i);
setEnabledProtocols(sslSocket); setEnabledProtocols(sslSocket);
return sslSocket; return sslSocket;
@ -463,7 +498,7 @@ public Socket createSocket(InetAddress ia, int i) throws IOException {
@Override @Override
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1)
throws IOException { throws IOException {
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia, sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia,
i, ia1, i1); i, ia1, i1);
setEnabledProtocols(sslSocket); setEnabledProtocols(sslSocket);
return sslSocket; return sslSocket;