diff --git a/networking/build.gradle b/networking/build.gradle index e24bab589..b970ec4d9 100644 --- a/networking/build.gradle +++ b/networking/build.gradle @@ -43,7 +43,6 @@ dependencies { annotationProcessor deps['com.google.dagger:dagger-compiler'] testAnnotationProcessor deps['com.google.dagger:dagger-compiler'] - compile 'joda-time:joda-time:2.9.2' } // Make testing artifacts available to be depended up on by other projects. diff --git a/networking/src/main/java/google/registry/networking/handler/SslServerInitializer.java b/networking/src/main/java/google/registry/networking/handler/SslServerInitializer.java index a34cb35a6..08656eb83 100644 --- a/networking/src/main/java/google/registry/networking/handler/SslServerInitializer.java +++ b/networking/src/main/java/google/registry/networking/handler/SslServerInitializer.java @@ -19,7 +19,6 @@ import static google.registry.util.X509Utils.getCertificateHash; import com.google.common.collect.ImmutableList; import com.google.common.flogger.FluentLogger; -import google.registry.util.Clock; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler.Sharable; @@ -43,7 +42,6 @@ import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.util.function.Supplier; import javax.net.ssl.SSLSession; -import org.joda.time.DateTime; /** * Adds a server side SSL handler to the channel pipeline. @@ -102,19 +100,13 @@ public class SslServerInitializer extends ChannelInitializer< private final Supplier privateKeySupplier; private final Supplier> certificatesSupplier; private final ImmutableList supportedSslVersions; - // TODO(sarahbot): Remove this variable and its check after enforcement start date has passed. - private final ImmutableList oldSupportedSslVersions; - private final DateTime enforcementStartTime; - private final Clock clock; public SslServerInitializer( boolean requireClientCert, boolean validateClientCert, SslProvider sslProvider, Supplier privateKeySupplier, - Supplier> certificatesSupplier, - DateTime enforcementStartTime, - Clock clock) { + Supplier> certificatesSupplier) { logger.atInfo().log("Server SSL Provider: %s", sslProvider); checkArgument( requireClientCert || !validateClientCert, @@ -130,12 +122,6 @@ public class SslServerInitializer extends ChannelInitializer< // JDK support for TLS 1.3 won't be available until 2021-04-20 at the earliest. // See: https://java.com/en/jre-jdk-cryptoroadmap.html : ImmutableList.of("TLSv1.2"); - this.oldSupportedSslVersions = - sslProvider == SslProvider.OPENSSL - ? ImmutableList.of("TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1") - : ImmutableList.of("TLSv1.2", "TLSv1.1", "TLSv1"); - this.enforcementStartTime = enforcementStartTime; - this.clock = clock; } @Override @@ -147,13 +133,8 @@ public class SslServerInitializer extends ChannelInitializer< .sslProvider(sslProvider) .trustManager(InsecureTrustManagerFactory.INSTANCE) .clientAuth(requireClientCert ? ClientAuth.REQUIRE : ClientAuth.NONE) - .protocols( - enforcementStartTime.isBefore(clock.nowUtc()) - ? supportedSslVersions - : oldSupportedSslVersions) - .ciphers( - enforcementStartTime.isBefore(clock.nowUtc()) ? ALLOWED_TLS_CIPHERS : null, - SupportedCipherSuiteFilter.INSTANCE) + .protocols(supportedSslVersions) + .ciphers(ALLOWED_TLS_CIPHERS, SupportedCipherSuiteFilter.INSTANCE) .build(); logger.atInfo().log("Available Cipher Suites: %s", sslContext.cipherSuites()); diff --git a/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java b/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java index b3a321bf3..796671cc6 100644 --- a/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java +++ b/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java @@ -23,7 +23,6 @@ import static google.registry.networking.handler.SslServerInitializer.CLIENT_CER import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; -import google.registry.testing.FakeClock; import google.registry.util.SelfSignedCaCertificate; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInitializer; @@ -35,6 +34,7 @@ import io.netty.handler.ssl.OpenSsl; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslProvider; +import java.nio.channels.ClosedChannelException; import java.security.KeyPair; import java.security.PrivateKey; import java.security.cert.CertificateException; @@ -43,6 +43,7 @@ import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.time.Duration; import java.time.Instant; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; @@ -52,8 +53,6 @@ import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSession; -import org.joda.time.DateTime; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -102,9 +101,7 @@ class SslServerInitializerTest { validateClientCert, sslProvider, Suppliers.ofInstance(privateKey), - Suppliers.ofInstance(ImmutableList.copyOf(certificates)), - DateTime.parse("2021-04-01T16:00:00Z"), - new FakeClock(DateTime.parse("2021-05-01T16:00:00Z"))); + Suppliers.ofInstance(ImmutableList.copyOf(certificates))); } private ChannelHandler getClientHandler( @@ -160,9 +157,7 @@ class SslServerInitializerTest { false, sslProvider, Suppliers.ofInstance(ssc.key()), - Suppliers.ofInstance(ImmutableList.of(ssc.cert())), - DateTime.parse("2021-04-01T16:00:00Z"), - new FakeClock(DateTime.parse("2021-05-01T16:00:00Z"))); + Suppliers.ofInstance(ImmutableList.of(ssc.cert()))); EmbeddedChannel channel = new EmbeddedChannel(); ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast(sslServerInitializer); @@ -239,9 +234,7 @@ class SslServerInitializerTest { true, sslProvider, Suppliers.ofInstance(serverSsc.key()), - Suppliers.ofInstance(ImmutableList.of(serverSsc.cert())), - DateTime.parse("2021-04-01T16:00:00Z"), - new FakeClock(DateTime.parse("2021-05-01T16:00:00Z")))); + Suppliers.ofInstance(ImmutableList.of(serverSsc.cert())))); SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create( "CLIENT", @@ -268,50 +261,6 @@ class SslServerInitializerTest { assertThat(sslSession.getCipherSuite()).isEqualTo("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); } - @ParameterizedTest - @MethodSource("provideTestCombinations") - void testSuccess_cipherNotAccepted_beforeEnforcementDate(SslProvider sslProvider) - throws Exception { - SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST); - LocalAddress localAddress = new LocalAddress("CIPHER_ACCEPTED_BEFORE_DATE_" + sslProvider); - - nettyExtension.setUpServer( - localAddress, - new SslServerInitializer( - true, - true, - sslProvider, - Suppliers.ofInstance(serverSsc.key()), - Suppliers.ofInstance(ImmutableList.of(serverSsc.cert())), - DateTime.parse("2021-04-01T16:00:00Z"), - new FakeClock(DateTime.parse("2021-03-01T16:00:00Z")))); - SelfSignedCaCertificate clientSsc = - SelfSignedCaCertificate.create( - "CLIENT", - Date.from(Instant.now().minus(Duration.ofDays(2))), - Date.from(Instant.now().plus(Duration.ofDays(1)))); - nettyExtension.setUpClient( - localAddress, - getClientHandler( - sslProvider, - serverSsc.cert(), - clientSsc.key(), - clientSsc.cert(), - "TLSv1.2", - Collections.singletonList("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"))); - - SSLSession sslSession = setUpSslChannel(nettyExtension.getClientChannel(), serverSsc.cert()); - nettyExtension.assertThatMessagesWork(); - - assertThat(sslSession.getLocalCertificates()).asList().containsExactly(clientSsc.cert()); - assertThat(sslSession.getPeerCertificates()).asList().containsExactly(serverSsc.cert()); - } - - // This test is a bit tricky to fix because apparently some new OpenJDK 11 version does no - // support TLS 1.1 anymore, and in that case it throws a ClosedChannelException instead of a - // SSLHandShakeException. It's going to be hard to accommodate both the OpenSSL and the JDK - // provider. Disable it for now to unblock people. - @Disabled @ParameterizedTest @MethodSource("provideTestCombinations") void testFailure_protocolNotAccepted(SslProvider sslProvider) throws Exception { @@ -330,45 +279,24 @@ class SslServerInitializerTest { getClientHandler( sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert(), "TLSv1.1", null)); + ImmutableList jdkVersion = + Arrays.asList(System.getProperty("java.version").split("\\.")).stream() + .map(Integer::parseInt) + .collect(ImmutableList.toImmutableList()); + + // In JDK v11.0.11 and above TLS 1.1 is not supported any more, in which case attempting to + // connect with TLS 1.1 results in a ClosedChannelException instead of a SSLHandShakeException. + // See https://www.oracle.com/java/technologies/javase/11-0-11-relnotes.html#JDK-8202343 + Class rootCause = + sslProvider == SslProvider.JDK + && compareSemanticVersion(jdkVersion, ImmutableList.of(11, 0, 11)) + ? ClosedChannelException.class + : SSLHandshakeException.class; + verifySslException( nettyExtension.getServerChannel(), channel -> channel.attr(CLIENT_CERTIFICATE_PROMISE_KEY).get().get(), - SSLHandshakeException.class); - } - - @Disabled - @ParameterizedTest - @MethodSource("provideTestCombinations") - void testSuccess_protocolNotAccepted_beforeEnforcementDate(SslProvider sslProvider) - throws Exception { - SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST); - LocalAddress localAddress = new LocalAddress("PROTOCOL_ACCEPTED_BEFORE_DATE_" + sslProvider); - - nettyExtension.setUpServer( - localAddress, - new SslServerInitializer( - true, - true, - sslProvider, - Suppliers.ofInstance(serverSsc.key()), - Suppliers.ofInstance(ImmutableList.of(serverSsc.cert())), - DateTime.parse("2021-04-01T16:00:00Z"), - new FakeClock(DateTime.parse("2021-03-01T16:00:00Z")))); - SelfSignedCaCertificate clientSsc = - SelfSignedCaCertificate.create( - "CLIENT", - Date.from(Instant.now().minus(Duration.ofDays(2))), - Date.from(Instant.now().plus(Duration.ofDays(1)))); - nettyExtension.setUpClient( - localAddress, - getClientHandler( - sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert(), "TLSv1.1", null)); - - SSLSession sslSession = setUpSslChannel(nettyExtension.getClientChannel(), serverSsc.cert()); - nettyExtension.assertThatMessagesWork(); - - assertThat(sslSession.getLocalCertificates()).asList().containsExactly(clientSsc.cert()); - assertThat(sslSession.getPeerCertificates()).asList().containsExactly(serverSsc.cert()); + rootCause); } @ParameterizedTest @@ -525,4 +453,14 @@ class SslServerInitializerTest { nettyExtension.assertThatServerRootCause().isInstanceOf(SSLException.class); assertThat(nettyExtension.getClientChannel().isActive()).isFalse(); } + + /** Returns true if v1 is larger or equals to v2. */ + private static boolean compareSemanticVersion( + ImmutableList v1, ImmutableList v2) { + for (int i : ImmutableList.of(0, 1, 2)) { + if (v1.get(i) > v2.get(i)) return true; + if (v1.get(i) < v2.get(i)) return false; + } + return true; + } } diff --git a/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java b/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java index 1dda3cf06..b39e59e5d 100644 --- a/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java +++ b/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java @@ -50,7 +50,6 @@ import javax.inject.Named; import javax.inject.Provider; import javax.inject.Qualifier; import javax.inject.Singleton; -import org.joda.time.DateTime; /** A module that provides the {@link FrontendProtocol} used for epp protocol. */ @Module @@ -160,19 +159,11 @@ public final class EppProtocolModule { @Provides @EppProtocol static SslServerInitializer provideSslServerInitializer( - ProxyConfig config, SslProvider sslProvider, Supplier privateKeySupplier, - Supplier> certificatesSupplier, - Clock clock) { + Supplier> certificatesSupplier) { return new SslServerInitializer<>( - true, - false, - sslProvider, - privateKeySupplier, - certificatesSupplier, - DateTime.parse(config.tlsEnforcementStartTime), - clock); + true, false, sslProvider, privateKeySupplier, certificatesSupplier); } @Provides diff --git a/proxy/src/main/java/google/registry/proxy/ProxyConfig.java b/proxy/src/main/java/google/registry/proxy/ProxyConfig.java index e53f167f2..79ea599c4 100644 --- a/proxy/src/main/java/google/registry/proxy/ProxyConfig.java +++ b/proxy/src/main/java/google/registry/proxy/ProxyConfig.java @@ -48,7 +48,6 @@ public class ProxyConfig { public WebWhois webWhois; public HttpsRelay httpsRelay; public Metrics metrics; - public String tlsEnforcementStartTime; /** Configuration options that apply to GCS. */ public static class Gcs { diff --git a/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java b/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java index 51370a8bc..0ee0bb417 100644 --- a/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java +++ b/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java @@ -21,8 +21,6 @@ import dagger.multibindings.IntoSet; import google.registry.networking.handler.SslServerInitializer; import google.registry.proxy.Protocol.FrontendProtocol; import google.registry.proxy.handler.WebWhoisRedirectHandler; -import google.registry.util.Clock; -import google.registry.util.DateTimeUtils; import io.netty.channel.ChannelHandler; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.HttpServerCodec; @@ -135,15 +133,8 @@ public final class WebWhoisProtocolsModule { static SslServerInitializer provideSslServerInitializer( SslProvider sslProvider, Supplier privateKeySupplier, - Supplier> certificatesSupplier, - Clock clock) { + Supplier> certificatesSupplier) { return new SslServerInitializer<>( - false, - false, - sslProvider, - privateKeySupplier, - certificatesSupplier, - DateTimeUtils.END_OF_TIME, - clock); + false, false, sslProvider, privateKeySupplier, certificatesSupplier); } } diff --git a/proxy/src/main/java/google/registry/proxy/config/default-config.yaml b/proxy/src/main/java/google/registry/proxy/config/default-config.yaml index d37fe2413..301cf5be9 100644 --- a/proxy/src/main/java/google/registry/proxy/config/default-config.yaml +++ b/proxy/src/main/java/google/registry/proxy/config/default-config.yaml @@ -8,9 +8,6 @@ # GCP project ID projectId: your-gcp-project-id -# Time to begin enforcement of TLS versions and cipher suites. -tlsEnforcementStartTime: "1970-01-01T00:00:00Z" - # OAuth scope that the GoogleCredential will be constructed with. This list # should include all service scopes that the proxy depends on. gcpScopes: