restrict default to TLS 1.2 if old/unavailable OpenSSL

This commit is contained in:
Jörg Prante 2021-09-16 12:07:58 +02:00
parent 8a4775c05c
commit 7f69090bcb
8 changed files with 69 additions and 14 deletions

View file

@ -1,11 +1,11 @@
group = org.xbib group = org.xbib
name = netty-http name = netty-http
version = 4.1.66.0 version = 4.1.68.0
gradle.wrapper.version = 6.6.1 gradle.wrapper.version = 6.6.1
netty.version = 4.1.66.Final netty.version = 4.1.68.Final
tcnative.version = 2.0.40.Final tcnative.version = 2.0.43.Final
bouncycastle.version = 1.69 bouncycastle.version = 1.69
reactivestreams.version = 1.0.3 reactivestreams.version = 1.0.3
reactivex.version = 1.3.8 reactivex.version = 1.3.8

View file

@ -693,7 +693,7 @@ public final class Client implements AutoCloseable {
return this; return this;
} }
public Builder setTlsProtocols(String[] protocols) { public Builder setTransportLayerSecurityProtocols(String... protocols) {
clientConfig.setProtocols(protocols); clientConfig.setProtocols(protocols);
return this; return this;
} }

View file

@ -6,6 +6,7 @@ import io.netty.handler.codec.http2.Http2Settings;
import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LogLevel;
import io.netty.handler.proxy.HttpProxyHandler; import io.netty.handler.proxy.HttpProxyHandler;
import io.netty.handler.ssl.CipherSuiteFilter; import io.netty.handler.ssl.CipherSuiteFilter;
import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslProvider; import io.netty.handler.ssl.SslProvider;
import org.xbib.netty.http.client.api.Pool; import org.xbib.netty.http.client.api.Pool;
import org.xbib.netty.http.client.api.BackOff; import org.xbib.netty.http.client.api.BackOff;
@ -94,7 +95,6 @@ public class ClientConfig {
/** /**
* This is Netty's default. * This is Netty's default.
* See {@link io.netty.handler.codec.MessageAggregator}.
*/ */
int MAX_COMPOSITE_BUFFER_COMPONENTS = 1024; int MAX_COMPOSITE_BUFFER_COMPONENTS = 1024;
@ -119,9 +119,11 @@ public class ClientConfig {
Provider SSL_CONTEXT_PROVIDER = null; Provider SSL_CONTEXT_PROVIDER = null;
/** /**
* Transport layer security protocol versions. * Default transport layer security protocol versions (depends on OpenSSL version)
*/ */
String[] PROTOCOLS = new String[] { "TLSv1.3", "TLSv1.2" }; String[] PROTOCOLS = OpenSsl.isAvailable() && OpenSsl.version() <= 0x10101009L ?
new String[] { "TLSv1.2" } :
new String[] { "TLSv1.3", "TLSv1.2" };
/** /**
* Default ciphers. We care about HTTP/2. * Default ciphers. We care about HTTP/2.
@ -211,7 +213,7 @@ public class ClientConfig {
private Provider sslContextProvider = Defaults.SSL_CONTEXT_PROVIDER; private Provider sslContextProvider = Defaults.SSL_CONTEXT_PROVIDER;
private String[] protocols = Defaults.PROTOCOLS; private String[] protocols = Defaults.PROTOCOLS;
private Iterable<String> ciphers = Defaults.CIPHERS; private Iterable<String> ciphers = Defaults.CIPHERS;

View file

@ -28,7 +28,7 @@ class ConscryptTest {
Client client = Client.builder() Client client = Client.builder()
.setJdkSslProvider() .setJdkSslProvider()
.setSslContextProvider(provider) .setSslContextProvider(provider)
.setTlsProtocols(new String[]{"TLSv1.2"}) // disable TLSv1.3 for Conscrypt .setTransportLayerSecurityProtocols("TLSv1.2") // disable TLSv1.3 for Conscrypt
.build(); .build();
logger.log(Level.INFO, client.getClientConfig().toString()); logger.log(Level.INFO, client.getClientConfig().toString());
try { try {

View file

@ -23,7 +23,7 @@ class GoogleTest {
void testHttp1WithTlsV13() throws Exception { void testHttp1WithTlsV13() throws Exception {
AtomicBoolean success = new AtomicBoolean(); AtomicBoolean success = new AtomicBoolean();
Client client = Client.builder() Client client = Client.builder()
.setTlsProtocols(new String[] { "TLSv1.3" }) .setTransportLayerSecurityProtocols(new String[] { "TLSv1.3" })
.build(); .build();
try { try {
Request request = Request.get().url("https://www.google.com/") Request request = Request.get().url("https://www.google.com/")

View file

@ -4,6 +4,7 @@ import io.netty.channel.WriteBufferWaterMark;
import io.netty.handler.codec.http2.Http2Settings; import io.netty.handler.codec.http2.Http2Settings;
import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LogLevel;
import io.netty.handler.ssl.CipherSuiteFilter; import io.netty.handler.ssl.CipherSuiteFilter;
import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslProvider; import io.netty.handler.ssl.SslProvider;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.security.SecurityUtil; import org.xbib.netty.http.common.security.SecurityUtil;
@ -130,7 +131,6 @@ public class DefaultServerConfig implements ServerConfig {
/** /**
* This is Netty's default. * This is Netty's default.
* See {@link io.netty.handler.codec.MessageAggregator#maxCumulationBufferComponents()}.
*/ */
int MAX_COMPOSITE_BUFFER_COMPONENTS = 1024; int MAX_COMPOSITE_BUFFER_COMPONENTS = 1024;
@ -179,7 +179,9 @@ public class DefaultServerConfig implements ServerConfig {
* Transport layer security protocol versions. * Transport layer security protocol versions.
* Do not use SSLv2, SSLv3, TLS 1.0, TLS 1.1. * Do not use SSLv2, SSLv3, TLS 1.0, TLS 1.1.
*/ */
String[] PROTOCOLS = new String[] { "TLSv1.3", "TLSv1.2" }; String[] PROTOCOLS = OpenSsl.isAvailable() && OpenSsl.version() <= 0x10101009L ?
new String[] { "TLSv1.2" } :
new String[] { "TLSv1.3", "TLSv1.2" };
/** /**
* Default ciphers. We care about HTTP/2. * Default ciphers. We care about HTTP/2.

View file

@ -664,6 +664,16 @@ public final class Server implements AutoCloseable {
return this; return this;
} }
public Builder setOpenSSLSslProvider() {
this.serverConfig.setOpenSSLSslProvider();
return this;
}
public Builder setJdkSslProvider() {
this.serverConfig.setJdkSslProvider();
return this;
}
public Builder setTransportLayerSecurityProtocols(String... protocols) { public Builder setTransportLayerSecurityProtocols(String... protocols) {
this.serverConfig.setProtocols(protocols); this.serverConfig.setProtocols(protocols);
return this; return this;

View file

@ -24,7 +24,42 @@ class TransportLayerSecurityServerTest {
private static final Logger logger = Logger.getLogger(TransportLayerSecurityServerTest.class.getName()); private static final Logger logger = Logger.getLogger(TransportLayerSecurityServerTest.class.getName());
@Test @Test
void testTLS12() throws Exception { void testTLSDefaultSettings() throws Exception {
HttpAddress httpAddress = HttpAddress.secureHttp1("localhost", 8143);
Server server = Server.builder(HttpServerDomain.builder(httpAddress)
.setSelfCert()
.singleEndpoint("/", (request, response) ->
response.getBuilder().setStatus(HttpResponseStatus.OK.code()).setContentType("text/plain").build()
.write(request.getContent().toString(StandardCharsets.UTF_8)))
.build())
.build();
Client client = Client.builder()
.trustInsecure()
.build();
AtomicInteger counter = new AtomicInteger();
final ResponseListener<HttpResponse> responseListener = resp -> {
logger.log(Level.INFO, "response listener: headers = " + resp.getHeaders() +
" response body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
counter.incrementAndGet();
};
try {
server.accept();
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base())
.content("Hello Jörg", "text/plain")
.setResponseListener(responseListener)
.build();
ClientTransport transport = client.execute(request).get();
logger.log(Level.INFO, "TLS protocol = " + transport.getSession().getProtocol());
} finally {
client.shutdownGracefully();
server.shutdownGracefully();
}
assertEquals(1, counter.get());
}
@Test
void testOpenSSL12() throws Exception {
HttpAddress httpAddress = HttpAddress.secureHttp1("localhost", 8143); HttpAddress httpAddress = HttpAddress.secureHttp1("localhost", 8143);
Server server = Server.builder(HttpServerDomain.builder(httpAddress) Server server = Server.builder(HttpServerDomain.builder(httpAddress)
.setSelfCert() .setSelfCert()
@ -32,9 +67,12 @@ class TransportLayerSecurityServerTest {
response.getBuilder().setStatus(HttpResponseStatus.OK.code()).setContentType("text/plain").build() response.getBuilder().setStatus(HttpResponseStatus.OK.code()).setContentType("text/plain").build()
.write(request.getContent().toString(StandardCharsets.UTF_8))) .write(request.getContent().toString(StandardCharsets.UTF_8)))
.build()) .build())
.setOpenSSLSslProvider()
.setTransportLayerSecurityProtocols("TLSv1.2") .setTransportLayerSecurityProtocols("TLSv1.2")
.build(); .build();
Client client = Client.builder() Client client = Client.builder()
.setOpenSSLSslProvider()
.setTransportLayerSecurityProtocols("TLSv1.2")
.trustInsecure() .trustInsecure()
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
@ -61,7 +99,7 @@ class TransportLayerSecurityServerTest {
} }
@Test @Test
void testTLS13() throws Exception { void testOpenSSL13() throws Exception {
HttpAddress httpAddress = HttpAddress.secureHttp2("localhost", 8143); HttpAddress httpAddress = HttpAddress.secureHttp2("localhost", 8143);
Server server = Server.builder(HttpServerDomain.builder(httpAddress) Server server = Server.builder(HttpServerDomain.builder(httpAddress)
.setSelfCert() .setSelfCert()
@ -69,9 +107,12 @@ class TransportLayerSecurityServerTest {
response.getBuilder().setStatus(HttpResponseStatus.OK.code()).setContentType("text/plain").build() response.getBuilder().setStatus(HttpResponseStatus.OK.code()).setContentType("text/plain").build()
.write(request.getContent().toString(StandardCharsets.UTF_8))) .write(request.getContent().toString(StandardCharsets.UTF_8)))
.build()) .build())
.setOpenSSLSslProvider()
.setTransportLayerSecurityProtocols("TLSv1.3") .setTransportLayerSecurityProtocols("TLSv1.3")
.build(); .build();
Client client = Client.builder() Client client = Client.builder()
.setOpenSSLSslProvider()
.setTransportLayerSecurityProtocols("TLSv1.3")
.trustInsecure() .trustInsecure()
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();