From 29e64fefbcc9c2bd694ae152c38785f22f65a079 Mon Sep 17 00:00:00 2001 From: Gus Brodman Date: Fri, 29 May 2026 13:25:05 -0400 Subject: [PATCH] Forbid deprecated algorithms in DNSSEC data This is similar to PR #3069 but for the algorithms themselves rather than the digest data. This forbids algorithms, that, according to RFC 9904, should not be used. --- .../flows/domain/DomainFlowUtils.java | 4 ++ .../model/domain/secdns/DomainDsDataBase.java | 12 ++++ .../java/google/registry/tools/DsRecord.java | 3 +- .../flows/domain/DomainCreateFlowTest.java | 40 +++++++++++- .../flows/domain/DomainInfoFlowTest.java | 8 +-- .../flows/domain/DomainUpdateFlowTest.java | 65 +++++++++++++++---- .../tools/CreateDomainCommandTest.java | 40 +++++++++--- .../tools/UpdateDomainCommandTest.java | 24 +++++++ .../flows/domain/domain_create_dsdata.xml | 2 +- .../domain/domain_create_dsdata_8_records.xml | 16 ++--- .../domain/domain_create_dsdata_9_records.xml | 18 ++--- .../domain_create_dsdata_bad_algorithms.xml | 12 ++-- .../domain_create_dsdata_bad_digest_types.xml | 16 ++--- ...main_create_dsdata_forbidden_algorithm.xml | 32 +++++++++ .../domain_create_dsdata_no_maxsiglife.xml | 2 +- .../domain/domain_create_dsdata_sha1.xml | 2 +- .../domain/domain_create_wrong_extension.xml | 2 +- .../domain/domain_info_response_dsdata.xml | 6 +- .../domain_info_response_dsdata_addperiod.xml | 6 +- .../domain/domain_update_dsdata_add_rem.xml | 4 +- .../domain_update_dsdata_add_rem_same.xml | 4 +- .../flows/domain/domain_update_dsdata_rem.xml | 2 +- .../domain/domain_update_dsdata_urgent.xml | 2 +- ...ain_update_restore_request_with_secdns.xml | 2 +- .../domain/domain_update_wrong_extension.xml | 2 +- .../flows/domain_update_dsdata_add.xml | 2 +- .../flows/domain_update_dsdata_rem.xml | 2 +- .../registry/model/domain_create_dsdata.xml | 2 +- .../model/domain_update_with_secdns.xml | 2 +- .../tools/server/domain_create_complete.xml | 4 +- 30 files changed, 256 insertions(+), 82 deletions(-) create mode 100644 core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_forbidden_algorithm.xml diff --git a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java index a44a9d39b12..fff9bfa826c 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java +++ b/core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java @@ -389,6 +389,10 @@ public static boolean algorithmIsInvalid(int alg) { if (alg > 255 || alg < 0) { return true; } + if (DomainDsData.FORBIDDEN_ALGORITHMS.contains(alg) + && FeatureFlag.isActiveNow(FORBID_INSECURE_ALGORITHMS_RFC_9904)) { + return true; + } // Algorithms that are reserved or unassigned will just return a string representation of their // integer wire value. String algorithm = Algorithm.string(alg); diff --git a/core/src/main/java/google/registry/model/domain/secdns/DomainDsDataBase.java b/core/src/main/java/google/registry/model/domain/secdns/DomainDsDataBase.java index 81509fac3d1..975e1ff7fc2 100644 --- a/core/src/main/java/google/registry/model/domain/secdns/DomainDsDataBase.java +++ b/core/src/main/java/google/registry/model/domain/secdns/DomainDsDataBase.java @@ -14,6 +14,7 @@ package google.registry.model.domain.secdns; +import com.google.common.collect.ImmutableSet; import google.registry.model.ImmutableObject; import google.registry.model.UnsafeSerializable; import jakarta.persistence.Access; @@ -26,6 +27,7 @@ import jakarta.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.adapters.HexBinaryAdapter; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.xbill.DNS.DNSSEC.Algorithm; /** Base class for {@link DomainDsData} and {@link DomainDsDataHistory}. */ @MappedSuperclass @@ -33,6 +35,16 @@ @XmlType(propOrder = {"keyTag", "algorithm", "digestType", "digest"}) public abstract class DomainDsDataBase extends ImmutableObject implements UnsafeSerializable { + // A set of algorithms that we do not allow. See RFC 9904 for more details. + public static final ImmutableSet FORBIDDEN_ALGORITHMS = + ImmutableSet.of( + Algorithm.RSAMD5, + Algorithm.RSASHA1, + Algorithm.RSA_NSEC3_SHA1, + Algorithm.DSA, + Algorithm.DSA_NSEC3_SHA1, + Algorithm.ECC_GOST); + @XmlTransient @Transient @Insignificant String domainRepoId; /** The identifier for this particular key in the domain. */ diff --git a/core/src/main/java/google/registry/tools/DsRecord.java b/core/src/main/java/google/registry/tools/DsRecord.java index 5d4b943ddfe..10872c04a05 100644 --- a/core/src/main/java/google/registry/tools/DsRecord.java +++ b/core/src/main/java/google/registry/tools/DsRecord.java @@ -15,6 +15,7 @@ package google.registry.tools; import static com.google.common.base.Preconditions.checkArgument; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.util.PreconditionsUtils.checkArgumentPresent; import com.beust.jcommander.IStringConverter; @@ -46,7 +47,7 @@ private static DsRecord create(int keyTag, int alg, int digestType, String diges String.format("DS record has an invalid digest length: %s", digest)); } - if (DomainFlowUtils.algorithmIsInvalid(alg)) { + if (tm().reTransact(() -> DomainFlowUtils.algorithmIsInvalid(alg))) { throw new IllegalArgumentException( String.format("DS record uses an unrecognized algorithm: %d", alg)); } diff --git a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java index 9e4147a9fd4..c86be82a184 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainCreateFlowTest.java @@ -798,7 +798,7 @@ void testSuccess_secDns() throws Exception { .hasExactlyDsData( DomainDsData.create( 12345, - 3, + 8, 2, base16() .decode("D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A")) @@ -992,7 +992,7 @@ void testSuccess_secDnsSha1_flagInactive() throws Exception { .that(domain) .hasExactlyDsData( DomainDsData.create( - 12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC49FD46E6C4B45C55D4AC")) + 12345, 8, 1, base16().decode("49FD46E6C4B45C55D4AC49FD46E6C4B45C55D4AC")) .cloneWithDomainRepoId(domain.getRepoId())); } @@ -1004,6 +1004,42 @@ void testFailure_secDnsInvalidAlgorithm() throws Exception { assertAboutEppExceptions().that(thrown).marshalsToXml(); } + @Test + void testFailure_secDnsForbiddenAlgorithm() throws Exception { + setEppInput("domain_create_dsdata_forbidden_algorithm.xml"); + persistHosts(); + DatabaseHelper.persistResource( + new FeatureFlag.Builder() + .setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904) + .setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.ACTIVE)) + .build()); + EppException thrown = assertThrows(InvalidDsRecordException.class, this::runFlow); + assertAboutEppExceptions().that(thrown).marshalsToXml(); + } + + @Test + void testSuccess_secDnsForbiddenAlgorithm_flagInactive() throws Exception { + setEppInput("domain_create_dsdata_forbidden_algorithm.xml"); + persistHosts(); + DatabaseHelper.persistResource( + new FeatureFlag.Builder() + .setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904) + .setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.INACTIVE)) + .build()); + doSuccessfulTest("tld"); + Domain domain = reloadResourceByForeignKey(); + assertAboutDomains() + .that(domain) + .hasExactlyDsData( + DomainDsData.create( + 12345, + 1, + 2, + base16() + .decode("D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A")) + .cloneWithDomainRepoId(domain.getRepoId())); + } + @Test void testFailure_wrongExtension() { setEppInput("domain_create_wrong_extension.xml"); diff --git a/core/src/test/java/google/registry/flows/domain/DomainInfoFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainInfoFlowTest.java index 47e267625a6..c31e158c852 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainInfoFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainInfoFlowTest.java @@ -98,6 +98,8 @@ class DomainInfoFlowTest extends ResourceFlowTestCase { "UNIT", "y"); private static final Pattern OK_PATTERN = Pattern.compile("\"ok\""); + private static final String SHA_256_DIGEST = + "D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A"; private Host host1; private Host host2; @@ -314,8 +316,7 @@ void testSuccess_secDns() throws Exception { domain .asBuilder() .setDsData( - ImmutableSet.of( - DomainDsData.create(12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC")))) + ImmutableSet.of(DomainDsData.create(12345, 8, 2, base16().decode(SHA_256_DIGEST)))) .setNameservers(ImmutableSet.of(host1.createVKey(), host3.createVKey())) .build()); doSuccessfulTest("domain_info_response_dsdata.xml", false); @@ -519,8 +520,7 @@ void testSuccess_secDnsAndAddGracePeriod() throws Exception { "TheRegistrar", null)) .setDsData( - ImmutableSet.of( - DomainDsData.create(12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC")))) + ImmutableSet.of(DomainDsData.create(12345, 8, 2, base16().decode(SHA_256_DIGEST)))) .build()); doSuccessfulTest("domain_info_response_dsdata_addperiod.xml", false); } diff --git a/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java index b49b6b7c4e4..ec2cc664599 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java @@ -130,7 +130,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase OTHER_DSDATA_TEMPLATE_MAP = ImmutableMap.of( "KEY_TAG", "12346", - "ALG", "3", + "ALG", "8", "DIGEST_TYPE", "2", "DIGEST", SHA_256_DIGEST); @@ -459,9 +459,9 @@ void testSuccess_secDnsAdd() throws Exception { doSecDnsSuccessfulTest( "domain_update_dsdata_add.xml", null, - ImmutableSet.of(DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))), + ImmutableSet.of(DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))), ImmutableMap.of( - "KEY_TAG", "12346", "ALG", "3", "DIGEST_TYPE", "2", "DIGEST", SHA_256_DIGEST), + "KEY_TAG", "12346", "ALG", "8", "DIGEST_TYPE", "2", "DIGEST", SHA_256_DIGEST), true); } @@ -471,9 +471,9 @@ void testSuccess_secDnsAddPreservesExisting() throws Exception { "domain_update_dsdata_add.xml", ImmutableSet.of(SOME_DSDATA), ImmutableSet.of( - SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))), + SOME_DSDATA, DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))), ImmutableMap.of( - "KEY_TAG", "12346", "ALG", "3", "DIGEST_TYPE", "2", "DIGEST", SHA_256_DIGEST), + "KEY_TAG", "12346", "ALG", "8", "DIGEST_TYPE", "2", "DIGEST", SHA_256_DIGEST), true); } @@ -648,7 +648,7 @@ void testSuccess_secDnsAddToMaxRecords() throws Exception { union( commonDsData, ImmutableSet.of( - DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))))), + DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))))), true); } @@ -657,7 +657,7 @@ void testSuccess_secDnsRemove() throws Exception { doSecDnsSuccessfulTest( "domain_update_dsdata_rem.xml", ImmutableSet.of( - SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))), + SOME_DSDATA, DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))), ImmutableSet.of(SOME_DSDATA), true); } @@ -668,7 +668,7 @@ void testSuccess_secDnsRemoveAll() throws Exception { doSecDnsSuccessfulTest( "domain_update_dsdata_rem_all.xml", ImmutableSet.of( - SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))), + SOME_DSDATA, DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))), ImmutableSet.of(), true); } @@ -678,9 +678,9 @@ void testSuccess_secDnsAddRemove() throws Exception { doSecDnsSuccessfulTest( "domain_update_dsdata_add_rem.xml", ImmutableSet.of( - SOME_DSDATA, DomainDsData.create(12345, 3, 2, base16().decode(SHA_256_DIGEST))), + SOME_DSDATA, DomainDsData.create(12345, 8, 2, base16().decode(SHA_256_DIGEST))), ImmutableSet.of( - SOME_DSDATA, DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))), + SOME_DSDATA, DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))), true); } @@ -703,12 +703,12 @@ void testSuccess_secDnsAddRemoveToMaxRecords() throws Exception { union( commonDsData, ImmutableSet.of( - DomainDsData.create(12345, 3, 2, base16().decode(SHA_256_DIGEST))))), + DomainDsData.create(12345, 8, 2, base16().decode(SHA_256_DIGEST))))), ImmutableSet.copyOf( union( commonDsData, ImmutableSet.of( - DomainDsData.create(12346, 3, 2, base16().decode(SHA_256_DIGEST))))), + DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))))), true); } @@ -990,6 +990,47 @@ void testFailure_secDnsInvalidAlgorithm() throws Exception { assertAboutEppExceptions().that(thrown).marshalsToXml(); } + @Test + void testFailure_secDnsForbiddenAlgorithm() throws Exception { + setEppInput("domain_update_dsdata_add.xml", OTHER_DSDATA_TEMPLATE_MAP); + persistResource( + DatabaseHelper.newDomain(getUniqueIdFromCommand()) + .asBuilder() + .setDsData( + ImmutableSet.of(DomainDsData.create(1, 1, 2, base16().decode(SHA_256_DIGEST)))) + .build()); + DatabaseHelper.persistResource( + new FeatureFlag.Builder() + .setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904) + .setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.ACTIVE)) + .build()); + EppException thrown = assertThrows(InvalidDsRecordException.class, this::runFlow); + assertAboutEppExceptions().that(thrown).marshalsToXml(); + } + + @Test + void testSuccess_secDnsForbiddenAlgorithm_flagInactive() throws Exception { + setEppInput("domain_update_dsdata_add.xml", OTHER_DSDATA_TEMPLATE_MAP); + persistResource( + DatabaseHelper.newDomain(getUniqueIdFromCommand()) + .asBuilder() + .setDsData( + ImmutableSet.of(DomainDsData.create(1, 1, 2, base16().decode(SHA_256_DIGEST)))) + .build()); + DatabaseHelper.persistResource( + new FeatureFlag.Builder() + .setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904) + .setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.INACTIVE)) + .build()); + runFlow(); + Domain domain = reloadResourceByForeignKey(); + assertAboutDomains() + .that(domain) + .hasExactlyDsData( + DomainDsData.create(1, 1, 2, base16().decode(SHA_256_DIGEST)), + DomainDsData.create(12346, 8, 2, base16().decode(SHA_256_DIGEST))); + } + @Test void testFailure_secDnsMultipleInvalidAlgorithms() throws Exception { setEppInput("domain_update_dsdata_add.xml", OTHER_DSDATA_TEMPLATE_MAP); diff --git a/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java b/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java index 9176a1e3679..cddb50879f8 100644 --- a/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java +++ b/core/src/test/java/google/registry/tools/CreateDomainCommandTest.java @@ -15,16 +15,21 @@ package google.registry.tools; import static com.google.common.truth.Truth.assertThat; +import static google.registry.model.common.FeatureFlag.FeatureName.FORBID_INSECURE_ALGORITHMS_RFC_9904; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.persistPremiumList; import static google.registry.testing.DatabaseHelper.persistResource; +import static google.registry.util.DateTimeUtils.START_INSTANT; import static org.joda.money.CurrencyUnit.JPY; import static org.junit.jupiter.api.Assertions.assertThrows; import com.beust.jcommander.ParameterException; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedMap; import google.registry.dns.writer.VoidDnsWriter; +import google.registry.model.common.FeatureFlag; +import google.registry.model.common.FeatureFlag.FeatureStatus; import google.registry.model.pricing.StaticPremiumListPricingEngine; import google.registry.model.tld.Tld; import google.registry.model.tld.label.PremiumListDao; @@ -49,9 +54,9 @@ void testSuccess_complete() throws Exception { "--period=1", "--nameservers=ns1.zdns.google,ns2.zdns.google,ns3.zdns.google,ns4.zdns.google", "--password=2fooBAR", - "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2" + "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 8 2" + " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", - "--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", + "--ds_records=60485 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", "example.tld"); eppVerifier.verifySent("domain_create_complete.xml"); } @@ -63,9 +68,9 @@ void testSuccess_completeWithCanonicalization() throws Exception { "--period=1", "--nameservers=NS1.zdns.google,ns2.ZDNS.google,ns3.zdns.gOOglE,ns4.zdns.google", "--password=2fooBAR", - "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2" + "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 8 2" + " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", - "--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", + "--ds_records=60485 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", "example.tld"); eppVerifier.verifySent("domain_create_complete.xml"); } @@ -77,9 +82,9 @@ void testSuccess_completeWithSquareBrackets() throws Exception { "--period=1", "--nameservers=ns[1-4].zdns.google", "--password=2fooBAR", - "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2" + "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 8 2" + " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", - "--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", + "--ds_records=60485 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", "example.tld"); eppVerifier.verifySent("domain_create_complete.xml"); } @@ -91,9 +96,9 @@ void testSuccess_completeWithSquareBracketsAndCanonicalization() throws Exceptio "--period=1", "--nameservers=NS[1-4].zdns.google", "--password=2fooBAR", - "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 5 2" + "--ds_records=1 2 2 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08,4 8 2" + " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", - "--ds_records=60485 5 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", + "--ds_records=60485 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", "example.tld"); eppVerifier.verifySent("domain_create_complete.xml"); } @@ -279,6 +284,25 @@ void testFailure_invalidDigestType() { assertThat(thrown).hasMessageThat().isEqualTo("DS record uses an unrecognized digest type: 3"); } + @Test + void testFailure_forbiddenAlgorithm() { + persistResource( + new FeatureFlag.Builder() + .setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904) + .setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.ACTIVE)) + .build()); + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> + runCommandForced( + "--client=NewRegistrar", + "--ds_records=1 1 2" + + " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", + "example.tld")); + assertThat(thrown).hasMessageThat().isEqualTo("DS record uses an unrecognized algorithm: 1"); + } + @Test void testFailure_invalidDigestLength() { IllegalArgumentException thrown = diff --git a/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java b/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java index 8511def829f..601929f1217 100644 --- a/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java +++ b/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java @@ -15,6 +15,7 @@ package google.registry.tools; import static com.google.common.truth.Truth.assertThat; +import static google.registry.model.common.FeatureFlag.FeatureName.FORBID_INSECURE_ALGORITHMS_RFC_9904; import static google.registry.model.domain.rgp.GracePeriodStatus.AUTO_RENEW; import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE; import static google.registry.model.eppcommon.StatusValue.SERVER_UPDATE_PROHIBITED; @@ -26,6 +27,7 @@ import static google.registry.testing.TestLogHandlerUtils.assertLogMessage; import static google.registry.testing.TestLogHandlerUtils.assertNoLogMessage; import static google.registry.util.DateTimeUtils.END_INSTANT; +import static google.registry.util.DateTimeUtils.START_INSTANT; import static google.registry.util.DateTimeUtils.minusDays; import static google.registry.util.DateTimeUtils.plusDays; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -33,9 +35,12 @@ import com.beust.jcommander.ParameterException; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedMap; import google.registry.model.billing.BillingBase.Flag; import google.registry.model.billing.BillingBase.Reason; import google.registry.model.billing.BillingRecurrence; +import google.registry.model.common.FeatureFlag; +import google.registry.model.common.FeatureFlag.FeatureStatus; import google.registry.model.domain.Domain; import google.registry.model.domain.DomainHistory; import google.registry.model.domain.GracePeriod; @@ -535,6 +540,25 @@ void testFailure_invalidDsRecordDigestType() { assertThat(thrown).hasMessageThat().isEqualTo("DS record uses an unrecognized digest type: 3"); } + @Test + void testFailure_forbiddenDsRecordAlgorithm() { + persistResource( + new FeatureFlag.Builder() + .setFeatureName(FORBID_INSECURE_ALGORITHMS_RFC_9904) + .setStatusMap(ImmutableSortedMap.of(START_INSTANT, FeatureStatus.ACTIVE)) + .build()); + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> + runCommandForced( + "--client=NewRegistrar", + "--add_ds_records=1 1 2" + + " D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A", + "example.tld")); + assertThat(thrown).hasMessageThat().isEqualTo("DS record uses an unrecognized algorithm: 1"); + } + @Test void testFailure_invalidDigestLength() { IllegalArgumentException thrown = diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata.xml index 11ea18d03a9..17eaf4c5331 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata.xml @@ -22,7 +22,7 @@ 604800 12345 - 3 + 8 1 49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_8_records.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_8_records.xml index 637f559265e..b51ce825339 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_8_records.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_8_records.xml @@ -21,49 +21,49 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 12346 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 12347 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 12348 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 12349 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 12350 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 12351 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 12352 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_9_records.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_9_records.xml index 23c14f839ef..66565a17a24 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_9_records.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_9_records.xml @@ -21,55 +21,55 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 + 8 1 49FD46E6C4B45C55D4AC 12346 - 3 + 8 1 49FD46E6C4B45C55D4AC 12347 - 3 + 8 1 49FD46E6C4B45C55D4AC 12348 - 3 + 8 1 49FD46E6C4B45C55D4AC 12349 - 3 + 8 1 49FD46E6C4B45C55D4AC 12350 - 3 + 8 1 49FD46E6C4B45C55D4AC 12351 - 3 + 8 1 49FD46E6C4B45C55D4AC 12352 - 3 + 8 1 49FD46E6C4B45C55D4AC 12353 - 3 + 8 1 49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_algorithms.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_algorithms.xml index bce11d615f9..b389f76786a 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_algorithms.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_algorithms.xml @@ -27,19 +27,19 @@ 12346 - 3 + 8 1 49FD46E6C4B45C55D4AC 12347 - 3 + 8 1 49FD46E6C4B45C55D4AC 12348 - 3 + 8 1 49FD46E6C4B45C55D4AC @@ -51,19 +51,19 @@ 12350 - 3 + 8 1 49FD46E6C4B45C55D4AC 12351 - 3 + 8 1 49FD46E6C4B45C55D4AC 12352 - 3 + 8 1 49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_digest_types.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_digest_types.xml index 267202bcd02..842232d384b 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_digest_types.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_bad_digest_types.xml @@ -21,49 +21,49 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 + 8 100 49FD46E6C4B45C55D4AC 12346 - 3 + 8 3 49FD46E6C4B45C55D4AC 12347 - 3 + 8 1 49FD46E6C4B45C55D4AC 12348 - 3 + 8 1 49FD46E6C4B45C55D4AC 12349 - 3 + 8 1 49FD46E6C4B45C55D4AC 12350 - 3 + 8 1 49FD46E6C4B45C55D4AC 12351 - 3 + 8 1 49FD46E6C4B45C55D4AC 12352 - 3 + 8 1 49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_forbidden_algorithm.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_forbidden_algorithm.xml new file mode 100644 index 00000000000..8ce86565e39 --- /dev/null +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_forbidden_algorithm.xml @@ -0,0 +1,32 @@ + + + + + + example.tld + 2 + + ns1.example.net + ns2.example.net + + + 2fooBAR + + + + + + + 12345 + 1 + 2 + D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A + + + + ABC-12345 + + diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_no_maxsiglife.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_no_maxsiglife.xml index 94ee4229bac..3aee660a804 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_no_maxsiglife.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_no_maxsiglife.xml @@ -21,7 +21,7 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_sha1.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_sha1.xml index c796aa5ff0c..780410cd133 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_sha1.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_dsdata_sha1.xml @@ -21,7 +21,7 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 + 8 1 49FD46E6C4B45C55D4AC49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/flows/domain/domain_create_wrong_extension.xml b/core/src/test/resources/google/registry/flows/domain/domain_create_wrong_extension.xml index 07ca9374466..87137c5024b 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_create_wrong_extension.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_create_wrong_extension.xml @@ -20,7 +20,7 @@ 12345 - 3 + 8 1 49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata.xml b/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata.xml index c1d8283988c..a1bf1e55f48 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata.xml @@ -34,9 +34,9 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 - 1 - 49FD46E6C4B45C55D4AC + 8 + 2 + D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata_addperiod.xml b/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata_addperiod.xml index 06d335008ce..d898bd6f239 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata_addperiod.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_info_response_dsdata_addperiod.xml @@ -33,9 +33,9 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 - 1 - 49FD46E6C4B45C55D4AC + 8 + 2 + D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem.xml b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem.xml index 1863c839694..7fdab5e00bb 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem.xml @@ -14,7 +14,7 @@ 12345 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A @@ -22,7 +22,7 @@ 12346 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem_same.xml b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem_same.xml index 5fce4574682..9da94a8ec08 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem_same.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_add_rem_same.xml @@ -14,7 +14,7 @@ 12345 - 3 + 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3 @@ -22,7 +22,7 @@ 12345 - 3 + 8 1 A94A8FE5CCB19BA61C4C0873D391E987982FBBD3 diff --git a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_rem.xml b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_rem.xml index 8178fb13da8..38e88fe1bd2 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_rem.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_rem.xml @@ -14,7 +14,7 @@ 12346 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_urgent.xml b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_urgent.xml index 7c82a7cec9d..3ae1a69f709 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_urgent.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_update_dsdata_urgent.xml @@ -17,7 +17,7 @@ 12346 - 3 + 8 1 38EC35D5B3A34B44C39B diff --git a/core/src/test/resources/google/registry/flows/domain/domain_update_restore_request_with_secdns.xml b/core/src/test/resources/google/registry/flows/domain/domain_update_restore_request_with_secdns.xml index a439b747e92..b54e4f7a9ae 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_update_restore_request_with_secdns.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_update_restore_request_with_secdns.xml @@ -16,7 +16,7 @@ 12346 - 3 + 8 1 38EC35D5B3A34B44C39B diff --git a/core/src/test/resources/google/registry/flows/domain/domain_update_wrong_extension.xml b/core/src/test/resources/google/registry/flows/domain/domain_update_wrong_extension.xml index c006d44fad9..25d4ff979be 100644 --- a/core/src/test/resources/google/registry/flows/domain/domain_update_wrong_extension.xml +++ b/core/src/test/resources/google/registry/flows/domain/domain_update_wrong_extension.xml @@ -13,7 +13,7 @@ xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"> 12345 - 3 + 8 1 49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/flows/domain_update_dsdata_add.xml b/core/src/test/resources/google/registry/flows/domain_update_dsdata_add.xml index f6468061a43..8646af967d0 100644 --- a/core/src/test/resources/google/registry/flows/domain_update_dsdata_add.xml +++ b/core/src/test/resources/google/registry/flows/domain_update_dsdata_add.xml @@ -14,7 +14,7 @@ 12346 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/flows/domain_update_dsdata_rem.xml b/core/src/test/resources/google/registry/flows/domain_update_dsdata_rem.xml index 8178fb13da8..38e88fe1bd2 100644 --- a/core/src/test/resources/google/registry/flows/domain_update_dsdata_rem.xml +++ b/core/src/test/resources/google/registry/flows/domain_update_dsdata_rem.xml @@ -14,7 +14,7 @@ 12346 - 3 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A diff --git a/core/src/test/resources/google/registry/model/domain_create_dsdata.xml b/core/src/test/resources/google/registry/model/domain_create_dsdata.xml index 89f5721d79c..077474d81a8 100644 --- a/core/src/test/resources/google/registry/model/domain_create_dsdata.xml +++ b/core/src/test/resources/google/registry/model/domain_create_dsdata.xml @@ -23,7 +23,7 @@ 604800 12345 - 3 + 8 1 49FD46E6C4B45C55D4AC diff --git a/core/src/test/resources/google/registry/model/domain_update_with_secdns.xml b/core/src/test/resources/google/registry/model/domain_update_with_secdns.xml index dd113cec54a..9752e5f450a 100644 --- a/core/src/test/resources/google/registry/model/domain_update_with_secdns.xml +++ b/core/src/test/resources/google/registry/model/domain_update_with_secdns.xml @@ -16,7 +16,7 @@ 12346 - 3 + 8 1 38EC35D5B3A34B44C39B diff --git a/core/src/test/resources/google/registry/tools/server/domain_create_complete.xml b/core/src/test/resources/google/registry/tools/server/domain_create_complete.xml index f2e1e724280..c80c7a08d34 100644 --- a/core/src/test/resources/google/registry/tools/server/domain_create_complete.xml +++ b/core/src/test/resources/google/registry/tools/server/domain_create_complete.xml @@ -27,13 +27,13 @@ 4 - 5 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A 60485 - 5 + 8 2 D4B7D520E7BB5F0F67674A0CCEB1E3E0614B93C4F9E99B8383F6A1E4469DA50A