From 1c1ccee75e57adb0cae004518dd86ba939c0bc35 Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Wed, 27 Nov 2019 16:08:38 -0500 Subject: [PATCH] Respect certificate validity period (#391) Client SSL handler already performs the necessary validation. Only tests are added. Server SSL handler does not currently check for the validity period of the client certificate as the insecure trust manager is used. This PR added the check but does not actually terminate the connection yet. It will log the expired certificates so that we can contact the registrars to update them. Once we are certain that all certificates are updated, we can turn off dryrun mode. We should also consider checking if the certificate has too long a validity period as it defeats the purpose of using regularly updated certificates to deprecate insecure cipher suites. --- networking/build.gradle | 1 + .../gradle/dependency-locks/compile.lockfile | 26 ++++++ .../compileClasspath.lockfile | 26 ++++++ .../gradle/dependency-locks/default.lockfile | 26 ++++++ .../gradle/dependency-locks/runtime.lockfile | 26 ++++++ .../runtimeClasspath.lockfile | 26 ++++++ .../dependency-locks/testCompile.lockfile | 25 ++++++ .../testCompileClasspath.lockfile | 25 ++++++ .../dependency-locks/testRuntime.lockfile | 25 ++++++ .../testRuntimeClasspath.lockfile | 25 ++++++ .../handler/SslServerInitializer.java | 34 +++++++- .../networking/handler/NettyRule.java | 22 +++-- .../handler/SslClientInitializerTest.java | 82 +++++++++++++++++- .../handler/SslInitializerTestUtils.java | 49 ++++++++++- .../handler/SslServerInitializerTest.java | 84 +++++++++++++++---- .../registry/proxy/EppProtocolModule.java | 3 +- .../proxy/WebWhoisProtocolsModule.java | 3 +- 17 files changed, 473 insertions(+), 35 deletions(-) diff --git a/networking/build.gradle b/networking/build.gradle index 8b8ec9bd6..f9609e217 100644 --- a/networking/build.gradle +++ b/networking/build.gradle @@ -24,6 +24,7 @@ dependencies { compile deps['io.netty:netty-handler'] compile deps['io.netty:netty-transport'] compile deps['javax.inject:javax.inject'] + compile project(':util') runtime deps['com.google.flogger:flogger-system-backend'] runtime deps['io.netty:netty-tcnative-boringssl-static'] diff --git a/networking/gradle/dependency-locks/compile.lockfile b/networking/gradle/dependency-locks/compile.lockfile index cfec92435..13bd5a865 100644 --- a/networking/gradle/dependency-locks/compile.lockfile +++ b/networking/gradle/dependency-locks/compile.lockfile @@ -1,13 +1,30 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 +com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -15,6 +32,15 @@ io.netty:netty-common:4.1.31.Final io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/compileClasspath.lockfile b/networking/gradle/dependency-locks/compileClasspath.lockfile index cfec92435..13bd5a865 100644 --- a/networking/gradle/dependency-locks/compileClasspath.lockfile +++ b/networking/gradle/dependency-locks/compileClasspath.lockfile @@ -1,13 +1,30 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 +com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -15,6 +32,15 @@ io.netty:netty-common:4.1.31.Final io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/default.lockfile b/networking/gradle/dependency-locks/default.lockfile index 7dc8b65fb..ccbad5fb1 100644 --- a/networking/gradle/dependency-locks/default.lockfile +++ b/networking/gradle/dependency-locks/default.lockfile @@ -1,14 +1,31 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 +com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger-system-backend:0.1 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -17,6 +34,15 @@ io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-tcnative-boringssl-static:2.0.22.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/runtime.lockfile b/networking/gradle/dependency-locks/runtime.lockfile index 7dc8b65fb..ccbad5fb1 100644 --- a/networking/gradle/dependency-locks/runtime.lockfile +++ b/networking/gradle/dependency-locks/runtime.lockfile @@ -1,14 +1,31 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 +com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger-system-backend:0.1 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -17,6 +34,15 @@ io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-tcnative-boringssl-static:2.0.22.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/runtimeClasspath.lockfile b/networking/gradle/dependency-locks/runtimeClasspath.lockfile index 7dc8b65fb..ccbad5fb1 100644 --- a/networking/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/networking/gradle/dependency-locks/runtimeClasspath.lockfile @@ -1,14 +1,31 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 +com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger-system-backend:0.1 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -17,6 +34,15 @@ io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-tcnative-boringssl-static:2.0.22.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/testCompile.lockfile b/networking/gradle/dependency-locks/testCompile.lockfile index daece711f..e45f7f6a4 100644 --- a/networking/gradle/dependency-locks/testCompile.lockfile +++ b/networking/gradle/dependency-locks/testCompile.lockfile @@ -1,16 +1,32 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 com.google.truth:truth:1.0 com.googlecode.java-diff-utils:diffutils:1.3.0 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -18,11 +34,20 @@ io.netty:netty-common:4.1.31.Final io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 junit:junit:4.12 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.bouncycastle:bcpkix-jdk15on:1.61 org.bouncycastle:bcprov-jdk15on:1.61 org.checkerframework:checker-compat-qual:2.5.5 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 org.hamcrest:hamcrest-core:1.3 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/testCompileClasspath.lockfile b/networking/gradle/dependency-locks/testCompileClasspath.lockfile index daece711f..e45f7f6a4 100644 --- a/networking/gradle/dependency-locks/testCompileClasspath.lockfile +++ b/networking/gradle/dependency-locks/testCompileClasspath.lockfile @@ -1,16 +1,32 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 com.google.truth:truth:1.0 com.googlecode.java-diff-utils:diffutils:1.3.0 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -18,11 +34,20 @@ io.netty:netty-common:4.1.31.Final io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 junit:junit:4.12 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.bouncycastle:bcpkix-jdk15on:1.61 org.bouncycastle:bcprov-jdk15on:1.61 org.checkerframework:checker-compat-qual:2.5.5 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 org.hamcrest:hamcrest-core:1.3 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/testRuntime.lockfile b/networking/gradle/dependency-locks/testRuntime.lockfile index c52811fd5..01a42c8e8 100644 --- a/networking/gradle/dependency-locks/testRuntime.lockfile +++ b/networking/gradle/dependency-locks/testRuntime.lockfile @@ -1,17 +1,33 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger-system-backend:0.1 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 com.google.truth:truth:1.0 com.googlecode.java-diff-utils:diffutils:1.3.0 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -20,11 +36,20 @@ io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-tcnative-boringssl-static:2.0.22.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 junit:junit:4.12 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.bouncycastle:bcpkix-jdk15on:1.61 org.bouncycastle:bcprov-jdk15on:1.61 org.checkerframework:checker-compat-qual:2.5.5 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 org.hamcrest:hamcrest-core:1.3 +org.yaml:snakeyaml:1.17 diff --git a/networking/gradle/dependency-locks/testRuntimeClasspath.lockfile b/networking/gradle/dependency-locks/testRuntimeClasspath.lockfile index c52811fd5..01a42c8e8 100644 --- a/networking/gradle/dependency-locks/testRuntimeClasspath.lockfile +++ b/networking/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -1,17 +1,33 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 +com.google.appengine:appengine-api-1.0-sdk:1.9.48 +com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 +com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 +com.google.dagger:dagger:2.21 com.google.errorprone:error_prone_annotations:2.3.2 com.google.flogger:flogger-system-backend:0.1 com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:28.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 +com.google.re2j:re2j:1.1 com.google.truth:truth:1.0 com.googlecode.java-diff-utils:diffutils:1.3.0 +com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -20,11 +36,20 @@ io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-tcnative-boringssl-static:2.0.22.Final io.netty:netty-transport:4.1.31.Final +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 +javax.activation:activation:1.1 javax.inject:javax.inject:1 +javax.mail:mail:1.4 +javax.xml.bind:jaxb-api:2.3.0 +joda-time:joda-time:2.9.2 junit:junit:4.12 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.bouncycastle:bcpkix-jdk15on:1.61 org.bouncycastle:bcprov-jdk15on:1.61 org.checkerframework:checker-compat-qual:2.5.5 org.checkerframework:checker-qual:2.8.1 org.codehaus.mojo:animal-sniffer-annotations:1.18 org.hamcrest:hamcrest-core:1.3 +org.yaml:snakeyaml:1.17 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 9bbf357cc..5be1af53a 100644 --- a/networking/src/main/java/google/registry/networking/handler/SslServerInitializer.java +++ b/networking/src/main/java/google/registry/networking/handler/SslServerInitializer.java @@ -14,9 +14,13 @@ package google.registry.networking.handler; +import static com.google.common.base.Preconditions.checkArgument; +import static google.registry.util.X509Utils.getCertificateHash; + import com.google.common.collect.ImmutableList; import com.google.common.flogger.FluentLogger; import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelInitializer; import io.netty.channel.embedded.EmbeddedChannel; @@ -29,6 +33,8 @@ import io.netty.util.AttributeKey; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; import java.security.PrivateKey; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.util.function.Supplier; @@ -58,6 +64,8 @@ public class SslServerInitializer extends ChannelInitializer< private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private final boolean requireClientCert; + // TODO(jianglai): Always validate client certs (if required). + private final boolean validateClientCert; private final SslProvider sslProvider; // We use suppliers for the key/cert pair because they are fetched and cached from GCS, and can // change when the artifacts on GCS changes. @@ -66,11 +74,16 @@ public class SslServerInitializer extends ChannelInitializer< public SslServerInitializer( boolean requireClientCert, + boolean validateClientCert, SslProvider sslProvider, Supplier privateKeySupplier, Supplier> certificatesSupplier) { logger.atInfo().log("Server SSL Provider: %s", sslProvider); + checkArgument( + requireClientCert || !validateClientCert, + "Cannot validate client certificate if client certificate is not required."); this.requireClientCert = requireClientCert; + this.validateClientCert = validateClientCert; this.sslProvider = sslProvider; this.privateKeySupplier = privateKeySupplier; this.certificatesSupplier = certificatesSupplier; @@ -95,10 +108,23 @@ public class SslServerInitializer extends ChannelInitializer< .addListener( future -> { if (future.isSuccess()) { - Promise unusedPromise = - clientCertificatePromise.setSuccess( - (X509Certificate) - sslHandler.engine().getSession().getPeerCertificates()[0]); + X509Certificate clientCertificate = + (X509Certificate) + sslHandler.engine().getSession().getPeerCertificates()[0]; + try { + clientCertificate.checkValidity(); + Promise unusedPromise = + clientCertificatePromise.setSuccess(clientCertificate); + } catch (CertificateNotYetValidException | CertificateExpiredException e) { + logger.atWarning().withCause(e).log( + "Client certificate is not valid.\nHash: %s", + getCertificateHash(clientCertificate)); + if (validateClientCert) { + Promise unusedPromise = + clientCertificatePromise.setFailure(e); + ChannelFuture unusedFuture2 = channel.close(); + } + } } else { Promise unusedPromise = clientCertificatePromise.setFailure(future.cause()); diff --git a/networking/src/test/java/google/registry/networking/handler/NettyRule.java b/networking/src/test/java/google/registry/networking/handler/NettyRule.java index f88f8961f..0b48b6998 100644 --- a/networking/src/test/java/google/registry/networking/handler/NettyRule.java +++ b/networking/src/test/java/google/registry/networking/handler/NettyRule.java @@ -61,7 +61,9 @@ public final class NettyRule extends ExternalResource { // Handler attached to client's channel to record the response received. private DumpHandler dumpHandler; - private Channel channel; + private Channel clientChannel; + + private Channel serverChannel; public EventLoopGroup getEventLoopGroup() { return eventLoopGroup; @@ -79,6 +81,7 @@ public final class NettyRule extends ExternalResource { ch.pipeline().addLast(handlers); // Add the "echoHandler" last to log the incoming message and send it back ch.pipeline().addLast(echoHandler); + serverChannel = ch; } }; ServerBootstrap sb = @@ -109,11 +112,11 @@ public final class NettyRule extends ExternalResource { .group(eventLoopGroup) .channel(LocalChannel.class) .handler(clientInitializer); - channel = b.connect(localAddress).syncUninterruptibly().channel(); + clientChannel = b.connect(localAddress).syncUninterruptibly().channel(); } void checkReady() { - checkState(channel != null, "Must call setUpClient to finish NettyRule setup"); + checkState(clientChannel != null, "Must call setUpClient to finish NettyRule setup"); } /** @@ -125,16 +128,21 @@ public final class NettyRule extends ExternalResource { */ void assertThatMessagesWork() throws Exception { checkReady(); - assertThat(channel.isActive()).isTrue(); + assertThat(clientChannel.isActive()).isTrue(); - writeToChannelAndFlush(channel, "Hello, world!"); + writeToChannelAndFlush(clientChannel, "Hello, world!"); assertThat(echoHandler.getRequestFuture().get()).isEqualTo("Hello, world!"); assertThat(dumpHandler.getResponseFuture().get()).isEqualTo("Hello, world!"); } - Channel getChannel() { + Channel getClientChannel() { checkReady(); - return channel; + return clientChannel; + } + + Channel getServerChannel() { + checkReady(); + return serverChannel; } ThrowableSubject assertThatServerRootCause() { diff --git a/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java b/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java index 3d15c6119..9a9decdf7 100644 --- a/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java +++ b/networking/src/test/java/google/registry/networking/handler/SslClientInitializerTest.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static google.registry.networking.handler.SslInitializerTestUtils.getKeyPair; import static google.registry.networking.handler.SslInitializerTestUtils.setUpSslChannel; import static google.registry.networking.handler.SslInitializerTestUtils.signKeyPair; +import static google.registry.networking.handler.SslInitializerTestUtils.verifySslExcpetion; import com.google.common.collect.ImmutableList; import io.netty.channel.Channel; @@ -39,7 +40,12 @@ import java.security.KeyPair; import java.security.PrivateKey; import java.security.cert.CertPathBuilderException; import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; import java.util.function.Function; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; @@ -159,7 +165,7 @@ public class SslClientInitializerTest { // exceptions. nettyRule.assertThatClientRootCause().isInstanceOf(CertPathBuilderException.class); nettyRule.assertThatServerRootCause().isInstanceOf(SSLException.class); - assertThat(nettyRule.getChannel().isActive()).isFalse(); + assertThat(nettyRule.getClientChannel().isActive()).isFalse(); } @Test @@ -184,13 +190,81 @@ public class SslClientInitializerTest { sslProvider, hostProvider, portProvider, ImmutableList.of(ssc.cert()), null, null); nettyRule.setUpClient(localAddress, sslClientInitializer); - setUpSslChannel(nettyRule.getChannel(), cert); + setUpSslChannel(nettyRule.getClientChannel(), cert); nettyRule.assertThatMessagesWork(); // Verify that the SNI extension is sent during handshake. assertThat(sniHostReceived).isEqualTo(SSL_HOST); } + @Test + public void testFailure_customTrustManager_serverCertExpired() throws Exception { + LocalAddress localAddress = + new LocalAddress("CUSTOM_TRUST_MANAGER_SERVE_CERT_EXPIRED_" + sslProvider); + + // Generate a new key pair. + KeyPair keyPair = getKeyPair(); + + // Generate a self signed certificate, and use it to sign the key pair. + SelfSignedCertificate ssc = new SelfSignedCertificate(); + X509Certificate cert = + signKeyPair( + ssc, + keyPair, + SSL_HOST, + Date.from(Instant.now().minus(Duration.ofDays(2))), + Date.from(Instant.now().minus(Duration.ofDays(1)))); + + // Set up the server to use the signed cert and private key to perform handshake; + PrivateKey privateKey = keyPair.getPrivate(); + nettyRule.setUpServer(localAddress, getServerHandler(false, privateKey, cert)); + + // Set up the client to trust the self signed cert used to sign the cert that server provides. + SslClientInitializer sslClientInitializer = + new SslClientInitializer<>( + sslProvider, hostProvider, portProvider, ImmutableList.of(ssc.cert()), null, null); + nettyRule.setUpClient(localAddress, sslClientInitializer); + + verifySslExcpetion( + nettyRule.getClientChannel(), + channel -> channel.pipeline().get(SslHandler.class).handshakeFuture().get(), + CertificateExpiredException.class); + } + + @Test + public void testFailure_customTrustManager_serverCertNotYetValid() throws Exception { + LocalAddress localAddress = + new LocalAddress("CUSTOM_TRUST_MANAGER_SERVE_CERT_NOT_YET_VALID_" + sslProvider); + + // Generate a new key pair. + KeyPair keyPair = getKeyPair(); + + // Generate a self signed certificate, and use it to sign the key pair. + SelfSignedCertificate ssc = new SelfSignedCertificate(); + X509Certificate cert = + signKeyPair( + ssc, + keyPair, + SSL_HOST, + Date.from(Instant.now().plus(Duration.ofDays(1))), + Date.from(Instant.now().plus(Duration.ofDays(2)))); + + // Set up the server to use the signed cert and private key to perform handshake; + PrivateKey privateKey = keyPair.getPrivate(); + nettyRule.setUpServer(localAddress, getServerHandler(false, privateKey, cert)); + + // Set up the client to trust the self signed cert used to sign the cert that server provides. + SslClientInitializer sslClientInitializer = + new SslClientInitializer<>( + sslProvider, hostProvider, portProvider, ImmutableList.of(ssc.cert()), null, null); + nettyRule.setUpClient(localAddress, sslClientInitializer); + + verifySslExcpetion( + nettyRule.getClientChannel(), + channel -> channel.pipeline().get(SslHandler.class).handshakeFuture().get(), + CertificateNotYetValidException.class); + } + @Test public void testSuccess_customTrustManager_acceptSelfSignedCert_clientCertRequired() throws Exception { @@ -215,7 +289,7 @@ public class SslClientInitializerTest { () -> ImmutableList.of(clientSsc.cert())); nettyRule.setUpClient(localAddress, sslClientInitializer); - SSLSession sslSession = setUpSslChannel(nettyRule.getChannel(), serverSsc.cert()); + SSLSession sslSession = setUpSslChannel(nettyRule.getClientChannel(), serverSsc.cert()); nettyRule.assertThatMessagesWork(); // Verify that the SNI extension is sent during handshake. @@ -255,6 +329,6 @@ public class SslClientInitializerTest { nettyRule.assertThatClientRootCause().isInstanceOf(CertificateException.class); nettyRule.assertThatClientRootCause().hasMessageThat().contains(SSL_HOST); nettyRule.assertThatServerRootCause().isInstanceOf(SSLException.class); - assertThat(nettyRule.getChannel().isActive()).isFalse(); + assertThat(nettyRule.getClientChannel().isActive()).isFalse(); } } diff --git a/networking/src/test/java/google/registry/networking/handler/SslInitializerTestUtils.java b/networking/src/test/java/google/registry/networking/handler/SslInitializerTestUtils.java index a690572e7..d2cebac95 100644 --- a/networking/src/test/java/google/registry/networking/handler/SslInitializerTestUtils.java +++ b/networking/src/test/java/google/registry/networking/handler/SslInitializerTestUtils.java @@ -15,8 +15,11 @@ package google.registry.networking.handler; import static com.google.common.truth.Truth.assertThat; +import static google.registry.testing.JUnitBackports.assertThrows; +import com.google.common.base.Throwables; import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.util.SelfSignedCertificate; import java.math.BigInteger; @@ -28,6 +31,7 @@ import java.security.cert.X509Certificate; import java.time.Duration; import java.time.Instant; import java.util.Date; +import java.util.concurrent.ExecutionException; import javax.net.ssl.SSLSession; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -61,17 +65,17 @@ public final class SslInitializerTestUtils { } /** - * Signs the given key pair with the given self signed certificate. + * Signs the given key pair with the given self signed certificate to generate a certificate with + * the given validity range. * * @return signed public key (of the key pair) certificate */ public static X509Certificate signKeyPair( - SelfSignedCertificate ssc, KeyPair keyPair, String hostname) throws Exception { + SelfSignedCertificate ssc, KeyPair keyPair, String hostname, Date from, Date to) + throws Exception { X500Name subjectDnName = new X500Name("CN=" + hostname); BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis()); X500Name issuerDnName = new X500Name(ssc.cert().getIssuerDN().getName()); - Date from = Date.from(Instant.now().minus(Duration.ofDays(1))); - Date to = Date.from(Instant.now().plus(Duration.ofDays(1))); SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()); AlgorithmIdentifier sigAlgId = @@ -89,6 +93,22 @@ public final class SslInitializerTestUtils { return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certificateHolder); } + /** + * Signs the given key pair with the given self signed certificate to generate a certificate that + * is valid from yesterday to tomorrow. + * + * @return signed public key (of the key pair) certificate + */ + public static X509Certificate signKeyPair( + SelfSignedCertificate ssc, KeyPair keyPair, String hostname) throws Exception { + return signKeyPair( + ssc, + keyPair, + hostname, + Date.from(Instant.now().minus(Duration.ofDays(1))), + Date.from(Instant.now().plus(Duration.ofDays(1)))); + } + /** * Verifies tha the SSL channel is established as expected, and also sends a message to the server * and verifies if it is echoed back correctly. @@ -110,4 +130,25 @@ public final class SslInitializerTestUtils { // Returns the SSL session for further assertion. return sslHandler.engine().getSession(); } + + /** Verifies tha the SSL channel cannot be established due to a given exception. */ + static void verifySslExcpetion( + Channel channel, CheckedConsumer operation, Class cause) + throws Exception { + // Extract SSL exception from the handshake future. + Exception exception = assertThrows(ExecutionException.class, () -> operation.accept(channel)); + + // Verify that the exception is caused by the expected cause. + assertThat(Throwables.getRootCause(exception)).isInstanceOf(cause); + + // Ensure that the channel is closed. If this step times out, the channel is not properly + // closed. + ChannelFuture unusedFuture = channel.closeFuture().syncUninterruptibly(); + } + + /** A consumer that can throw checked exceptions. */ + @FunctionalInterface + interface CheckedConsumer { + void accept(T t) throws Exception; + } } 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 928dd2089..13214b2ab 100644 --- a/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java +++ b/networking/src/test/java/google/registry/networking/handler/SslServerInitializerTest.java @@ -18,6 +18,8 @@ import static com.google.common.truth.Truth.assertThat; import static google.registry.networking.handler.SslInitializerTestUtils.getKeyPair; import static google.registry.networking.handler.SslInitializerTestUtils.setUpSslChannel; import static google.registry.networking.handler.SslInitializerTestUtils.signKeyPair; +import static google.registry.networking.handler.SslInitializerTestUtils.verifySslExcpetion; +import static google.registry.networking.handler.SslServerInitializer.CLIENT_CERTIFICATE_PROMISE_KEY; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; @@ -35,7 +37,12 @@ import io.netty.handler.ssl.util.SelfSignedCertificate; import java.security.KeyPair; import java.security.PrivateKey; import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; @@ -82,18 +89,18 @@ public class SslServerInitializerTest { } private ChannelHandler getServerHandler( - boolean requireClientCert, PrivateKey privateKey, X509Certificate... certificates) { + boolean requireClientCert, + boolean validateClientCert, + PrivateKey privateKey, + X509Certificate... certificates) { return new SslServerInitializer( requireClientCert, + validateClientCert, sslProvider, Suppliers.ofInstance(privateKey), Suppliers.ofInstance(ImmutableList.copyOf(certificates))); } - private ChannelHandler getServerHandler(PrivateKey privateKey, X509Certificate... certificates) { - return getServerHandler(true, privateKey, certificates); - } - private ChannelHandler getClientHandler( X509Certificate trustedCertificate, PrivateKey privateKey, X509Certificate certificate) { return new ChannelInitializer() { @@ -124,6 +131,7 @@ public class SslServerInitializerTest { SslServerInitializer sslServerInitializer = new SslServerInitializer<>( true, + false, sslProvider, Suppliers.ofInstance(ssc.key()), Suppliers.ofInstance(ImmutableList.of(ssc.cert()))); @@ -142,12 +150,13 @@ public class SslServerInitializerTest { SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST); LocalAddress localAddress = new LocalAddress("TRUST_ANY_CLIENT_CERT_" + sslProvider); - nettyRule.setUpServer(localAddress, getServerHandler(serverSsc.key(), serverSsc.cert())); + nettyRule.setUpServer( + localAddress, getServerHandler(true, false, serverSsc.key(), serverSsc.cert())); SelfSignedCertificate clientSsc = new SelfSignedCertificate(); nettyRule.setUpClient( localAddress, getClientHandler(serverSsc.cert(), clientSsc.key(), clientSsc.cert())); - SSLSession sslSession = setUpSslChannel(nettyRule.getChannel(), serverSsc.cert()); + SSLSession sslSession = setUpSslChannel(nettyRule.getClientChannel(), serverSsc.cert()); nettyRule.assertThatMessagesWork(); // Verify that the SSL session gets the client cert. Note that this SslSession is for the client @@ -157,15 +166,58 @@ public class SslServerInitializerTest { assertThat(sslSession.getPeerCertificates()).asList().containsExactly(serverSsc.cert()); } + @Test + public void testFailure_clientCertExpired() throws Exception { + SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST); + LocalAddress localAddress = new LocalAddress("CLIENT_CERT_EXPIRED_" + sslProvider); + + nettyRule.setUpServer( + localAddress, getServerHandler(true, true, serverSsc.key(), serverSsc.cert())); + SelfSignedCertificate clientSsc = + new SelfSignedCertificate( + "CLIENT", + Date.from(Instant.now().minus(Duration.ofDays(2))), + Date.from(Instant.now().minus(Duration.ofDays(1)))); + nettyRule.setUpClient( + localAddress, getClientHandler(serverSsc.cert(), clientSsc.key(), clientSsc.cert())); + + verifySslExcpetion( + nettyRule.getServerChannel(), + channel -> channel.attr(CLIENT_CERTIFICATE_PROMISE_KEY).get().get(), + CertificateExpiredException.class); + } + + @Test + public void testFailure_clientCertNotYetValid() throws Exception { + SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST); + LocalAddress localAddress = new LocalAddress("CLIENT_CERT_EXPIRED_" + sslProvider); + + nettyRule.setUpServer( + localAddress, getServerHandler(true, true, serverSsc.key(), serverSsc.cert())); + SelfSignedCertificate clientSsc = + new SelfSignedCertificate( + "CLIENT", + Date.from(Instant.now().plus(Duration.ofDays(1))), + Date.from(Instant.now().plus(Duration.ofDays(2)))); + nettyRule.setUpClient( + localAddress, getClientHandler(serverSsc.cert(), clientSsc.key(), clientSsc.cert())); + + verifySslExcpetion( + nettyRule.getServerChannel(), + channel -> channel.attr(CLIENT_CERTIFICATE_PROMISE_KEY).get().get(), + CertificateNotYetValidException.class); + } + @Test public void testSuccess_doesNotRequireClientCert() throws Exception { SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST); LocalAddress localAddress = new LocalAddress("DOES_NOT_REQUIRE_CLIENT_CERT_" + sslProvider); - nettyRule.setUpServer(localAddress, getServerHandler(false, serverSsc.key(), serverSsc.cert())); + nettyRule.setUpServer( + localAddress, getServerHandler(false, false, serverSsc.key(), serverSsc.cert())); nettyRule.setUpClient(localAddress, getClientHandler(serverSsc.cert(), null, null)); - SSLSession sslSession = setUpSslChannel(nettyRule.getChannel(), serverSsc.cert()); + SSLSession sslSession = setUpSslChannel(nettyRule.getClientChannel(), serverSsc.cert()); nettyRule.assertThatMessagesWork(); // Verify that the SSL session does not contain any client cert. Note that this SslSession is @@ -186,6 +238,8 @@ public class SslServerInitializerTest { nettyRule.setUpServer( localAddress, getServerHandler( + true, + false, keyPair.getPrivate(), // Serving both the server cert, and the CA cert serverCert, @@ -197,7 +251,7 @@ public class SslServerInitializerTest { // Client trusts the CA cert caSsc.cert(), clientSsc.key(), clientSsc.cert())); - SSLSession sslSession = setUpSslChannel(nettyRule.getChannel(), serverCert, caSsc.cert()); + SSLSession sslSession = setUpSslChannel(nettyRule.getClientChannel(), serverCert, caSsc.cert()); nettyRule.assertThatMessagesWork(); assertThat(sslSession.getLocalCertificates()).asList().containsExactly(clientSsc.cert()); @@ -212,7 +266,8 @@ public class SslServerInitializerTest { SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST); LocalAddress localAddress = new LocalAddress("REQUIRE_CLIENT_CERT_" + sslProvider); - nettyRule.setUpServer(localAddress, getServerHandler(serverSsc.key(), serverSsc.cert())); + nettyRule.setUpServer( + localAddress, getServerHandler(true, false, serverSsc.key(), serverSsc.cert())); nettyRule.setUpClient( localAddress, getClientHandler( @@ -225,7 +280,7 @@ public class SslServerInitializerTest { // should throw exceptions. nettyRule.assertThatServerRootCause().isInstanceOf(SSLHandshakeException.class); nettyRule.assertThatClientRootCause().isInstanceOf(SSLException.class); - assertThat(nettyRule.getChannel().isActive()).isFalse(); + assertThat(nettyRule.getClientChannel().isActive()).isFalse(); } @Test @@ -233,7 +288,8 @@ public class SslServerInitializerTest { SelfSignedCertificate serverSsc = new SelfSignedCertificate("wrong.com"); LocalAddress localAddress = new LocalAddress("WRONG_HOSTNAME_" + sslProvider); - nettyRule.setUpServer(localAddress, getServerHandler(serverSsc.key(), serverSsc.cert())); + nettyRule.setUpServer( + localAddress, getServerHandler(true, false, serverSsc.key(), serverSsc.cert())); SelfSignedCertificate clientSsc = new SelfSignedCertificate(); nettyRule.setUpClient( localAddress, getClientHandler(serverSsc.cert(), clientSsc.key(), clientSsc.cert())); @@ -243,6 +299,6 @@ public class SslServerInitializerTest { nettyRule.assertThatClientRootCause().isInstanceOf(CertificateException.class); nettyRule.assertThatClientRootCause().hasMessageThat().contains(SSL_HOST); nettyRule.assertThatServerRootCause().isInstanceOf(SSLException.class); - assertThat(nettyRule.getChannel().isActive()).isFalse(); + assertThat(nettyRule.getClientChannel().isActive()).isFalse(); } } diff --git a/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java b/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java index b9b00cba8..b39e59e5d 100644 --- a/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java +++ b/proxy/src/main/java/google/registry/proxy/EppProtocolModule.java @@ -162,7 +162,8 @@ public final class EppProtocolModule { SslProvider sslProvider, Supplier privateKeySupplier, Supplier> certificatesSupplier) { - return new SslServerInitializer<>(true, sslProvider, privateKeySupplier, certificatesSupplier); + return new SslServerInitializer<>( + true, false, sslProvider, privateKeySupplier, certificatesSupplier); } @Provides diff --git a/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java b/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java index 0242c3a33..0ee0bb417 100644 --- a/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java +++ b/proxy/src/main/java/google/registry/proxy/WebWhoisProtocolsModule.java @@ -134,6 +134,7 @@ public final class WebWhoisProtocolsModule { SslProvider sslProvider, Supplier privateKeySupplier, Supplier> certificatesSupplier) { - return new SslServerInitializer<>(false, sslProvider, privateKeySupplier, certificatesSupplier); + return new SslServerInitializer<>( + false, false, sslProvider, privateKeySupplier, certificatesSupplier); } }