1
0
mirror of https://github.com/google/nomulus synced 2026-03-16 23:54:59 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
gbrodman
f2cfd36b73 Always allow both TLS 1.2 and 1.3 (#2978)
The JDK version of SSL has long supported TLS v1.3 (since version 11) so
fortunately we can use TLS v1.3 regardless if which implementation of
SSL we're using.

We prefer OpenSSL in general so I'm not entirely sure why we were using
the JDK version of SSL on the proxy before, but this should work and be
a good idea regardless.

Tested on alpha by running

```
$ openssl s_client -connect epp.registryalpha.foo:700 -tls1_3 -ciphersuites "TLS_AES_128_GCM_SHA256"
```

Previously we'd get a failure, now it returns the proper cert data.
2026-03-09 22:51:17 +00:00
Weimin Yu
8ea5fe3774 Enable Fee-1.0 extension in prod (#2975)
This extension has been in Sandbox for more than a month.
2026-03-05 20:22:33 +00:00
7 changed files with 76 additions and 21 deletions

View File

@@ -68,6 +68,10 @@ public class FeatureFlag extends ImmutableObject implements Buildable {
/** Feature flag name used for testing only. */
TEST_FEATURE(FeatureStatus.INACTIVE),
/** True if Fee Extension 1.0 (RFC 8748) is enabled in production. */
// TODO(b/159033801) Delete this flag after 1.0 is hardened in prod.
FEE_EXTENSION_1_DOT_0_IN_PROD(FeatureStatus.INACTIVE),
/** If we're not requiring the presence of contact data on domain EPP commands. */
MINIMUM_DATASET_CONTACTS_OPTIONAL(FeatureStatus.INACTIVE),

View File

@@ -16,11 +16,14 @@ package google.registry.model.eppcommon;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Maps.uniqueIndex;
import static google.registry.model.common.FeatureFlag.FeatureName.FEE_EXTENSION_1_DOT_0_IN_PROD;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import google.registry.model.common.FeatureFlag;
import google.registry.model.domain.fee06.FeeCheckCommandExtensionV06;
import google.registry.model.domain.fee06.FeeCheckResponseExtensionV06;
import google.registry.model.domain.fee11.FeeCheckCommandExtensionV11;
@@ -58,7 +61,7 @@ public class ProtocolDefinition {
/** Enum representing which environments should have which service extensions enabled. */
private enum ServiceExtensionVisibility {
ALL,
ONLY_IN_NON_PRODUCTION,
FEE_1_DOT_0_EXTENSION_VISIBILITY,
NONE
}
@@ -82,7 +85,7 @@ public class ProtocolDefinition {
FEE_1_00(
FeeCheckCommandExtensionStdV1.class,
FeeCheckResponseExtensionStdV1.class,
ServiceExtensionVisibility.ONLY_IN_NON_PRODUCTION),
ServiceExtensionVisibility.FEE_1_DOT_0_EXTENSION_VISIBILITY),
METADATA_1_0(MetadataExtension.class, null, ServiceExtensionVisibility.NONE);
private final Class<? extends CommandExtension> commandExtensionClass;
@@ -138,8 +141,9 @@ public class ProtocolDefinition {
public boolean isVisible() {
return switch (visibility) {
case ALL -> true;
case ONLY_IN_NON_PRODUCTION ->
!RegistryEnvironment.get().equals(RegistryEnvironment.PRODUCTION);
case FEE_1_DOT_0_EXTENSION_VISIBILITY ->
!RegistryEnvironment.get().equals(RegistryEnvironment.PRODUCTION)
|| tm().transact(() -> FeatureFlag.isActiveNow(FEE_EXTENSION_1_DOT_0_IN_PROD));
case NONE -> false;
};
}

View File

@@ -91,7 +91,7 @@ public enum RegistryToolEnvironment {
/** Sets up execution environment. Call this method before any classes are loaded. */
@VisibleForTesting
void setup(SystemPropertySetter systemPropertySetter) {
public void setup(SystemPropertySetter systemPropertySetter) {
instance = this;
actualEnvironment.setup(systemPropertySetter);
for (Map.Entry<String, String> entry : extraProperties.entrySet()) {

View File

@@ -15,15 +15,21 @@
package google.registry.flows.domain;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.common.FeatureFlag.FeatureName.FEE_EXTENSION_1_DOT_0_IN_PROD;
import static google.registry.tools.RegistryToolEnvironment.PRODUCTION;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import google.registry.model.eppcommon.ProtocolDefinition;
import google.registry.tools.CommandTestCase;
import google.registry.tools.ConfigureFeatureFlagCommand;
import google.registry.util.RegistryEnvironment;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Class for testing the XML extension definitions loaded in the prod environment. */
public class ProductionSimulatingFeeExtensionsTest {
public class ProductionSimulatingFeeExtensionsTest
extends CommandTestCase<ConfigureFeatureFlagCommand> {
private RegistryEnvironment previousEnvironment;
@@ -59,7 +65,7 @@ public class ProductionSimulatingFeeExtensionsTest {
}
@Test
void testProdEnvironment() {
void testProdEnvironment_feeExtensionFeatureNotSet() {
RegistryEnvironment.PRODUCTION.setup();
ProtocolDefinition.reloadServiceExtensionUris();
// prod shouldn't have the fee extension version 1.0
@@ -72,4 +78,47 @@ public class ProductionSimulatingFeeExtensionsTest {
"urn:ietf:params:xml:ns:fee-0.11",
"urn:ietf:params:xml:ns:fee-0.12");
}
@Test
void testProdEnvironment_feeExtensionFeatureActiveInTheFuture() throws Exception {
runCommandInEnvironment(
PRODUCTION,
FEE_EXTENSION_1_DOT_0_IN_PROD.name(),
"--force",
"--status_map",
String.format("%s=INACTIVE,%s=ACTIVE", START_OF_TIME, fakeClock.nowUtc().plusMillis(1)));
RegistryEnvironment.PRODUCTION.setup();
ProtocolDefinition.reloadServiceExtensionUris();
// prod shouldn't have the fee extension version 1.0
assertThat(ProtocolDefinition.getVisibleServiceExtensionUris())
.containsExactly(
"urn:ietf:params:xml:ns:launch-1.0",
"urn:ietf:params:xml:ns:rgp-1.0",
"urn:ietf:params:xml:ns:secDNS-1.1",
"urn:ietf:params:xml:ns:fee-0.6",
"urn:ietf:params:xml:ns:fee-0.11",
"urn:ietf:params:xml:ns:fee-0.12");
}
@Test
void testProdEnvironment_feeExtensionFeatureActiveInThePast() throws Exception {
runCommandInEnvironment(
PRODUCTION,
FEE_EXTENSION_1_DOT_0_IN_PROD.name(),
"--force",
"--status_map",
String.format("%s=INACTIVE,%s=ACTIVE", START_OF_TIME, fakeClock.nowUtc().minusMillis(1)));
RegistryEnvironment.PRODUCTION.setup();
ProtocolDefinition.reloadServiceExtensionUris();
// prod should have the fee extension version 1.0
assertThat(ProtocolDefinition.getVisibleServiceExtensionUris())
.containsExactly(
"urn:ietf:params:xml:ns:launch-1.0",
"urn:ietf:params:xml:ns:rgp-1.0",
"urn:ietf:params:xml:ns:secDNS-1.1",
"urn:ietf:params:xml:ns:fee-0.6",
"urn:ietf:params:xml:ns:fee-0.11",
"urn:ietf:params:xml:ns:fee-0.12",
"urn:ietf:params:xml:ns:epp:fee-1.0");
}
}

View File

@@ -94,7 +94,8 @@ public abstract class CommandTestCase<C extends Command> {
System.setErr(oldStderr);
}
void runCommandInEnvironment(RegistryToolEnvironment env, String... args) throws Exception {
protected void runCommandInEnvironment(RegistryToolEnvironment env, String... args)
throws Exception {
env.setup(systemPropertyExtension);
try {
JCommander jcommander = new JCommander(command);

View File

@@ -333,7 +333,7 @@
);
create table "FeatureFlag" (
feature_name text not null check (feature_name in ('TEST_FEATURE','MINIMUM_DATASET_CONTACTS_OPTIONAL','MINIMUM_DATASET_CONTACTS_PROHIBITED','INCLUDE_PENDING_DELETE_DATE_FOR_DOMAINS','PROHIBIT_CONTACT_OBJECTS_ON_LOGIN')),
feature_name text not null check (feature_name in ('TEST_FEATURE','FEE_EXTENSION_1_DOT_0_IN_PROD','MINIMUM_DATASET_CONTACTS_OPTIONAL','MINIMUM_DATASET_CONTACTS_PROHIBITED','INCLUDE_PENDING_DELETE_DATE_FOR_DOMAINS','PROHIBIT_CONTACT_OBJECTS_ON_LOGIN')),
status hstore not null,
primary key (feature_name)
);

View File

@@ -70,10 +70,10 @@ public class SslServerInitializer<C extends Channel> extends ChannelInitializer<
/**
* The list of cipher suites that are currently acceptable to create a successful handshake.
*
* <p>This list includes all of the current TLS1.3 ciphers and a collection of TLS1.2 ciphers with
* no known security vulnerabilities. Note that OpenSSL uses a separate nomenclature for the
* ciphers internally but the IANA names listed here will be transparently translated by the
* OpenSSL provider (if used), so there is no need to include the OpenSSL name variants here. More
* <p>This list includes all the current TLS1.3 ciphers and a collection of TLS1.2 ciphers with no
* known security vulnerabilities. Note that OpenSSL uses a separate nomenclature for the ciphers
* internally but the IANA names listed here will be transparently translated by the OpenSSL
* provider (if used), so there is no need to include the OpenSSL name variants here. More
* information about these cipher suites and their OpenSSL names can be found at ciphersuite.info.
*/
private static final ImmutableList<String> ALLOWED_TLS_CIPHERS =
@@ -90,6 +90,10 @@ public class SslServerInitializer<C extends Channel> extends ChannelInitializer<
"TLS_AES_128_CCM_SHA256",
"TLS_AES_128_CCM_8_SHA256");
/** Thankfully, the JDK supports TLS version 1.3 now. */
private static final ImmutableList<String> SUPPORTED_TLS_VERSIONS =
ImmutableList.of("TLSv1.3", "TLSv1.2");
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final boolean requireClientCert;
// TODO(jianglai): Always validate client certs (if required).
@@ -99,7 +103,6 @@ public class SslServerInitializer<C extends Channel> extends ChannelInitializer<
// change when the artifacts on GCS changes.
private final Supplier<PrivateKey> privateKeySupplier;
private final Supplier<ImmutableList<X509Certificate>> certificatesSupplier;
private final ImmutableList<String> supportedSslVersions;
public SslServerInitializer(
boolean requireClientCert,
@@ -116,12 +119,6 @@ public class SslServerInitializer<C extends Channel> extends ChannelInitializer<
this.sslProvider = sslProvider;
this.privateKeySupplier = privateKeySupplier;
this.certificatesSupplier = certificatesSupplier;
this.supportedSslVersions =
sslProvider == SslProvider.OPENSSL
? ImmutableList.of("TLSv1.3", "TLSv1.2")
// 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");
}
@Override
@@ -133,7 +130,7 @@ public class SslServerInitializer<C extends Channel> extends ChannelInitializer<
.sslProvider(sslProvider)
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.clientAuth(requireClientCert ? ClientAuth.REQUIRE : ClientAuth.NONE)
.protocols(supportedSslVersions)
.protocols(SUPPORTED_TLS_VERSIONS)
.ciphers(ALLOWED_TLS_CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
.build();