Daggerize TMCH/signed mark util classes

This allows them to support injectable configuration.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=143709052
This commit is contained in:
mcilwain 2017-01-05 14:26:18 -08:00 committed by Ben McIlwain
parent 534e3ba01c
commit c05424b947
19 changed files with 242 additions and 165 deletions

View file

@ -48,7 +48,12 @@ import org.xml.sax.SAXException;
/** TMCH utility functions for domain flows. */ /** TMCH utility functions for domain flows. */
public final class DomainFlowTmchUtils { public final class DomainFlowTmchUtils {
@Inject public DomainFlowTmchUtils() {} private final TmchXmlSignature tmchXmlSignature;
@Inject
public DomainFlowTmchUtils(TmchXmlSignature tmchXmlSignature) {
this.tmchXmlSignature = tmchXmlSignature;
}
public SignedMark verifySignedMarks( public SignedMark verifySignedMarks(
ImmutableList<AbstractSignedMark> signedMarks, String domainLabel, DateTime now) ImmutableList<AbstractSignedMark> signedMarks, String domainLabel, DateTime now)
@ -86,7 +91,7 @@ public final class DomainFlowTmchUtils {
} }
try { try {
TmchXmlSignature.verify(signedMarkData); tmchXmlSignature.verify(signedMarkData);
} catch (CertificateExpiredException e) { } catch (CertificateExpiredException e) {
throw new SignedMarkCertificateExpiredException(); throw new SignedMarkCertificateExpiredException();
} catch (CertificateNotYetValidException e) { } catch (CertificateNotYetValidException e) {

View file

@ -37,6 +37,7 @@ public final class TmchCrl extends CrossTldSingleton {
String crl; String crl;
DateTime updated; DateTime updated;
String url;
/** Returns the singleton instance of this entity, without memoization. */ /** Returns the singleton instance of this entity, without memoization. */
@Nullable @Nullable
@ -50,13 +51,14 @@ public final class TmchCrl extends CrossTldSingleton {
* <p>Please do not call this function unless your CRL is properly formatted, signed by the root, * <p>Please do not call this function unless your CRL is properly formatted, signed by the root,
* and actually newer than the one currently in the datastore. * and actually newer than the one currently in the datastore.
*/ */
public static void set(final String crl) { public static void set(final String crl, final String url) {
ofy().transactNew(new VoidWork() { ofy().transactNew(new VoidWork() {
@Override @Override
public void vrun() { public void vrun() {
TmchCrl tmchCrl = new TmchCrl(); TmchCrl tmchCrl = new TmchCrl();
tmchCrl.updated = ofy().getTransactionTime(); tmchCrl.updated = ofy().getTransactionTime();
tmchCrl.crl = checkNotNull(crl, "crl"); tmchCrl.crl = checkNotNull(crl, "crl");
tmchCrl.url = checkNotNull(url, "url");
ofy().saveWithoutBackup().entity(tmchCrl); ofy().saveWithoutBackup().entity(tmchCrl);
}}); }});
} }
@ -66,7 +68,12 @@ public final class TmchCrl extends CrossTldSingleton {
return crl; return crl;
} }
/** Time we last updated the datastore with a newer ICANN CRL. */ /** Returns the URL that the CRL was downloaded from. */
public final String getUrl() {
return crl;
}
/** Time we last updated the Datastore with a newer ICANN CRL. */
public final DateTime getUpdated() { public final DateTime getUpdated() {
return updated; return updated;
} }

View file

@ -14,13 +14,13 @@
package google.registry.tmch; package google.registry.tmch;
import static com.google.common.base.Throwables.propagateIfInstanceOf;
import static google.registry.util.CacheUtils.memoizeWithLongExpiration;
import static google.registry.util.CacheUtils.memoizeWithShortExpiration;
import static google.registry.util.ResourceUtils.readResourceUtf8; import static google.registry.util.ResourceUtils.readResourceUtf8;
import static google.registry.util.X509Utils.loadCrl; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.common.base.Supplier; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import google.registry.config.ConfigModule.Config;
import google.registry.config.RegistryEnvironment; import google.registry.config.RegistryEnvironment;
import google.registry.model.tmch.TmchCrl; import google.registry.model.tmch.TmchCrl;
import google.registry.util.Clock; import google.registry.util.Clock;
@ -30,10 +30,18 @@ import google.registry.util.X509Utils;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.cert.X509CRL; import java.security.cert.X509CRL;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.concurrent.ExecutionException;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
/** Datastore singleton for ICANN's TMCH root certificate and revocation list. */ /**
* Helper methods for accessing ICANN's TMCH root certificate and revocation list.
*
* <p>There are two CRLs, a real one for the production environment and a testing one for
* non-production environments. The Datastore singleton {@link TmchCrl} entity is used to cache this
* CRL once loaded and will always contain the proper one corresponding to the environment.
*/
@Immutable @Immutable
@ThreadSafe @ThreadSafe
public final class TmchCertificateAuthority { public final class TmchCertificateAuthority {
@ -45,44 +53,69 @@ public final class TmchCertificateAuthority {
private static final String CRL_FILE = "icann-tmch.crl"; private static final String CRL_FILE = "icann-tmch.crl";
private static final String TEST_CRL_FILE = "icann-tmch-test.crl"; private static final String TEST_CRL_FILE = "icann-tmch-test.crl";
private boolean tmchCaTestingMode;
public @Inject TmchCertificateAuthority(@Config("tmchCaTestingMode") boolean tmchCaTestingMode) {
this.tmchCaTestingMode = tmchCaTestingMode;
}
/** /**
* A cached supplier that loads the crl from datastore or chooses a default value. * A cached supplier that loads the CRL from Datastore or chooses a default value.
* *
* <p>We keep the cache here rather than caching TmchCrl in the model, because loading the crl * <p>We keep the cache here rather than caching TmchCrl in the model, because loading the CRL
* string into an X509CRL instance is expensive and should itself be cached. * string into an X509CRL instance is expensive and should itself be cached.
*
* <p>Note that the stored CRL won't exist for tests, and on deployed environments will always
* correspond to the correct CRL for the given testing mode because {@link TmchCrlAction} can
* only persist the correct one for this given environment.
*/ */
private static final Supplier<X509CRL> CRL_CACHE = private static final LoadingCache<Boolean, X509CRL> CRL_CACHE =
memoizeWithShortExpiration(new Supplier<X509CRL>() { CacheBuilder.newBuilder()
.expireAfterWrite(
ENVIRONMENT.config().getSingletonCacheRefreshDuration().getMillis(), MILLISECONDS)
.build(
new CacheLoader<Boolean, X509CRL>() {
@Override @Override
public X509CRL get() { public X509CRL load(final Boolean tmchCaTestingMode)
throws GeneralSecurityException {
TmchCrl storedCrl = TmchCrl.get(); TmchCrl storedCrl = TmchCrl.get();
try { try {
X509CRL crl = loadCrl((storedCrl == null) String crlContents;
? readResourceUtf8( if (storedCrl == null) {
TmchCertificateAuthority.class, String file = tmchCaTestingMode.booleanValue() ? TEST_CRL_FILE : CRL_FILE;
ENVIRONMENT.config().getTmchCaTestingMode() ? TEST_CRL_FILE : CRL_FILE) crlContents = readResourceUtf8(TmchCertificateAuthority.class, file);
: storedCrl.getCrl()); } else {
crl.verify(getRoot().getPublicKey()); crlContents = storedCrl.getCrl();
}
X509CRL crl = X509Utils.loadCrl(crlContents);
crl.verify(ROOT_CACHE.get(tmchCaTestingMode).getPublicKey());
return crl; return crl;
} catch (GeneralSecurityException e) { } catch (ExecutionException e) {
throw new RuntimeException(e); if (e.getCause() instanceof GeneralSecurityException) {
throw (GeneralSecurityException) e.getCause();
} else {
throw new RuntimeException("Unexpected exception while loading CRL", e);
}
} }
}}); }});
/** A cached function that loads the crt from a jar resource. */ /** A cached function that loads the CRT from a jar resource. */
private static final Supplier<X509Certificate> ROOT_CACHE = private static final LoadingCache<Boolean, X509Certificate> ROOT_CACHE =
memoizeWithLongExpiration(new Supplier<X509Certificate>() { CacheBuilder.newBuilder()
.expireAfterWrite(
ENVIRONMENT.config().getSingletonCachePersistDuration().getMillis(), MILLISECONDS)
.build(
new CacheLoader<Boolean, X509Certificate>() {
@Override @Override
public X509Certificate get() { public X509Certificate load(final Boolean tmchCaTestingMode)
try { throws GeneralSecurityException {
X509Certificate root = X509Utils.loadCertificate(readResourceUtf8( String file =
TmchCertificateAuthority.class, tmchCaTestingMode.booleanValue() ? TEST_ROOT_CRT_FILE : ROOT_CRT_FILE;
ENVIRONMENT.config().getTmchCaTestingMode() ? TEST_ROOT_CRT_FILE : ROOT_CRT_FILE)); X509Certificate root =
X509Utils.loadCertificate(
readResourceUtf8(TmchCertificateAuthority.class, file));
root.checkValidity(clock.nowUtc().toDate()); root.checkValidity(clock.nowUtc().toDate());
return root; return root;
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}}); }});
@NonFinalForTesting @NonFinalForTesting
@ -97,14 +130,14 @@ public final class TmchCertificateAuthority {
* incorrect keys, and for invalid, old, not-yet-valid or revoked certificates. * incorrect keys, and for invalid, old, not-yet-valid or revoked certificates.
* @see X509Utils#verifyCertificate * @see X509Utils#verifyCertificate
*/ */
public static void verify(X509Certificate cert) throws GeneralSecurityException { public void verify(X509Certificate cert) throws GeneralSecurityException {
synchronized (TmchCertificateAuthority.class) { synchronized (TmchCertificateAuthority.class) {
X509Utils.verifyCertificate(getRoot(), getCrl(), cert, clock.nowUtc().toDate()); X509Utils.verifyCertificate(getRoot(), getCrl(), cert, clock.nowUtc().toDate());
} }
} }
/** /**
* Update to the latest TMCH X.509 certificate revocation list and save to the datastore. * Update to the latest TMCH X.509 certificate revocation list and save it to Datastore.
* *
* <p>Your ASCII-armored CRL must be signed by the current ICANN root certificate. * <p>Your ASCII-armored CRL must be signed by the current ICANN root certificate.
* *
@ -115,27 +148,35 @@ public final class TmchCertificateAuthority {
* incorrect keys, and for invalid, old, not-yet-valid or revoked certificates. * incorrect keys, and for invalid, old, not-yet-valid or revoked certificates.
* @see X509Utils#verifyCrl * @see X509Utils#verifyCrl
*/ */
public static void updateCrl(String asciiCrl) throws GeneralSecurityException { public void updateCrl(String asciiCrl, String url) throws GeneralSecurityException {
X509CRL crl = X509Utils.loadCrl(asciiCrl); X509CRL crl = X509Utils.loadCrl(asciiCrl);
X509Utils.verifyCrl(getRoot(), getCrl(), crl, clock.nowUtc().toDate()); X509Utils.verifyCrl(getRoot(), getCrl(), crl, clock.nowUtc().toDate());
TmchCrl.set(asciiCrl); TmchCrl.set(asciiCrl, url);
} }
public static X509Certificate getRoot() throws GeneralSecurityException { public X509Certificate getRoot() throws GeneralSecurityException {
try { try {
return ROOT_CACHE.get(); return ROOT_CACHE.get(tmchCaTestingMode);
} catch (RuntimeException e) { } catch (Exception e) {
propagateIfInstanceOf(e.getCause(), GeneralSecurityException.class); if (e.getCause() instanceof GeneralSecurityException) {
throw e; throw (GeneralSecurityException) e.getCause();
} else if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new RuntimeException(e);
} }
} }
public static X509CRL getCrl() throws GeneralSecurityException { public X509CRL getCrl() throws GeneralSecurityException {
try { try {
return CRL_CACHE.get(); return CRL_CACHE.get(tmchCaTestingMode);
} catch (RuntimeException e) { } catch (Exception e) {
propagateIfInstanceOf(e.getCause(), GeneralSecurityException.class); if (e.getCause() instanceof GeneralSecurityException) {
throw e; throw (GeneralSecurityException) e.getCause();
} else if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new RuntimeException(e);
} }
} }
} }

View file

@ -31,14 +31,16 @@ public final class TmchCrlAction implements Runnable {
@Inject Marksdb marksdb; @Inject Marksdb marksdb;
@Inject @Config("tmchCrlUrl") URL tmchCrlUrl; @Inject @Config("tmchCrlUrl") URL tmchCrlUrl;
@Inject TmchCertificateAuthority tmchCertificateAuthority;
@Inject TmchCrlAction() {} @Inject TmchCrlAction() {}
/** Synchronously fetches latest ICANN TMCH CRL and saves it to datastore. */ /** Synchronously fetches latest ICANN TMCH CRL and saves it to datastore. */
@Override @Override
public void run() { public void run() {
try { try {
TmchCertificateAuthority tmchCertificateAuthority.updateCrl(
.updateCrl(new String(marksdb.fetch(tmchCrlUrl, Optional.<String>absent()), UTF_8)); new String(marksdb.fetch(tmchCrlUrl, Optional.<String>absent()), UTF_8),
tmchCrlUrl.toString());
} catch (IOException | GeneralSecurityException e) { } catch (IOException | GeneralSecurityException e) {
throw new RuntimeException("Failed to update ICANN TMCH CRL.", e); throw new RuntimeException("Failed to update ICANN TMCH CRL.", e);
} }

View file

@ -20,6 +20,7 @@ import static com.google.common.base.Throwables.getRootCause;
import static com.google.common.base.Throwables.propagateIfInstanceOf; import static com.google.common.base.Throwables.propagateIfInstanceOf;
import static google.registry.xml.XmlTransformer.loadXmlSchemas; import static google.registry.xml.XmlTransformer.loadXmlSchemas;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
@ -32,6 +33,7 @@ import java.security.cert.X509Certificate;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import javax.xml.crypto.AlgorithmMethod; import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.KeySelector; import javax.xml.crypto.KeySelector;
import javax.xml.crypto.KeySelectorException; import javax.xml.crypto.KeySelectorException;
@ -56,6 +58,14 @@ import org.xml.sax.SAXException;
@ThreadSafe @ThreadSafe
public final class TmchXmlSignature { public final class TmchXmlSignature {
@VisibleForTesting
final TmchCertificateAuthority tmchCertificateAuthority;
@Inject
public TmchXmlSignature(TmchCertificateAuthority tmchCertificateAuthority) {
this.tmchCertificateAuthority = tmchCertificateAuthority;
}
private static final Schema SCHEMA = private static final Schema SCHEMA =
loadXmlSchemas(ImmutableList.of("mark.xsd", "dsig.xsd", "smd.xsd")); loadXmlSchemas(ImmutableList.of("mark.xsd", "dsig.xsd", "smd.xsd"));
@ -72,13 +82,9 @@ public final class TmchXmlSignature {
* @throws ParserConfigurationException * @throws ParserConfigurationException
* @throws SAXException * @throws SAXException
*/ */
public static void verify(byte[] smdXml) public void verify(byte[] smdXml)
throws GeneralSecurityException, throws GeneralSecurityException, IOException, MarshalException, ParserConfigurationException,
IOException, SAXException, XMLSignatureException {
MarshalException,
ParserConfigurationException,
SAXException,
XMLSignatureException {
checkArgument(smdXml.length > 0); checkArgument(smdXml.length > 0);
Document doc = parseSmdDocument(new ByteArrayInputStream(smdXml)); Document doc = parseSmdDocument(new ByteArrayInputStream(smdXml));
@ -87,7 +93,7 @@ public final class TmchXmlSignature {
throw new XMLSignatureException("Expected exactly one <ds:Signature> element."); throw new XMLSignatureException("Expected exactly one <ds:Signature> element.");
} }
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM"); XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
KeyValueKeySelector selector = new KeyValueKeySelector(); KeyValueKeySelector selector = new KeyValueKeySelector(tmchCertificateAuthority);
DOMValidateContext context = new DOMValidateContext(selector, signatureNodes.item(0)); DOMValidateContext context = new DOMValidateContext(selector, signatureNodes.item(0));
XMLSignature signature = factory.unmarshalXMLSignature(context); XMLSignature signature = factory.unmarshalXMLSignature(context);
@ -134,13 +140,21 @@ public final class TmchXmlSignature {
/** Callback class for DOM validator checks validity of {@code <ds:KeyInfo>} elements. */ /** Callback class for DOM validator checks validity of {@code <ds:KeyInfo>} elements. */
private static final class KeyValueKeySelector extends KeySelector { private static final class KeyValueKeySelector extends KeySelector {
private final TmchCertificateAuthority tmchCertificateAuthority;
KeyValueKeySelector(TmchCertificateAuthority tmchCertificateAuthority) {
this.tmchCertificateAuthority = tmchCertificateAuthority;
}
@Nullable @Nullable
@Override @Override
public KeySelectorResult select( public KeySelectorResult select(
@Nullable KeyInfo keyInfo, @Nullable KeyInfo keyInfo,
KeySelector.Purpose purpose, KeySelector.Purpose purpose,
AlgorithmMethod method, AlgorithmMethod method,
XMLCryptoContext context) throws KeySelectorException { XMLCryptoContext context)
throws KeySelectorException {
if (keyInfo == null) { if (keyInfo == null) {
return null; return null;
} }
@ -151,7 +165,7 @@ public final class TmchXmlSignature {
if (x509DataChild instanceof X509Certificate) { if (x509DataChild instanceof X509Certificate) {
X509Certificate cert = (X509Certificate) x509DataChild; X509Certificate cert = (X509Certificate) x509DataChild;
try { try {
TmchCertificateAuthority.verify(cert); tmchCertificateAuthority.verify(cert);
} catch (SignatureException e) { } catch (SignatureException e) {
throw new KeySelectorException(new CertificateSignatureException(e.getMessage())); throw new KeySelectorException(new CertificateSignatureException(e.getMessage()));
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {

View file

@ -71,8 +71,8 @@ final class GenerateApplicationsReportCommand implements RemoteApiCommand {
validateWith = PathParameter.OutputFile.class) validateWith = PathParameter.OutputFile.class)
private Path output = Paths.get("/dev/stdout"); private Path output = Paths.get("/dev/stdout");
@Inject @Inject Clock clock;
Clock clock; @Inject TmchXmlSignature tmchXmlSignature;
@Override @Override
public void run() throws Exception { public void run() throws Exception {
@ -143,7 +143,7 @@ final class GenerateApplicationsReportCommand implements RemoteApiCommand {
} }
try { try {
TmchXmlSignature.verify(signedMarkData); tmchXmlSignature.verify(signedMarkData);
} catch (Exception e) { } catch (Exception e) {
return Optional.of( return Optional.of(
makeLine(domainApplication, String.format("Invalid SMD (%s)", e.getMessage()))); makeLine(domainApplication, String.format("Invalid SMD (%s)", e.getMessage())));

View file

@ -26,7 +26,6 @@ import google.registry.flows.EppTestComponent.FakesAndMocksModule;
import google.registry.model.registrar.Registrar; import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.testing.AppEngineRule; import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse; import google.registry.testing.FakeResponse;
import java.util.Map; import java.util.Map;
import org.json.simple.JSONValue; import org.json.simple.JSONValue;
@ -63,7 +62,7 @@ public class CheckApiActionTest {
action.response = new FakeResponse(); action.response = new FakeResponse();
action.config = RegistryEnvironment.UNITTEST.config(); action.config = RegistryEnvironment.UNITTEST.config();
action.eppController = DaggerEppTestComponent.builder() action.eppController = DaggerEppTestComponent.builder()
.fakesAndMocksModule(new FakesAndMocksModule(new FakeClock())) .fakesAndMocksModule(new FakesAndMocksModule())
.build() .build()
.startRequest() .startRequest()
.eppController(); .eppController();

View file

@ -71,7 +71,7 @@ public class EppCommitLogsTest extends ShardableTestCase {
SessionMetadata sessionMetadata = new HttpSessionMetadata(new FakeHttpSession()); SessionMetadata sessionMetadata = new HttpSessionMetadata(new FakeHttpSession());
sessionMetadata.setClientId("TheRegistrar"); sessionMetadata.setClientId("TheRegistrar");
DaggerEppTestComponent.builder() DaggerEppTestComponent.builder()
.fakesAndMocksModule(new FakesAndMocksModule(clock)) .fakesAndMocksModule(new FakesAndMocksModule(clock, true))
.build() .build()
.startRequest() .startRequest()
.flowComponentBuilder() .flowComponentBuilder()

View file

@ -114,7 +114,7 @@ public class EppTestCase extends ShardableTestCase {
FakeResponse response = new FakeResponse(); FakeResponse response = new FakeResponse();
handler.response = response; handler.response = response;
handler.eppController = DaggerEppTestComponent.builder() handler.eppController = DaggerEppTestComponent.builder()
.fakesAndMocksModule(new FakesAndMocksModule(clock)) .fakesAndMocksModule(new FakesAndMocksModule(clock, true))
.build() .build()
.startRequest() .startRequest()
.eppController(); .eppController();

View file

@ -31,6 +31,8 @@ import google.registry.monitoring.whitebox.EppMetric;
import google.registry.request.RequestScope; import google.registry.request.RequestScope;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper; import google.registry.testing.FakeSleeper;
import google.registry.tmch.TmchCertificateAuthority;
import google.registry.tmch.TmchXmlSignature;
import google.registry.util.Clock; import google.registry.util.Clock;
import google.registry.util.Sleeper; import google.registry.util.Sleeper;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -58,9 +60,15 @@ interface EppTestComponent {
final ModulesService modulesService; final ModulesService modulesService;
final Sleeper sleeper; final Sleeper sleeper;
FakesAndMocksModule(FakeClock clock) { FakesAndMocksModule() {
this(new FakeClock(), true);
}
FakesAndMocksModule(FakeClock clock, boolean tmchCaTestingMode) {
this.clock = clock; this.clock = clock;
this.domainFlowTmchUtils = new DomainFlowTmchUtils(); this.domainFlowTmchUtils =
new DomainFlowTmchUtils(
new TmchXmlSignature(new TmchCertificateAuthority(tmchCaTestingMode)));
this.sleeper = new FakeSleeper(clock); this.sleeper = new FakeSleeper(clock);
this.dnsQueue = DnsQueue.create(); this.dnsQueue = DnsQueue.create();
this.metricBuilder = EppMetric.builderForRequest("request-id-1", clock); this.metricBuilder = EppMetric.builderForRequest("request-id-1", clock);

View file

@ -277,7 +277,7 @@ public abstract class FlowTestCase<F extends Flow> extends ShardableTestCase {
.isEqualTo(new TypeInstantiator<F>(getClass()){}.getExactType()); .isEqualTo(new TypeInstantiator<F>(getClass()){}.getExactType());
// Run the flow. // Run the flow.
return DaggerEppTestComponent.builder() return DaggerEppTestComponent.builder()
.fakesAndMocksModule(new FakesAndMocksModule(clock)) .fakesAndMocksModule(new FakesAndMocksModule(clock, tmchCaTestingMode))
.build() .build()
.startRequest() .startRequest()
.flowComponentBuilder() .flowComponentBuilder()
@ -339,6 +339,12 @@ public abstract class FlowTestCase<F extends Flow> extends ShardableTestCase {
return output; return output;
} }
private boolean tmchCaTestingMode = true;
protected void useTmchProdCert() {
tmchCaTestingMode = false;
}
public EppOutput dryRunFlowAssertResponse(String xml, String... ignoredPaths) throws Exception { public EppOutput dryRunFlowAssertResponse(String xml, String... ignoredPaths) throws Exception {
List<Object> beforeEntities = ofy().load().list(); List<Object> beforeEntities = ofy().load().list();
EppOutput output = EppOutput output =

View file

@ -282,7 +282,6 @@ public class DomainApplicationCreateFlowTest
setEppInput("domain_create_sunrush_encoded_signed_mark.xml"); setEppInput("domain_create_sunrush_encoded_signed_mark.xml");
persistContactsAndHosts(); persistContactsAndHosts();
clock.advanceOneMilli(); clock.advanceOneMilli();
clock.setTo(DateTime.parse("2012-07-26T00:01:00Z"));
clock.setTo(DateTime.parse("2012-07-22T00:01:00Z")); clock.setTo(DateTime.parse("2012-07-22T00:01:00Z"));
thrown.expect(SignedMarkCertificateNotYetValidException.class); thrown.expect(SignedMarkCertificateNotYetValidException.class);
runFlow(); runFlow();
@ -291,7 +290,7 @@ public class DomainApplicationCreateFlowTest
@Test @Test
@Ignore("I'm not sure how to get this to throw without creating a custom CA / certs") @Ignore("I'm not sure how to get this to throw without creating a custom CA / certs")
public void testFailure_signedMarkCertificateCorrupt() throws Exception { public void testFailure_signedMarkCertificateCorrupt() throws Exception {
configRule.useTmchProdCert(); useTmchProdCert();
createTld("tld", TldState.SUNRUSH); createTld("tld", TldState.SUNRUSH);
setEppInput("domain_create_sunrush_encoded_signed_mark_certificate_corrupt.xml"); setEppInput("domain_create_sunrush_encoded_signed_mark_certificate_corrupt.xml");
persistContactsAndHosts(); persistContactsAndHosts();
@ -302,7 +301,7 @@ public class DomainApplicationCreateFlowTest
@Test @Test
public void testFailure_signedMarkCertificateSignature() throws Exception { public void testFailure_signedMarkCertificateSignature() throws Exception {
configRule.useTmchProdCert(); useTmchProdCert();
createTld("tld", TldState.SUNRUSH); createTld("tld", TldState.SUNRUSH);
setEppInput("domain_create_sunrush_encoded_signed_mark.xml"); setEppInput("domain_create_sunrush_encoded_signed_mark.xml");
persistContactsAndHosts(); persistContactsAndHosts();

View file

@ -851,6 +851,7 @@ class google.registry.model.tmch.TmchCrl {
@Id long id; @Id long id;
@Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent; @Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent;
java.lang.String crl; java.lang.String crl;
java.lang.String url;
org.joda.time.DateTime updated; org.joda.time.DateTime updated;
} }
class google.registry.model.transfer.TransferData { class google.registry.model.transfer.TransferData {

View file

@ -32,7 +32,7 @@ public class TmchCrlTest {
@SuppressWarnings("null") @SuppressWarnings("null")
public void testSuccess() throws Exception { public void testSuccess() throws Exception {
assertThat(TmchCrl.get()).isNull(); assertThat(TmchCrl.get()).isNull();
TmchCrl.set("lolcat"); TmchCrl.set("lolcat", "http://lol.cat");
assertThat(TmchCrl.get().getCrl()).isEqualTo("lolcat"); assertThat(TmchCrl.get().getCrl()).isEqualTo("lolcat");
} }
} }

View file

@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import google.registry.config.RegistryConfig; import google.registry.config.RegistryConfig;
import google.registry.config.RegistryEnvironment; import google.registry.config.RegistryEnvironment;
import google.registry.config.TestRegistryConfig;
import org.junit.rules.ExternalResource; import org.junit.rules.ExternalResource;
/** JUnit Rule for overriding Nomulus configuration values. */ /** JUnit Rule for overriding Nomulus configuration values. */
@ -42,15 +41,6 @@ public final class RegistryConfigRule extends ExternalResource {
RegistryEnvironment.overrideConfigurationForTesting(checkNotNull(override)); RegistryEnvironment.overrideConfigurationForTesting(checkNotNull(override));
} }
/** Override registry configuration to use TMCH production CA. */
public void useTmchProdCert() {
override(new TestRegistryConfig() {
@Override
public boolean getTmchCaTestingMode() {
return false;
}});
}
@Override @Override
protected void before() throws Exception { protected void before() throws Exception {
if (override.isPresent()) { if (override.isPresent()) {

View file

@ -23,7 +23,6 @@ import google.registry.testing.AppEngineRule;
import google.registry.testing.ExceptionRule; import google.registry.testing.ExceptionRule;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import google.registry.testing.InjectRule; import google.registry.testing.InjectRule;
import google.registry.testing.RegistryConfigRule;
import java.security.SignatureException; import java.security.SignatureException;
import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateNotYetValidException;
@ -53,9 +52,6 @@ public class TmchCertificateAuthorityTest {
@Rule @Rule
public final InjectRule inject = new InjectRule(); public final InjectRule inject = new InjectRule();
@Rule
public final RegistryConfigRule configRule = new RegistryConfigRule();
private FakeClock clock = new FakeClock(DateTime.parse("2014-01-01T00:00:00Z")); private FakeClock clock = new FakeClock(DateTime.parse("2014-01-01T00:00:00Z"));
@Before @Before
@ -65,45 +61,49 @@ public class TmchCertificateAuthorityTest {
@Test @Test
public void testFailure_prodRootExpired() throws Exception { public void testFailure_prodRootExpired() throws Exception {
configRule.useTmchProdCert(); TmchCertificateAuthority tmchCertificateAuthority = new TmchCertificateAuthority(false);
clock.setTo(DateTime.parse("2024-01-01T00:00:00Z")); clock.setTo(DateTime.parse("2024-01-01T00:00:00Z"));
thrown.expectRootCause( thrown.expectRootCause(
CertificateExpiredException.class, "NotAfter: Sun Jul 23 23:59:59 UTC 2023"); CertificateExpiredException.class, "NotAfter: Sun Jul 23 23:59:59 UTC 2023");
TmchCertificateAuthority.getRoot(); tmchCertificateAuthority.getRoot();
} }
@Test @Test
public void testFailure_prodRootNotYetValid() throws Exception { public void testFailure_prodRootNotYetValid() throws Exception {
configRule.useTmchProdCert(); TmchCertificateAuthority tmchCertificateAuthority = new TmchCertificateAuthority(false);
clock.setTo(DateTime.parse("2000-01-01T00:00:00Z")); clock.setTo(DateTime.parse("2000-01-01T00:00:00Z"));
thrown.expectRootCause(CertificateNotYetValidException.class, thrown.expectRootCause(CertificateNotYetValidException.class,
"NotBefore: Wed Jul 24 00:00:00 UTC 2013"); "NotBefore: Wed Jul 24 00:00:00 UTC 2013");
TmchCertificateAuthority.getRoot(); tmchCertificateAuthority.getRoot();
} }
@Test @Test
public void testFailure_crlDoesntMatchCerts() throws Exception { public void testFailure_crlDoesntMatchCerts() throws Exception {
// Use the prod cl, which won't match our test certificate. // Use the prod cl, which won't match our test certificate.
TmchCrl.set(readResourceUtf8(TmchCertificateAuthority.class, "icann-tmch.crl")); TmchCertificateAuthority tmchCertificateAuthority = new TmchCertificateAuthority(true);
TmchCrl.set(
readResourceUtf8(TmchCertificateAuthority.class, "icann-tmch.crl"), "http://cert.crl");
thrown.expectRootCause(SignatureException.class, "Signature does not match"); thrown.expectRootCause(SignatureException.class, "Signature does not match");
TmchCertificateAuthority.verify(loadCertificate(GOOD_TEST_CERTIFICATE)); tmchCertificateAuthority.verify(loadCertificate(GOOD_TEST_CERTIFICATE));
} }
@Test @Test
public void testSuccess_verify() throws Exception { public void testSuccess_verify() throws Exception {
TmchCertificateAuthority.verify(loadCertificate(GOOD_TEST_CERTIFICATE)); TmchCertificateAuthority tmchCertificateAuthority = new TmchCertificateAuthority(true);
tmchCertificateAuthority.verify(loadCertificate(GOOD_TEST_CERTIFICATE));
} }
@Test @Test
public void testFailure_verifySignatureDoesntMatch() throws Exception { public void testFailure_verifySignatureDoesntMatch() throws Exception {
configRule.useTmchProdCert(); TmchCertificateAuthority tmchCertificateAuthority = new TmchCertificateAuthority(false);
thrown.expectRootCause(SignatureException.class, "Signature does not match"); thrown.expectRootCause(SignatureException.class, "Signature does not match");
TmchCertificateAuthority.verify(loadCertificate(GOOD_TEST_CERTIFICATE)); tmchCertificateAuthority.verify(loadCertificate(GOOD_TEST_CERTIFICATE));
} }
@Test @Test
public void testFailure_verifyRevoked() throws Exception { public void testFailure_verifyRevoked() throws Exception {
TmchCertificateAuthority tmchCertificateAuthority = new TmchCertificateAuthority(true);
thrown.expect(CertificateRevokedException.class, "revoked, reason: KEY_COMPROMISE"); thrown.expect(CertificateRevokedException.class, "revoked, reason: KEY_COMPROMISE");
TmchCertificateAuthority.verify(loadCertificate(REVOKED_TEST_CERTIFICATE)); tmchCertificateAuthority.verify(loadCertificate(REVOKED_TEST_CERTIFICATE));
} }
} }

View file

@ -30,9 +30,10 @@ import org.junit.Test;
/** Unit tests for {@link TmchCrlAction}. */ /** Unit tests for {@link TmchCrlAction}. */
public class TmchCrlActionTest extends TmchActionTestCase { public class TmchCrlActionTest extends TmchActionTestCase {
private TmchCrlAction newTmchCrlAction() throws MalformedURLException { private TmchCrlAction newTmchCrlAction(boolean tmchCaTestingMode) throws MalformedURLException {
TmchCrlAction action = new TmchCrlAction(); TmchCrlAction action = new TmchCrlAction();
action.marksdb = marksdb; action.marksdb = marksdb;
action.tmchCertificateAuthority = new TmchCertificateAuthority(tmchCaTestingMode);
action.tmchCrlUrl = new URL("http://sloth.lol/tmch.crl"); action.tmchCrlUrl = new URL("http://sloth.lol/tmch.crl");
return action; return action;
} }
@ -40,10 +41,9 @@ public class TmchCrlActionTest extends TmchActionTestCase {
@Test @Test
public void testSuccess() throws Exception { public void testSuccess() throws Exception {
clock.setTo(DateTime.parse("2013-07-24TZ")); clock.setTo(DateTime.parse("2013-07-24TZ"));
configRule.useTmchProdCert();
when(httpResponse.getContent()).thenReturn( when(httpResponse.getContent()).thenReturn(
readResourceBytes(TmchCertificateAuthority.class, "icann-tmch.crl").read()); readResourceBytes(TmchCertificateAuthority.class, "icann-tmch.crl").read());
newTmchCrlAction().run(); newTmchCrlAction(false).run();
verify(httpResponse).getContent(); verify(httpResponse).getContent();
verify(fetchService).fetch(httpRequest.capture()); verify(fetchService).fetch(httpRequest.capture());
assertThat(httpRequest.getValue().getURL().toString()).isEqualTo("http://sloth.lol/tmch.crl"); assertThat(httpRequest.getValue().getURL().toString()).isEqualTo("http://sloth.lol/tmch.crl");
@ -52,11 +52,11 @@ public class TmchCrlActionTest extends TmchActionTestCase {
@Test @Test
public void testFailure_crlTooOld() throws Exception { public void testFailure_crlTooOld() throws Exception {
clock.setTo(DateTime.parse("2020-01-01TZ")); clock.setTo(DateTime.parse("2020-01-01TZ"));
configRule.useTmchProdCert();
when(httpResponse.getContent()).thenReturn( when(httpResponse.getContent()).thenReturn(
readResourceBytes(TmchCertificateAuthority.class, "icann-tmch-test.crl").read()); readResourceBytes(TmchCertificateAuthority.class, "icann-tmch-test.crl").read());
TmchCrlAction action = newTmchCrlAction(false);
thrown.expectRootCause(CRLException.class, "New CRL is more out of date than our current CRL."); thrown.expectRootCause(CRLException.class, "New CRL is more out of date than our current CRL.");
newTmchCrlAction().run(); action.run();
} }
@Test @Test
@ -65,7 +65,7 @@ public class TmchCrlActionTest extends TmchActionTestCase {
when(httpResponse.getContent()).thenReturn( when(httpResponse.getContent()).thenReturn(
readResourceBytes(TmchCertificateAuthority.class, "icann-tmch.crl").read()); readResourceBytes(TmchCertificateAuthority.class, "icann-tmch.crl").read());
thrown.expectRootCause(SignatureException.class, "Signature does not match."); thrown.expectRootCause(SignatureException.class, "Signature does not match.");
newTmchCrlAction().run(); newTmchCrlAction(true).run();
} }
@Test @Test
@ -74,6 +74,6 @@ public class TmchCrlActionTest extends TmchActionTestCase {
when(httpResponse.getContent()).thenReturn( when(httpResponse.getContent()).thenReturn(
readResourceBytes(TmchCertificateAuthority.class, "icann-tmch-test.crl").read()); readResourceBytes(TmchCertificateAuthority.class, "icann-tmch-test.crl").read());
thrown.expectRootCause(CertificateNotYetValidException.class); thrown.expectRootCause(CertificateNotYetValidException.class);
newTmchCrlAction().run(); newTmchCrlAction(true).run();
} }
} }

View file

@ -57,17 +57,19 @@ public class TmchXmlSignatureTest {
private final FakeClock clock = new FakeClock(DateTime.parse("2013-11-24T23:15:37.4Z")); private final FakeClock clock = new FakeClock(DateTime.parse("2013-11-24T23:15:37.4Z"));
private byte[] smdData; private byte[] smdData;
private TmchXmlSignature tmchXmlSignature;
@Before @Before
public void before() throws Exception { public void before() throws Exception {
inject.setStaticField(TmchCertificateAuthority.class, "clock", clock); inject.setStaticField(TmchCertificateAuthority.class, "clock", clock);
tmchXmlSignature = new TmchXmlSignature(new TmchCertificateAuthority(true));
} }
public void wrongCertificateAuthority() throws Exception { public void wrongCertificateAuthority() throws Exception {
configRule.useTmchProdCert(); tmchXmlSignature = new TmchXmlSignature(new TmchCertificateAuthority(false));
smdData = loadSmd("active/Court-Agent-Arabic-Active.smd"); smdData = loadSmd("active/Court-Agent-Arabic-Active.smd");
thrown.expectRootCause(SignatureException.class, "Signature does not match"); thrown.expectRootCause(SignatureException.class, "Signature does not match");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
@ -75,7 +77,7 @@ public class TmchXmlSignatureTest {
smdData = loadSmd("active/Court-Agent-Arabic-Active.smd"); smdData = loadSmd("active/Court-Agent-Arabic-Active.smd");
clock.setTo(DateTime.parse("2013-05-01T00:00:00Z")); clock.setTo(DateTime.parse("2013-05-01T00:00:00Z"));
thrown.expectRootCause(CertificateNotYetValidException.class); thrown.expectRootCause(CertificateNotYetValidException.class);
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
@ -83,256 +85,256 @@ public class TmchXmlSignatureTest {
smdData = loadSmd("active/Court-Agent-Arabic-Active.smd"); smdData = loadSmd("active/Court-Agent-Arabic-Active.smd");
clock.setTo(DateTime.parse("2023-06-01T00:00:00Z")); clock.setTo(DateTime.parse("2023-06-01T00:00:00Z"));
thrown.expectRootCause(CertificateExpiredException.class); thrown.expectRootCause(CertificateExpiredException.class);
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtAgentArabicActive() throws Exception { public void testActiveCourtAgentArabicActive() throws Exception {
smdData = loadSmd("active/Court-Agent-Arabic-Active.smd"); smdData = loadSmd("active/Court-Agent-Arabic-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtAgentChineseActive() throws Exception { public void testActiveCourtAgentChineseActive() throws Exception {
smdData = loadSmd("active/Court-Agent-Chinese-Active.smd"); smdData = loadSmd("active/Court-Agent-Chinese-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtAgentEnglishActive() throws Exception { public void testActiveCourtAgentEnglishActive() throws Exception {
smdData = loadSmd("active/Court-Agent-English-Active.smd"); smdData = loadSmd("active/Court-Agent-English-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtAgentFrenchActive() throws Exception { public void testActiveCourtAgentFrenchActive() throws Exception {
smdData = loadSmd("active/Court-Agent-French-Active.smd"); smdData = loadSmd("active/Court-Agent-French-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtAgentRussianActive() throws Exception { public void testActiveCourtAgentRussianActive() throws Exception {
smdData = loadSmd("active/Court-Agent-Russian-Active.smd"); smdData = loadSmd("active/Court-Agent-Russian-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtHolderArabicActive() throws Exception { public void testActiveCourtHolderArabicActive() throws Exception {
smdData = loadSmd("active/Court-Holder-Arabic-Active.smd"); smdData = loadSmd("active/Court-Holder-Arabic-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtHolderChineseActive() throws Exception { public void testActiveCourtHolderChineseActive() throws Exception {
smdData = loadSmd("active/Court-Holder-Chinese-Active.smd"); smdData = loadSmd("active/Court-Holder-Chinese-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtHolderEnglishActive() throws Exception { public void testActiveCourtHolderEnglishActive() throws Exception {
smdData = loadSmd("active/Court-Holder-English-Active.smd"); smdData = loadSmd("active/Court-Holder-English-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtHolderFrenchActive() throws Exception { public void testActiveCourtHolderFrenchActive() throws Exception {
smdData = loadSmd("active/Court-Holder-French-Active.smd"); smdData = loadSmd("active/Court-Holder-French-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveCourtHolderRussianActive() throws Exception { public void testActiveCourtHolderRussianActive() throws Exception {
smdData = loadSmd("active/Court-Holder-Russian-Active.smd"); smdData = loadSmd("active/Court-Holder-Russian-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkAgentArabicActive() throws Exception { public void testActiveTrademarkAgentArabicActive() throws Exception {
smdData = loadSmd("active/Trademark-Agent-Arabic-Active.smd"); smdData = loadSmd("active/Trademark-Agent-Arabic-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkAgentChineseActive() throws Exception { public void testActiveTrademarkAgentChineseActive() throws Exception {
smdData = loadSmd("active/Trademark-Agent-Chinese-Active.smd"); smdData = loadSmd("active/Trademark-Agent-Chinese-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkAgentEnglishActive() throws Exception { public void testActiveTrademarkAgentEnglishActive() throws Exception {
smdData = loadSmd("active/Trademark-Agent-English-Active.smd"); smdData = loadSmd("active/Trademark-Agent-English-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkAgentFrenchActive() throws Exception { public void testActiveTrademarkAgentFrenchActive() throws Exception {
smdData = loadSmd("active/Trademark-Agent-French-Active.smd"); smdData = loadSmd("active/Trademark-Agent-French-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkAgentRussianActive() throws Exception { public void testActiveTrademarkAgentRussianActive() throws Exception {
smdData = loadSmd("active/Trademark-Agent-Russian-Active.smd"); smdData = loadSmd("active/Trademark-Agent-Russian-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkHolderArabicActive() throws Exception { public void testActiveTrademarkHolderArabicActive() throws Exception {
smdData = loadSmd("active/Trademark-Holder-Arabic-Active.smd"); smdData = loadSmd("active/Trademark-Holder-Arabic-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkHolderChineseActive() throws Exception { public void testActiveTrademarkHolderChineseActive() throws Exception {
smdData = loadSmd("active/Trademark-Holder-Chinese-Active.smd"); smdData = loadSmd("active/Trademark-Holder-Chinese-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkHolderEnglishActive() throws Exception { public void testActiveTrademarkHolderEnglishActive() throws Exception {
smdData = loadSmd("active/Trademark-Holder-English-Active.smd"); smdData = loadSmd("active/Trademark-Holder-English-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkHolderFrenchActive() throws Exception { public void testActiveTrademarkHolderFrenchActive() throws Exception {
smdData = loadSmd("active/Trademark-Holder-French-Active.smd"); smdData = loadSmd("active/Trademark-Holder-French-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTrademarkHolderRussianActive() throws Exception { public void testActiveTrademarkHolderRussianActive() throws Exception {
smdData = loadSmd("active/Trademark-Holder-Russian-Active.smd"); smdData = loadSmd("active/Trademark-Holder-Russian-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteAgentArabicActive() throws Exception { public void testActiveTreatystatuteAgentArabicActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Agent-Arabic-Active.smd"); smdData = loadSmd("active/TreatyStatute-Agent-Arabic-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteAgentChineseActive() throws Exception { public void testActiveTreatystatuteAgentChineseActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Agent-Chinese-Active.smd"); smdData = loadSmd("active/TreatyStatute-Agent-Chinese-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteAgentEnglishActive() throws Exception { public void testActiveTreatystatuteAgentEnglishActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Agent-English-Active.smd"); smdData = loadSmd("active/TreatyStatute-Agent-English-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteAgentFrenchActive() throws Exception { public void testActiveTreatystatuteAgentFrenchActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Agent-French-Active.smd"); smdData = loadSmd("active/TreatyStatute-Agent-French-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteAgentRussianActive() throws Exception { public void testActiveTreatystatuteAgentRussianActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Agent-Russian-Active.smd"); smdData = loadSmd("active/TreatyStatute-Agent-Russian-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteHolderArabicActive() throws Exception { public void testActiveTreatystatuteHolderArabicActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Holder-Arabic-Active.smd"); smdData = loadSmd("active/TreatyStatute-Holder-Arabic-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteHolderChineseActive() throws Exception { public void testActiveTreatystatuteHolderChineseActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Holder-Chinese-Active.smd"); smdData = loadSmd("active/TreatyStatute-Holder-Chinese-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteHolderEnglishActive() throws Exception { public void testActiveTreatystatuteHolderEnglishActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Holder-English-Active.smd"); smdData = loadSmd("active/TreatyStatute-Holder-English-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteHolderFrenchActive() throws Exception { public void testActiveTreatystatuteHolderFrenchActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Holder-French-Active.smd"); smdData = loadSmd("active/TreatyStatute-Holder-French-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testActiveTreatystatuteHolderRussianActive() throws Exception { public void testActiveTreatystatuteHolderRussianActive() throws Exception {
smdData = loadSmd("active/TreatyStatute-Holder-Russian-Active.smd"); smdData = loadSmd("active/TreatyStatute-Holder-Russian-Active.smd");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testInvalidInvalidsignatureCourtAgentFrenchActive() throws Exception { public void testInvalidInvalidsignatureCourtAgentFrenchActive() throws Exception {
smdData = loadSmd("invalid/InvalidSignature-Court-Agent-French-Active.smd"); smdData = loadSmd("invalid/InvalidSignature-Court-Agent-French-Active.smd");
thrown.expect(XMLSignatureException.class); thrown.expect(XMLSignatureException.class);
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testInvalidInvalidsignatureTrademarkAgentEnglishActive() throws Exception { public void testInvalidInvalidsignatureTrademarkAgentEnglishActive() throws Exception {
smdData = loadSmd("invalid/InvalidSignature-Trademark-Agent-English-Active.smd"); smdData = loadSmd("invalid/InvalidSignature-Trademark-Agent-English-Active.smd");
thrown.expect(XMLSignatureException.class); thrown.expect(XMLSignatureException.class);
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testInvalidInvalidsignatureTrademarkAgentRussianActive() throws Exception { public void testInvalidInvalidsignatureTrademarkAgentRussianActive() throws Exception {
smdData = loadSmd("invalid/InvalidSignature-Trademark-Agent-Russian-Active.smd"); smdData = loadSmd("invalid/InvalidSignature-Trademark-Agent-Russian-Active.smd");
thrown.expect(XMLSignatureException.class); thrown.expect(XMLSignatureException.class);
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testInvalidInvalidsignatureTreatystatuteAgentChineseActive() throws Exception { public void testInvalidInvalidsignatureTreatystatuteAgentChineseActive() throws Exception {
smdData = loadSmd("invalid/InvalidSignature-TreatyStatute-Agent-Chinese-Active.smd"); smdData = loadSmd("invalid/InvalidSignature-TreatyStatute-Agent-Chinese-Active.smd");
thrown.expect(XMLSignatureException.class); thrown.expect(XMLSignatureException.class);
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testInvalidInvalidsignatureTreatystatuteAgentEnglishActive() throws Exception { public void testInvalidInvalidsignatureTreatystatuteAgentEnglishActive() throws Exception {
smdData = loadSmd("invalid/InvalidSignature-TreatyStatute-Agent-English-Active.smd"); smdData = loadSmd("invalid/InvalidSignature-TreatyStatute-Agent-English-Active.smd");
thrown.expect(XMLSignatureException.class); thrown.expect(XMLSignatureException.class);
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testRevokedTmvTmvrevokedCourtAgentFrenchActive() throws Exception { public void testRevokedTmvTmvrevokedCourtAgentFrenchActive() throws Exception {
smdData = loadSmd("revoked/tmv/TMVRevoked-Court-Agent-French-Active.smd"); smdData = loadSmd("revoked/tmv/TMVRevoked-Court-Agent-French-Active.smd");
thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE"); thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testRevokedTmvTmvrevokedTrademarkAgentEnglishActive() throws Exception { public void testRevokedTmvTmvrevokedTrademarkAgentEnglishActive() throws Exception {
smdData = loadSmd("revoked/tmv/TMVRevoked-Trademark-Agent-English-Active.smd"); smdData = loadSmd("revoked/tmv/TMVRevoked-Trademark-Agent-English-Active.smd");
thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE"); thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testRevokedTmvTmvrevokedTrademarkAgentRussianActive() throws Exception { public void testRevokedTmvTmvrevokedTrademarkAgentRussianActive() throws Exception {
smdData = loadSmd("revoked/tmv/TMVRevoked-Trademark-Agent-Russian-Active.smd"); smdData = loadSmd("revoked/tmv/TMVRevoked-Trademark-Agent-Russian-Active.smd");
thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE"); thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testRevokedTmvTmvrevokedTreatystatuteAgentChineseActive() throws Exception { public void testRevokedTmvTmvrevokedTreatystatuteAgentChineseActive() throws Exception {
smdData = loadSmd("revoked/tmv/TMVRevoked-TreatyStatute-Agent-Chinese-Active.smd"); smdData = loadSmd("revoked/tmv/TMVRevoked-TreatyStatute-Agent-Chinese-Active.smd");
thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE"); thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
@Test @Test
public void testRevokedTmvTmvrevokedTreatystatuteAgentEnglishActive() throws Throwable { public void testRevokedTmvTmvrevokedTreatystatuteAgentEnglishActive() throws Throwable {
smdData = loadSmd("revoked/tmv/TMVRevoked-TreatyStatute-Agent-English-Active.smd"); smdData = loadSmd("revoked/tmv/TMVRevoked-TreatyStatute-Agent-English-Active.smd");
thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE"); thrown.expectRootCause(CertificateRevokedException.class, "KEY_COMPROMISE");
TmchXmlSignature.verify(smdData); tmchXmlSignature.verify(smdData);
} }
} }

View file

@ -34,7 +34,9 @@ import google.registry.model.domain.DomainApplication;
import google.registry.model.reporting.HistoryEntry; import google.registry.model.reporting.HistoryEntry;
import google.registry.model.smd.EncodedSignedMark; import google.registry.model.smd.EncodedSignedMark;
import google.registry.model.smd.SignedMarkRevocationList; import google.registry.model.smd.SignedMarkRevocationList;
import google.registry.tmch.TmchCertificateAuthority;
import google.registry.tmch.TmchData; import google.registry.tmch.TmchData;
import google.registry.tmch.TmchXmlSignature;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -66,7 +68,8 @@ public class UpdateSmdCommandTest extends CommandTestCase<UpdateSmdCommand> {
.setCurrentSponsorClientId("TheRegistrar") .setCurrentSponsorClientId("TheRegistrar")
.setEncodedSignedMarks(ImmutableList.of(EncodedSignedMark.create("base64", "garbage"))) .setEncodedSignedMarks(ImmutableList.of(EncodedSignedMark.create("base64", "garbage")))
.build()); .build());
command.tmchUtils = new DomainFlowTmchUtils(); command.tmchUtils =
new DomainFlowTmchUtils(new TmchXmlSignature(new TmchCertificateAuthority(true)));
} }
private DomainApplication reloadDomainApplication() { private DomainApplication reloadDomainApplication() {