Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
18a1bca
KAFKA-9320: Initial commit.
nizhikov May 19, 2020
1076e51
KAFKA-9320: Initial commit.
nizhikov May 19, 2020
7dec0d6
KAFKA-9320: Test added
nizhikov May 20, 2020
f6afbb9
KAFKA-9320: Test added
nizhikov May 20, 2020
142e487
KAFKA-9320: Test added
nizhikov May 20, 2020
ac448d1
KAFKA-9320: Test added
nizhikov May 20, 2020
e1287c6
KAFKA-9320: SslVersionsTransportLayerTest added.
nizhikov May 25, 2020
b310e60
KAFKA-9320: Tests fix.
nizhikov May 26, 2020
518eb77
KAFKA-9320: system tests updated.
nizhikov May 26, 2020
5b5f37e
KAFKA-9320: system tests updated.
nizhikov May 27, 2020
c7000d9
KAFKA-9320: system tests updated.
nizhikov May 27, 2020
862f7ae
KAFKA-9320: code review fixes
nizhikov May 28, 2020
d1dd114
Merge branch 'trunk' into KAFKA-9320
nizhikov May 28, 2020
5578192
KAFKA-9320: code review fixes
nizhikov May 28, 2020
c1847e7
KAFKA-9320: code review fixes
nizhikov May 28, 2020
c901254
KAFKA-9320: code review fixes
nizhikov May 28, 2020
61cd6c5
KAFKA-9320: code review fixes
nizhikov May 28, 2020
fd1f48b
KAFKA-9320: code review fixes
nizhikov May 29, 2020
e1a2fe4
Merge branch 'trunk' into KAFKA-9320
nizhikov May 29, 2020
4e7eaec
KAFKA-9320: test fix.
nizhikov May 29, 2020
c756720
KAFKA-9320: code review fixes.
nizhikov May 29, 2020
a231e2f
KAFKA-9320: code review fixes.
nizhikov May 29, 2020
7ab2f39
KAFKA-9320: code review fixes.
nizhikov Jun 1, 2020
17612ac
KAFKA-9320: code review fixes.
nizhikov Jun 1, 2020
ebb20e1
KAFKA-9320: revert test changes.
nizhikov Jun 1, 2020
1b55587
KAFKA-9320: fix test duration.
nizhikov Jun 1, 2020
9da1c21
KAFKA-9320: unused code removed.
nizhikov Jun 1, 2020
3e6c445
KAFKA-9320: code review fixes.
nizhikov Jun 1, 2020
14bf85a
KAFKA-9320: TLSv1.3 vs TLSv1.2 explanation comments.
nizhikov Jun 2, 2020
67f0ef9
Merge branch 'trunk' into KAFKA-9320
nizhikov Jun 2, 2020
869e342
KAFKA-9320: code review fixes.
nizhikov Jun 2, 2020
ca81fcd
KAFKA-9320: code review fixes.
nizhikov Jun 2, 2020
6a82441
KAFKA-9320: SSL_PROTOCOL_DOC updated.
nizhikov Jun 2, 2020
ce7505f
Documentation tweaks
ijuma Jun 2, 2020
b293578
Merge branch 'trunk' into KAFKA-9320
nizhikov Jun 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;

/**
* Tests for the SSL transport layer. These use a test harness that runs a simple socket server that echos back responses.
Expand Down Expand Up @@ -578,30 +577,6 @@ public void testTLSDefaults() throws Exception {
server.verifyAuthenticationMetrics(1, 2);
}

@Test
public void testUnsupportedCipher() throws Exception {
String[] cipherSuites;
if (Java.IS_JAVA11_COMPATIBLE) {
cipherSuites = new String[] {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_AES_256_GCM_SHA384"};
} else {
cipherSuites = new String[] {"TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384"};
}

sslServerConfigs = serverCertStores.getTrustingConfig(clientCertStores);
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuites[0]));
sslClientConfigs = clientCertStores.getTrustingConfig(serverCertStores);
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuites[1]));

server = createEchoServer(SecurityProtocol.SSL);
createSelector(sslClientConfigs);

checkAuthentiationFailed("1", "TLSv1.1");
server.verifyAuthenticationMetrics(0, 1);

checkAuthentiationFailed("2", "TLSv1");
server.verifyAuthenticationMetrics(0, 2);
}

/** Checks connection failed using the specified {@code tlsVersion}. */
private void checkAuthentiationFailed(String node, String tlsVersion) throws IOException {
sslClientConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(tlsVersion));
Expand All @@ -626,104 +601,11 @@ public void testUnsupportedTLSVersion() throws Exception {
server.verifyAuthenticationMetrics(0, 1);
}

/**
* Tests that connections fails if TLSv1.3 enabled but cipher suite suitable only for TLSv1.2 used.
*/
@Test
public void testCiphersSuiteForTls12FailsForTls13() throws Exception {
assumeTrue(Java.IS_JAVA11_COMPATIBLE);

String cipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";

sslServerConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, "TLSv1.3");
sslServerConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Collections.singletonList("TLSv1.3"));
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
server = createEchoServer(SecurityProtocol.SSL);

sslClientConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Collections.singletonList("TLSv1.3"));
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));

checkAuthentiationFailed("0", "TLSv1.3");
server.verifyAuthenticationMetrics(0, 1);
}

/**
* Tests that connections can't be made if server uses TLSv1.2 with custom cipher suite and client uses TLSv1.3.
*/
@Test
public void testCiphersSuiteFailForServerTls12ClientTls13() throws Exception {
assumeTrue(Java.IS_JAVA11_COMPATIBLE);

String tls12CipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
String tls13CipherSuite = "TLS_AES_128_GCM_SHA256";

sslServerConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, "TLSv1.2");
sslServerConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Collections.singletonList("TLSv1.2"));
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(tls12CipherSuite));
server = createEchoServer(SecurityProtocol.SSL);

sslClientConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, "TLSv1.3");
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(tls13CipherSuite));

checkAuthentiationFailed("0", "TLSv1.3");
server.verifyAuthenticationMetrics(0, 1);
}

/**
* Tests that connections can be made with TLSv1.3 cipher suite.
*/
@Test
public void testCiphersSuiteForTls13() throws Exception {
assumeTrue(Java.IS_JAVA11_COMPATIBLE);

String node = "0";
String cipherSuite = "TLS_AES_128_GCM_SHA256";

sslServerConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, SslConfigs.DEFAULT_SSL_PROTOCOL);
sslServerConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split(",")));
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
server = createEchoServer(SecurityProtocol.SSL);

sslClientConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, SslConfigs.DEFAULT_SSL_PROTOCOL);
sslClientConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split(",")));
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
createSelector(sslClientConfigs);
InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
selector.connect(node, addr, BUFFER_SIZE, BUFFER_SIZE);
NetworkTestUtils.waitForChannelReady(selector, node);
server.verifyAuthenticationMetrics(1, 0);
}

/**
* Tests that connections can be made with TLSv1.2 cipher suite.
*/
@Test
public void testCiphersSuiteForTls12() throws Exception {
String node = "0";
String cipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";

sslServerConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, SslConfigs.DEFAULT_SSL_PROTOCOL);
sslServerConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split(",")));
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
server = createEchoServer(SecurityProtocol.SSL);

sslClientConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, SslConfigs.DEFAULT_SSL_PROTOCOL);
sslClientConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split(",")));
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
createSelector(sslClientConfigs);
InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
selector.connect(node, addr, BUFFER_SIZE, BUFFER_SIZE);

NetworkTestUtils.waitForChannelReady(selector, node);
server.verifyAuthenticationMetrics(1, 0);
}

/**
* Tests that connections cannot be made with unsupported TLS cipher suites
*/
@Test
public void testUnsupportedCiphers() throws Exception {
String node = "0";
SSLContext context = SSLContext.getInstance(tlsProtocol);
context.init(null, null, null);
String[] cipherSuites = context.getDefaultSSLParameters().getCipherSuites();
Expand All @@ -732,11 +614,8 @@ public void testUnsupportedCiphers() throws Exception {

sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Arrays.asList(cipherSuites[1]));
createSelector(sslClientConfigs);
InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
selector.connect(node, addr, BUFFER_SIZE, BUFFER_SIZE);

NetworkTestUtils.waitForChannelClose(selector, node, ChannelState.State.AUTHENTICATION_FAILED);
server.verifyAuthenticationMetrics(0, 1);
Comment thread
nizhikov marked this conversation as resolved.
checkAuthentiationFailed("1", tlsProtocol);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.kafka.common.network;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import org.apache.kafka.common.config.SslConfigs;
import org.apache.kafka.common.metrics.Metrics;
import org.apache.kafka.common.security.TestSecurityConfig;
import org.apache.kafka.common.security.auth.SecurityProtocol;
import org.apache.kafka.common.utils.Java;
import org.apache.kafka.common.utils.LogContext;
import org.apache.kafka.common.utils.Time;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assume.assumeTrue;

public class SslTransportTls12Tls13Test {
private static final int BUFFER_SIZE = 4 * 1024;
private static final Time TIME = Time.SYSTEM;

private NioEchoServer server;
private Selector selector;
private Map<String, Object> sslClientConfigs;
private Map<String, Object> sslServerConfigs;

@Before
public void setup() throws Exception {
// Create certificates for use by client and server. Add server cert to client truststore and vice versa.
CertStores serverCertStores = new CertStores(true, "server", "localhost");
CertStores clientCertStores = new CertStores(false, "client", "localhost");
sslServerConfigs = serverCertStores.getTrustingConfig(clientCertStores);
sslClientConfigs = clientCertStores.getTrustingConfig(serverCertStores);

LogContext logContext = new LogContext();
ChannelBuilder channelBuilder = new SslChannelBuilder(Mode.CLIENT, null, false, logContext);
channelBuilder.configure(sslClientConfigs);
this.selector = new Selector(5000, new Metrics(), TIME, "MetricGroup", channelBuilder, logContext);
}

@After
public void teardown() throws Exception {
if (selector != null)
this.selector.close();
if (server != null)
this.server.close();
}

/**
* Tests that connections fails if TLSv1.3 enabled but cipher suite suitable only for TLSv1.2 used.
*/
@Test
public void testCiphersSuiteForTls12FailsForTls13() throws Exception {
assumeTrue(Java.IS_JAVA11_COMPATIBLE);

String cipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";

sslServerConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Collections.singletonList("TLSv1.3"));
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
server = NetworkTestUtils.createEchoServer(ListenerName.forSecurityProtocol(SecurityProtocol.SSL),
SecurityProtocol.SSL, new TestSecurityConfig(sslServerConfigs), null, TIME);

sslClientConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Collections.singletonList("TLSv1.3"));
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));

checkAuthentiationFailed();
}

/**
* Tests that connections can't be made if server uses TLSv1.2 with custom cipher suite and client uses TLSv1.3.
*/
@Test
public void testCiphersSuiteFailForServerTls12ClientTls13() throws Exception {
assumeTrue(Java.IS_JAVA11_COMPATIBLE);

String tls12CipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
String tls13CipherSuite = "TLS_AES_128_GCM_SHA256";

sslServerConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, "TLSv1.2");
sslServerConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Collections.singletonList("TLSv1.2"));
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(tls12CipherSuite));
server = NetworkTestUtils.createEchoServer(ListenerName.forSecurityProtocol(SecurityProtocol.SSL),
SecurityProtocol.SSL, new TestSecurityConfig(sslServerConfigs), null, TIME);

sslClientConfigs.put(SslConfigs.SSL_PROTOCOL_CONFIG, "TLSv1.3");
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(tls13CipherSuite));

checkAuthentiationFailed();
}

/**
* Tests that connections can be made with TLSv1.3 cipher suite.
*/
@Test
public void testCiphersSuiteForTls13() throws Exception {
assumeTrue(Java.IS_JAVA11_COMPATIBLE);

String cipherSuite = "TLS_AES_128_GCM_SHA256";

sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
server = NetworkTestUtils.createEchoServer(ListenerName.forSecurityProtocol(SecurityProtocol.SSL),
SecurityProtocol.SSL, new TestSecurityConfig(sslServerConfigs), null, TIME);

sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
checkAuthenticationSucceed();
}

/**
* Tests that connections can be made with TLSv1.2 cipher suite.
*/
@Test
public void testCiphersSuiteForTls12() throws Exception {
String cipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";

sslServerConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split(",")));
sslServerConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
server = NetworkTestUtils.createEchoServer(ListenerName.forSecurityProtocol(SecurityProtocol.SSL),
SecurityProtocol.SSL, new TestSecurityConfig(sslServerConfigs), null, TIME);

sslClientConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList(SslConfigs.DEFAULT_SSL_ENABLED_PROTOCOLS.split(",")));
sslClientConfigs.put(SslConfigs.SSL_CIPHER_SUITES_CONFIG, Collections.singletonList(cipherSuite));
checkAuthenticationSucceed();
}

/** Checks connection failed using the specified {@code tlsVersion}. */
private void checkAuthentiationFailed() throws IOException, InterruptedException {
sslClientConfigs.put(SslConfigs.SSL_ENABLED_PROTOCOLS_CONFIG, Arrays.asList("TLSv1.3"));
createSelector(sslClientConfigs);
InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
selector.connect("0", addr, BUFFER_SIZE, BUFFER_SIZE);

NetworkTestUtils.waitForChannelClose(selector, "0", ChannelState.State.AUTHENTICATION_FAILED);
server.verifyAuthenticationMetrics(0, 1);
}

private void checkAuthenticationSucceed() throws IOException, InterruptedException {
createSelector(sslClientConfigs);
InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
selector.connect("0", addr, BUFFER_SIZE, BUFFER_SIZE);
NetworkTestUtils.waitForChannelReady(selector, "0");
server.verifyAuthenticationMetrics(1, 0);
}

private void createSelector(Map<String, Object> sslClientConfigs) {
SslTransportLayerTest.TestSslChannelBuilder channelBuilder = new SslTransportLayerTest.TestSslChannelBuilder(Mode.CLIENT);
channelBuilder.configureBufferSizes(null, null, null);
channelBuilder.configure(sslClientConfigs);
this.selector = new Selector(100 * 5000, new Metrics(), TIME, "MetricGroup", channelBuilder, new LogContext());
}
}