mirror of
https://github.com/google/nomulus.git
synced 2025-07-22 18:55:58 +02:00
Remove java.util.Date (#2373)
There is one remaining instance in JpaTransactionManagerImpl that cannot be removed because DetachingTypedQuery is implementing TypedQuery, which has a method that expectred java.util.Date.
This commit is contained in:
parent
6d2eb2e140
commit
c68583f666
14 changed files with 108 additions and 147 deletions
|
@ -173,17 +173,24 @@ PRESUBMITS = {
|
||||||
):
|
):
|
||||||
"JavaScript files should not include console logging.",
|
"JavaScript files should not include console logging.",
|
||||||
PresubmitCheck(
|
PresubmitCheck(
|
||||||
r"org\.testcontainers\.shaded\.",
|
r".*org\.testcontainers\.shaded.*",
|
||||||
"java",
|
"java",
|
||||||
{"/node_modules/"},
|
{"/node_modules/"},
|
||||||
):
|
):
|
||||||
"Do not use shaded dependencies from testcontainers.",
|
"Do not use shaded dependencies from testcontainers.",
|
||||||
PresubmitCheck(
|
PresubmitCheck(
|
||||||
r"com\.google\.common\.truth\.Truth8",
|
r".*com\.google\.common\.truth\.Truth8.*",
|
||||||
"java",
|
"java",
|
||||||
{"/node_modules/"},
|
{"/node_modules/"},
|
||||||
):
|
):
|
||||||
"Truth8 is deprecated. Use Truth instead.",
|
"Truth8 is deprecated. Use Truth instead.",
|
||||||
|
PresubmitCheck(
|
||||||
|
r".*java\.util\.Date.*",
|
||||||
|
"java",
|
||||||
|
{"/node_modules/", "JpaTransactionManagerImpl.java"},
|
||||||
|
):
|
||||||
|
"Do not use java.util.Date. Use classes in java.time package instead.",
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Note that this regex only works for one kind of Flyway file. If we want to
|
# Note that this regex only works for one kind of Flyway file. If we want to
|
||||||
|
|
|
@ -45,7 +45,6 @@ import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
@ -195,10 +194,7 @@ public class DelegatedCredentials extends GoogleCredentials {
|
||||||
GenericData responseData = response.parseAs(GenericData.class);
|
GenericData responseData = response.parseAs(GenericData.class);
|
||||||
String accessToken = validateString(responseData, "access_token", PARSE_ERROR_PREFIX);
|
String accessToken = validateString(responseData, "access_token", PARSE_ERROR_PREFIX);
|
||||||
int expiresInSeconds = validateInt32(responseData, "expires_in", PARSE_ERROR_PREFIX);
|
int expiresInSeconds = validateInt32(responseData, "expires_in", PARSE_ERROR_PREFIX);
|
||||||
long expiresAtMilliseconds = clock.nowUtc().getMillis() + expiresInSeconds * 1000L;
|
return new AccessToken(accessToken, clock.nowUtc().plusSeconds(expiresInSeconds).toDate());
|
||||||
@SuppressWarnings("JavaUtilDate")
|
|
||||||
AccessToken token = new AccessToken(accessToken, new Date(expiresAtMilliseconds));
|
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String createAssertion(JsonFactory jsonFactory, long currentTime) throws IOException {
|
String createAssertion(JsonFactory jsonFactory, long currentTime) throws IOException {
|
||||||
|
@ -257,8 +253,7 @@ public class DelegatedCredentials extends GoogleCredentials {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new IOException(String.format(VALUE_NOT_FOUND_MESSAGE, errorPrefix, key));
|
throw new IOException(String.format(VALUE_NOT_FOUND_MESSAGE, errorPrefix, key));
|
||||||
}
|
}
|
||||||
if (value instanceof BigDecimal) {
|
if (value instanceof BigDecimal bigDecimalValue) {
|
||||||
BigDecimal bigDecimalValue = (BigDecimal) value;
|
|
||||||
return bigDecimalValue.intValueExact();
|
return bigDecimalValue.intValueExact();
|
||||||
}
|
}
|
||||||
if (!(value instanceof Integer)) {
|
if (!(value instanceof Integer)) {
|
||||||
|
|
|
@ -31,7 +31,6 @@ import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.interfaces.ECPublicKey;
|
import java.security.interfaces.ECPublicKey;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
|
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
|
||||||
|
@ -106,12 +105,9 @@ public class CertificateChecker {
|
||||||
// These 2 different instances of PublicKey need to be handled separately since their OIDs are
|
// These 2 different instances of PublicKey need to be handled separately since their OIDs are
|
||||||
// encoded differently. More details on this can be found at
|
// encoded differently. More details on this can be found at
|
||||||
// https://stackoverflow.com/questions/49895713/how-to-find-the-matching-curve-name-from-an-ecpublickey.
|
// https://stackoverflow.com/questions/49895713/how-to-find-the-matching-curve-name-from-an-ecpublickey.
|
||||||
if (key instanceof ECPublicKey) {
|
if (key instanceof ECPublicKey ecKey) {
|
||||||
ECPublicKey ecKey = (ECPublicKey) key;
|
|
||||||
params = EC5Util.convertSpec(ecKey.getParams());
|
params = EC5Util.convertSpec(ecKey.getParams());
|
||||||
} else if (key instanceof org.bouncycastle.jce.interfaces.ECPublicKey) {
|
} else if (key instanceof org.bouncycastle.jce.interfaces.ECPublicKey ecKey) {
|
||||||
org.bouncycastle.jce.interfaces.ECPublicKey ecKey =
|
|
||||||
(org.bouncycastle.jce.interfaces.ECPublicKey) key;
|
|
||||||
params = ecKey.getParameters();
|
params = ecKey.getParameters();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unrecognized instance of PublicKey.");
|
throw new IllegalArgumentException("Unrecognized instance of PublicKey.");
|
||||||
|
@ -148,7 +144,7 @@ public class CertificateChecker {
|
||||||
if (!violations.isEmpty()) {
|
if (!violations.isEmpty()) {
|
||||||
String displayMessages =
|
String displayMessages =
|
||||||
violations.stream()
|
violations.stream()
|
||||||
.map(violation -> getViolationDisplayMessage(violation))
|
.map(this::getViolationDisplayMessage)
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
throw new InsecureCertificateException(violations, displayMessages);
|
throw new InsecureCertificateException(violations, displayMessages);
|
||||||
}
|
}
|
||||||
|
@ -162,7 +158,7 @@ public class CertificateChecker {
|
||||||
ImmutableSet.Builder<CertificateViolation> violations = new ImmutableSet.Builder<>();
|
ImmutableSet.Builder<CertificateViolation> violations = new ImmutableSet.Builder<>();
|
||||||
|
|
||||||
// Check if currently in validity period
|
// Check if currently in validity period
|
||||||
Date now = clock.nowUtc().toDate();
|
DateTime now = clock.nowUtc();
|
||||||
if (DateTimeComparator.getInstance().compare(certificate.getNotAfter(), now) < 0) {
|
if (DateTimeComparator.getInstance().compare(certificate.getNotAfter(), now) < 0) {
|
||||||
violations.add(CertificateViolation.EXPIRED);
|
violations.add(CertificateViolation.EXPIRED);
|
||||||
} else if (DateTimeComparator.getInstance().compare(certificate.getNotBefore(), now) > 0) {
|
} else if (DateTimeComparator.getInstance().compare(certificate.getNotBefore(), now) > 0) {
|
||||||
|
@ -231,13 +227,13 @@ public class CertificateChecker {
|
||||||
DateTime lastExpiringNotificationSentDate, String certificateStr) {
|
DateTime lastExpiringNotificationSentDate, String certificateStr) {
|
||||||
X509Certificate certificate = getCertificate(certificateStr);
|
X509Certificate certificate = getCertificate(certificateStr);
|
||||||
DateTime now = clock.nowUtc();
|
DateTime now = clock.nowUtc();
|
||||||
// expiration date is one day after lastValidDate
|
// the expiration date is one day after lastValidDate
|
||||||
DateTime lastValidDate = new DateTime(certificate.getNotAfter());
|
DateTime lastValidDate = new DateTime(certificate.getNotAfter());
|
||||||
if (lastValidDate.isBefore(now)) {
|
if (lastValidDate.isBefore(now)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Client should receive a notification if :
|
* Client should receive a notification if:
|
||||||
* 1) client has never received notification (lastExpiringNotificationSentDate is initially
|
* 1) client has never received notification (lastExpiringNotificationSentDate is initially
|
||||||
* set to START_OF_TIME) and the certificate has entered the expiring period, OR
|
* set to START_OF_TIME) and the certificate has entered the expiring period, OR
|
||||||
* 2) client has received notification but the interval between now and
|
* 2) client has received notification but the interval between now and
|
||||||
|
@ -254,29 +250,21 @@ public class CertificateChecker {
|
||||||
// Yes, we'd rather do this as an instance method on the CertificateViolation enum itself, but
|
// Yes, we'd rather do this as an instance method on the CertificateViolation enum itself, but
|
||||||
// we can't because we need access to configuration (injected as instance variables) which you
|
// we can't because we need access to configuration (injected as instance variables) which you
|
||||||
// can't get in a static enum context.
|
// can't get in a static enum context.
|
||||||
switch (certificateViolation) {
|
return switch (certificateViolation) {
|
||||||
case EXPIRED:
|
case EXPIRED -> "Certificate is expired.";
|
||||||
return "Certificate is expired.";
|
case NOT_YET_VALID -> "Certificate start date is in the future.";
|
||||||
case NOT_YET_VALID:
|
case ALGORITHM_CONSTRAINED -> "Certificate key algorithm must be RSA or ECDSA.";
|
||||||
return "Certificate start date is in the future.";
|
case RSA_KEY_LENGTH_TOO_SHORT ->
|
||||||
case ALGORITHM_CONSTRAINED:
|
String.format(
|
||||||
return "Certificate key algorithm must be RSA or ECDSA.";
|
"RSA key length is too short; the minimum allowed length is %d bits.",
|
||||||
case RSA_KEY_LENGTH_TOO_SHORT:
|
this.minimumRsaKeyLength);
|
||||||
return String.format(
|
case VALIDITY_LENGTH_TOO_LONG ->
|
||||||
"RSA key length is too short; the minimum allowed length is %d bits.",
|
String.format(
|
||||||
this.minimumRsaKeyLength);
|
"Certificate validity period is too long; it must be less than or equal to %d days.",
|
||||||
case VALIDITY_LENGTH_TOO_LONG:
|
this.maxValidityLengthSchedule.lastEntry().getValue());
|
||||||
return String.format(
|
case INVALID_ECDSA_CURVE ->
|
||||||
"Certificate validity period is too long; it must be less than or equal to %d days.",
|
String.format("The ECDSA key must use one of these algorithms: %s", allowedEcdsaCurves);
|
||||||
this.maxValidityLengthSchedule.lastEntry().getValue());
|
};
|
||||||
case INVALID_ECDSA_CURVE:
|
|
||||||
return String.format(
|
|
||||||
"The ECDSA key must use one of these algorithms: %s", allowedEcdsaCurves);
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
String.format(
|
|
||||||
"Unknown CertificateViolation enum value: %s", certificateViolation.name()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,7 +283,7 @@ public class CertificateChecker {
|
||||||
* Gets a suitable end-user-facing display message for this particular certificate violation.
|
* Gets a suitable end-user-facing display message for this particular certificate violation.
|
||||||
*
|
*
|
||||||
* <p>Note that the {@link CertificateChecker} instance must be passed in because it contains
|
* <p>Note that the {@link CertificateChecker} instance must be passed in because it contains
|
||||||
* configuration values (e.g. minimum RSA key length) that go into the error message text.
|
* configuration values (e.g., minimum RSA key length) that go into the error message text.
|
||||||
*/
|
*/
|
||||||
public String getDisplayMessage(CertificateChecker certificateChecker) {
|
public String getDisplayMessage(CertificateChecker certificateChecker) {
|
||||||
return certificateChecker.getViolationDisplayMessage(this);
|
return certificateChecker.getViolationDisplayMessage(this);
|
||||||
|
|
|
@ -127,7 +127,7 @@ public final class TmchCertificateAuthority {
|
||||||
*/
|
*/
|
||||||
public void verify(X509Certificate cert) throws GeneralSecurityException {
|
public void verify(X509Certificate cert) throws GeneralSecurityException {
|
||||||
synchronized (TmchCertificateAuthority.class) {
|
synchronized (TmchCertificateAuthority.class) {
|
||||||
X509Utils.verifyCertificate(getAndValidateRoot(), getCrl(), cert, clock.nowUtc().toDate());
|
X509Utils.verifyCertificate(getAndValidateRoot(), getCrl(), cert, clock.nowUtc());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ public final class TmchCertificateAuthority {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.atWarning().withCause(e).log("Old CRL is invalid, ignored during CRL update.");
|
logger.atWarning().withCause(e).log("Old CRL is invalid, ignored during CRL update.");
|
||||||
}
|
}
|
||||||
X509Utils.verifyCrl(getAndValidateRoot(), oldCrl, newCrl, clock.nowUtc().toDate());
|
X509Utils.verifyCrl(getAndValidateRoot(), oldCrl, newCrl, clock.nowUtc());
|
||||||
TmchCrl.set(asciiCrl, url);
|
TmchCrl.set(asciiCrl, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import google.registry.model.domain.token.AllocationToken;
|
||||||
import google.registry.model.domain.token.AllocationToken.TokenType;
|
import google.registry.model.domain.token.AllocationToken.TokenType;
|
||||||
import google.registry.model.domain.token.BulkPricingPackage;
|
import google.registry.model.domain.token.BulkPricingPackage;
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import java.util.Date;
|
import google.registry.tools.params.DateTimeParameter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -56,9 +56,11 @@ abstract class CreateOrUpdateBulkPricingPackageCommand extends MutatingCommand {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Parameter(
|
@Parameter(
|
||||||
names = "--next_billing_date",
|
names = "--next_billing_date",
|
||||||
|
converter = DateTimeParameter.class,
|
||||||
|
validateWith = DateTimeParameter.class,
|
||||||
description =
|
description =
|
||||||
"The next date that the bulk pricing package should be billed for its annual fee")
|
"The next date that the bulk pricing package should be billed for its annual fee")
|
||||||
Date nextBillingDate;
|
DateTime nextBillingDate;
|
||||||
|
|
||||||
/** Returns the existing BulkPricingPackage or null if it does not exist. */
|
/** Returns the existing BulkPricingPackage or null if it does not exist. */
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -105,9 +107,7 @@ abstract class CreateOrUpdateBulkPricingPackageCommand extends MutatingCommand {
|
||||||
Optional.ofNullable(maxCreates).ifPresent(builder::setMaxCreates);
|
Optional.ofNullable(maxCreates).ifPresent(builder::setMaxCreates);
|
||||||
Optional.ofNullable(price).ifPresent(builder::setBulkPrice);
|
Optional.ofNullable(price).ifPresent(builder::setBulkPrice);
|
||||||
Optional.ofNullable(nextBillingDate)
|
Optional.ofNullable(nextBillingDate)
|
||||||
.ifPresent(
|
.ifPresent(nextBillingDate -> builder.setNextBillingDate(nextBillingDate));
|
||||||
nextBillingDate ->
|
|
||||||
builder.setNextBillingDate(new DateTime(nextBillingDate)));
|
|
||||||
if (clearLastNotificationSent()) {
|
if (clearLastNotificationSent()) {
|
||||||
builder.setLastNotificationSent(null);
|
builder.setLastNotificationSent(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import google.registry.module.backend.BackendRequestComponent;
|
import google.registry.module.backend.BackendRequestComponent;
|
||||||
import google.registry.module.bsa.BsaRequestComponent;
|
import google.registry.module.bsa.BsaRequestComponent;
|
||||||
import google.registry.module.frontend.FrontendRequestComponent;
|
import google.registry.module.frontend.FrontendRequestComponent;
|
||||||
|
@ -28,7 +29,6 @@ import google.registry.testing.TestDataHelper;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testcontainers.shaded.com.google.common.collect.ImmutableMap;
|
|
||||||
|
|
||||||
/** Unit tests for {@link RequestComponent}. */
|
/** Unit tests for {@link RequestComponent}. */
|
||||||
public class RequestComponentTest {
|
public class RequestComponentTest {
|
||||||
|
|
|
@ -40,7 +40,6 @@ import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Multimaps;
|
import com.google.common.collect.Multimaps;
|
||||||
import com.google.common.net.HttpHeaders;
|
import com.google.common.net.HttpHeaders;
|
||||||
import com.google.common.net.MediaType;
|
import com.google.common.net.MediaType;
|
||||||
import com.google.common.truth.Truth8;
|
|
||||||
import com.google.protobuf.Timestamp;
|
import com.google.protobuf.Timestamp;
|
||||||
import com.google.protobuf.util.Timestamps;
|
import com.google.protobuf.util.Timestamps;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
|
@ -133,7 +132,7 @@ public class CloudTasksHelper implements Serializable {
|
||||||
public void assertTasksEnqueuedWithProperty(
|
public void assertTasksEnqueuedWithProperty(
|
||||||
String queueName, Function<Task, String> propertyGetter, String... expectedTaskProperties) {
|
String queueName, Function<Task, String> propertyGetter, String... expectedTaskProperties) {
|
||||||
// Ordering is irrelevant but duplicates should be considered independently.
|
// Ordering is irrelevant but duplicates should be considered independently.
|
||||||
Truth8.assertThat(getTestTasksFor(queueName).stream().map(propertyGetter))
|
assertThat(getTestTasksFor(queueName).stream().map(propertyGetter))
|
||||||
.containsExactly((Object[]) expectedTaskProperties);
|
.containsExactly((Object[]) expectedTaskProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class CreateBulkPricingPackageCommandTest
|
||||||
"--max_domains=100",
|
"--max_domains=100",
|
||||||
"--max_creates=500",
|
"--max_creates=500",
|
||||||
"--price=USD 1000.00",
|
"--price=USD 1000.00",
|
||||||
"--next_billing_date=2012-03-17",
|
"--next_billing_date=2012-03-17T00:00:00Z",
|
||||||
"abc123");
|
"abc123");
|
||||||
|
|
||||||
Optional<BulkPricingPackage> bulkPricingPackageOptional =
|
Optional<BulkPricingPackage> bulkPricingPackageOptional =
|
||||||
|
@ -161,7 +161,7 @@ public class CreateBulkPricingPackageCommandTest
|
||||||
.setAllowedEppActions(ImmutableSet.of(CommandName.CREATE))
|
.setAllowedEppActions(ImmutableSet.of(CommandName.CREATE))
|
||||||
.setDiscountFraction(1)
|
.setDiscountFraction(1)
|
||||||
.build());
|
.build());
|
||||||
runCommandForced("--price=USD 1000.00", "--next_billing_date=2012-03-17", "abc123");
|
runCommandForced("--price=USD 1000.00", "--next_billing_date=2012-03-17T00:00:00Z", "abc123");
|
||||||
Optional<BulkPricingPackage> bulkPricingPackageOptional =
|
Optional<BulkPricingPackage> bulkPricingPackageOptional =
|
||||||
tm().transact(() -> BulkPricingPackage.loadByTokenString("abc123"));
|
tm().transact(() -> BulkPricingPackage.loadByTokenString("abc123"));
|
||||||
assertThat(bulkPricingPackageOptional).isPresent();
|
assertThat(bulkPricingPackageOptional).isPresent();
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class UpdateBulkPricingPackageCommandTest
|
||||||
"--max_domains=200",
|
"--max_domains=200",
|
||||||
"--max_creates=1000",
|
"--max_creates=1000",
|
||||||
"--price=USD 2000.00",
|
"--price=USD 2000.00",
|
||||||
"--next_billing_date=2013-03-17",
|
"--next_billing_date=2013-03-17T00:00:00Z",
|
||||||
"--clear_last_notification_sent",
|
"--clear_last_notification_sent",
|
||||||
"abc123");
|
"abc123");
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ public class UpdateBulkPricingPackageCommandTest
|
||||||
"--max_domains=100",
|
"--max_domains=100",
|
||||||
"--max_creates=500",
|
"--max_creates=500",
|
||||||
"--price=USD 1000.00",
|
"--price=USD 1000.00",
|
||||||
"--next_billing_date=2012-03-17",
|
"--next_billing_date=2012-03-17T00:00:00Z",
|
||||||
"nullPackage"));
|
"nullPackage"));
|
||||||
Truth.assertThat(thrown.getMessage())
|
Truth.assertThat(thrown.getMessage())
|
||||||
.isEqualTo("BulkPricingPackage with token nullPackage does not exist");
|
.isEqualTo("BulkPricingPackage with token nullPackage does not exist");
|
||||||
|
@ -117,7 +117,7 @@ public class UpdateBulkPricingPackageCommandTest
|
||||||
runCommandForced(
|
runCommandForced(
|
||||||
"--max_creates=1000",
|
"--max_creates=1000",
|
||||||
"--price=USD 2000.00",
|
"--price=USD 2000.00",
|
||||||
"--next_billing_date=2013-03-17",
|
"--next_billing_date=2013-03-17T00:00:00Z",
|
||||||
"--clear_last_notification_sent",
|
"--clear_last_notification_sent",
|
||||||
"abc123");
|
"abc123");
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ public class UpdateBulkPricingPackageCommandTest
|
||||||
runCommandForced(
|
runCommandForced(
|
||||||
"--max_domains=200",
|
"--max_domains=200",
|
||||||
"--max_creates=1000",
|
"--max_creates=1000",
|
||||||
"--next_billing_date=2013-03-17",
|
"--next_billing_date=2013-03-17T00:00:00Z",
|
||||||
"--clear_last_notification_sent",
|
"--clear_last_notification_sent",
|
||||||
"abc123");
|
"abc123");
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import static google.registry.networking.handler.SslInitializerTestUtils.getKeyP
|
||||||
import static google.registry.networking.handler.SslInitializerTestUtils.setUpSslChannel;
|
import static google.registry.networking.handler.SslInitializerTestUtils.setUpSslChannel;
|
||||||
import static google.registry.networking.handler.SslInitializerTestUtils.signKeyPair;
|
import static google.registry.networking.handler.SslInitializerTestUtils.signKeyPair;
|
||||||
import static google.registry.networking.handler.SslInitializerTestUtils.verifySslException;
|
import static google.registry.networking.handler.SslInitializerTestUtils.verifySslException;
|
||||||
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import google.registry.util.SelfSignedCaCertificate;
|
import google.registry.util.SelfSignedCaCertificate;
|
||||||
|
@ -43,12 +44,10 @@ import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateExpiredException;
|
import java.security.cert.CertificateExpiredException;
|
||||||
import java.security.cert.CertificateNotYetValidException;
|
import java.security.cert.CertificateNotYetValidException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
@ -62,7 +61,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||||
* the overhead of routing traffic through the network layer, even if it were to go through
|
* the overhead of routing traffic through the network layer, even if it were to go through
|
||||||
* loopback. It also alleviates the need to pick a free port to use.
|
* loopback. It also alleviates the need to pick a free port to use.
|
||||||
*
|
*
|
||||||
* <p>The local addresses used in each test method must to be different, otherwise tests run in
|
* <p>The local addresses used in each test method must be different, otherwise tests run in
|
||||||
* parallel may interfere with each other.
|
* parallel may interfere with each other.
|
||||||
*/
|
*/
|
||||||
class SslClientInitializerTest {
|
class SslClientInitializerTest {
|
||||||
|
@ -204,7 +203,7 @@ class SslClientInitializerTest {
|
||||||
// Generate a new key pair.
|
// Generate a new key pair.
|
||||||
KeyPair keyPair = getKeyPair();
|
KeyPair keyPair = getKeyPair();
|
||||||
|
|
||||||
// Generate a self signed certificate, and use it to sign the key pair.
|
// Generate a self-signed certificate, and use it to sign the key pair.
|
||||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||||
X509Certificate cert = signKeyPair(ssc, keyPair, SSL_HOST);
|
X509Certificate cert = signKeyPair(ssc, keyPair, SSL_HOST);
|
||||||
|
|
||||||
|
@ -212,7 +211,7 @@ class SslClientInitializerTest {
|
||||||
PrivateKey privateKey = keyPair.getPrivate();
|
PrivateKey privateKey = keyPair.getPrivate();
|
||||||
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
||||||
|
|
||||||
// Set up the client to trust the self signed cert used to sign the cert that server provides.
|
// Set up the client to trust the self-signed cert used to sign the cert that server provides.
|
||||||
SslClientInitializer<LocalChannel> sslClientInitializer =
|
SslClientInitializer<LocalChannel> sslClientInitializer =
|
||||||
new SslClientInitializer<>(
|
new SslClientInitializer<>(
|
||||||
sslProvider,
|
sslProvider,
|
||||||
|
@ -239,21 +238,17 @@ class SslClientInitializerTest {
|
||||||
// Generate a new key pair.
|
// Generate a new key pair.
|
||||||
KeyPair keyPair = getKeyPair();
|
KeyPair keyPair = getKeyPair();
|
||||||
|
|
||||||
// Generate a self signed certificate, and use it to sign the key pair.
|
// Generate a self-signed certificate, and use it to sign the key pair.
|
||||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||||
X509Certificate cert =
|
X509Certificate cert =
|
||||||
signKeyPair(
|
signKeyPair(
|
||||||
ssc,
|
ssc, keyPair, SSL_HOST, DateTime.now(UTC).minusDays(2), DateTime.now(UTC).minusDays(1));
|
||||||
keyPair,
|
|
||||||
SSL_HOST,
|
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(2))),
|
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(1))));
|
|
||||||
|
|
||||||
// Set up the server to use the signed cert and private key to perform handshake;
|
// Set up the server to use the signed cert and private key to perform handshake;
|
||||||
PrivateKey privateKey = keyPair.getPrivate();
|
PrivateKey privateKey = keyPair.getPrivate();
|
||||||
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
||||||
|
|
||||||
// Set up the client to trust the self signed cert used to sign the cert that server provides.
|
// Set up the client to trust the self-signed cert used to sign the cert that server provides.
|
||||||
SslClientInitializer<LocalChannel> sslClientInitializer =
|
SslClientInitializer<LocalChannel> sslClientInitializer =
|
||||||
new SslClientInitializer<>(
|
new SslClientInitializer<>(
|
||||||
sslProvider,
|
sslProvider,
|
||||||
|
@ -280,21 +275,17 @@ class SslClientInitializerTest {
|
||||||
// Generate a new key pair.
|
// Generate a new key pair.
|
||||||
KeyPair keyPair = getKeyPair();
|
KeyPair keyPair = getKeyPair();
|
||||||
|
|
||||||
// Generate a self signed certificate, and use it to sign the key pair.
|
// Generate a self-signed certificate, and use it to sign the key pair.
|
||||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||||
X509Certificate cert =
|
X509Certificate cert =
|
||||||
signKeyPair(
|
signKeyPair(
|
||||||
ssc,
|
ssc, keyPair, SSL_HOST, DateTime.now(UTC).plusDays(1), DateTime.now(UTC).plusDays(2));
|
||||||
keyPair,
|
|
||||||
SSL_HOST,
|
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(1))),
|
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(2))));
|
|
||||||
|
|
||||||
// Set up the server to use the signed cert and private key to perform handshake;
|
// Set up the server to use the signed cert and private key to perform handshake;
|
||||||
PrivateKey privateKey = keyPair.getPrivate();
|
PrivateKey privateKey = keyPair.getPrivate();
|
||||||
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
||||||
|
|
||||||
// Set up the client to trust the self signed cert used to sign the cert that server provides.
|
// Set up the client to trust the self-signed cert used to sign the cert that server provides.
|
||||||
SslClientInitializer<LocalChannel> sslClientInitializer =
|
SslClientInitializer<LocalChannel> sslClientInitializer =
|
||||||
new SslClientInitializer<>(
|
new SslClientInitializer<>(
|
||||||
sslProvider,
|
sslProvider,
|
||||||
|
@ -333,7 +324,7 @@ class SslClientInitializerTest {
|
||||||
SslClientInitializerTest::hostProvider,
|
SslClientInitializerTest::hostProvider,
|
||||||
SslClientInitializerTest::portProvider,
|
SslClientInitializerTest::portProvider,
|
||||||
ImmutableList.of(serverSsc.cert()),
|
ImmutableList.of(serverSsc.cert()),
|
||||||
() -> clientSsc.key(),
|
clientSsc::key,
|
||||||
() -> ImmutableList.of(clientSsc.cert()));
|
() -> ImmutableList.of(clientSsc.cert()));
|
||||||
nettyExtension.setUpClient(localAddress, sslClientInitializer);
|
nettyExtension.setUpClient(localAddress, sslClientInitializer);
|
||||||
|
|
||||||
|
@ -360,7 +351,7 @@ class SslClientInitializerTest {
|
||||||
// Generate a new key pair.
|
// Generate a new key pair.
|
||||||
KeyPair keyPair = getKeyPair();
|
KeyPair keyPair = getKeyPair();
|
||||||
|
|
||||||
// Generate a self signed certificate, and use it to sign the key pair.
|
// Generate a self-signed certificate, and use it to sign the key pair.
|
||||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||||
X509Certificate cert = signKeyPair(ssc, keyPair, "wrong.com");
|
X509Certificate cert = signKeyPair(ssc, keyPair, "wrong.com");
|
||||||
|
|
||||||
|
@ -368,7 +359,7 @@ class SslClientInitializerTest {
|
||||||
PrivateKey privateKey = keyPair.getPrivate();
|
PrivateKey privateKey = keyPair.getPrivate();
|
||||||
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
nettyExtension.setUpServer(localAddress, getServerHandler(false, privateKey, cert));
|
||||||
|
|
||||||
// Set up the client to trust the self signed cert used to sign the cert that server provides.
|
// Set up the client to trust the self-signed cert used to sign the cert that server provides.
|
||||||
SslClientInitializer<LocalChannel> sslClientInitializer =
|
SslClientInitializer<LocalChannel> sslClientInitializer =
|
||||||
new SslClientInitializer<>(
|
new SslClientInitializer<>(
|
||||||
sslProvider,
|
sslProvider,
|
||||||
|
@ -379,7 +370,7 @@ class SslClientInitializerTest {
|
||||||
null);
|
null);
|
||||||
nettyExtension.setUpClient(localAddress, sslClientInitializer);
|
nettyExtension.setUpClient(localAddress, sslClientInitializer);
|
||||||
|
|
||||||
// When the client rejects the server cert due to wrong hostname, both the client and server
|
// When the client rejects the server cert due to the wrong hostname, both the client and server
|
||||||
// should throw exceptions.
|
// should throw exceptions.
|
||||||
nettyExtension.assertThatClientRootCause().isInstanceOf(CertificateException.class);
|
nettyExtension.assertThatClientRootCause().isInstanceOf(CertificateException.class);
|
||||||
nettyExtension.assertThatClientRootCause().hasMessageThat().contains(SSL_HOST);
|
nettyExtension.assertThatClientRootCause().hasMessageThat().contains(SSL_HOST);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package google.registry.networking.handler;
|
package google.registry.networking.handler;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
@ -27,9 +28,6 @@ import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
import org.bouncycastle.asn1.x500.X500Name;
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
|
@ -40,6 +38,7 @@ import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.bouncycastle.operator.ContentSigner;
|
import org.bouncycastle.operator.ContentSigner;
|
||||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class that provides methods used by {@link SslClientInitializerTest} and {@link
|
* Utility class that provides methods used by {@link SslClientInitializerTest} and {@link
|
||||||
|
@ -67,13 +66,13 @@ public final class SslInitializerTestUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signs the given key pair with the given self signed certificate to generate a certificate with
|
* Signs the given key pair with the given self-signed certificate to generate a certificate with
|
||||||
* the given validity range.
|
* the given validity range.
|
||||||
*
|
*
|
||||||
* @return signed public key (of the key pair) certificate
|
* @return signed public key (of the key pair) certificate
|
||||||
*/
|
*/
|
||||||
public static X509Certificate signKeyPair(
|
public static X509Certificate signKeyPair(
|
||||||
SelfSignedCaCertificate ssc, KeyPair keyPair, String hostname, Date from, Date to)
|
SelfSignedCaCertificate ssc, KeyPair keyPair, String hostname, DateTime from, DateTime to)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
X500Name subjectDnName = new X500Name("CN=" + hostname);
|
X500Name subjectDnName = new X500Name("CN=" + hostname);
|
||||||
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
|
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
|
||||||
|
@ -81,7 +80,12 @@ public final class SslInitializerTestUtils {
|
||||||
ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(ssc.key());
|
ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(ssc.key());
|
||||||
X509v3CertificateBuilder v3CertGen =
|
X509v3CertificateBuilder v3CertGen =
|
||||||
new JcaX509v3CertificateBuilder(
|
new JcaX509v3CertificateBuilder(
|
||||||
issuerDnName, serialNumber, from, to, subjectDnName, keyPair.getPublic());
|
issuerDnName,
|
||||||
|
serialNumber,
|
||||||
|
from.toDate(),
|
||||||
|
to.toDate(),
|
||||||
|
subjectDnName,
|
||||||
|
keyPair.getPublic());
|
||||||
|
|
||||||
X509CertificateHolder certificateHolder = v3CertGen.build(sigGen);
|
X509CertificateHolder certificateHolder = v3CertGen.build(sigGen);
|
||||||
return new JcaX509CertificateConverter()
|
return new JcaX509CertificateConverter()
|
||||||
|
@ -90,7 +94,7 @@ public final class SslInitializerTestUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signs the given key pair with the given self signed certificate to generate a certificate that
|
* Signs the given key pair with the given self-signed certificate to generate a certificate that
|
||||||
* is valid from yesterday to tomorrow.
|
* is valid from yesterday to tomorrow.
|
||||||
*
|
*
|
||||||
* @return signed public key (of the key pair) certificate
|
* @return signed public key (of the key pair) certificate
|
||||||
|
@ -98,11 +102,7 @@ public final class SslInitializerTestUtils {
|
||||||
public static X509Certificate signKeyPair(
|
public static X509Certificate signKeyPair(
|
||||||
SelfSignedCaCertificate ssc, KeyPair keyPair, String hostname) throws Exception {
|
SelfSignedCaCertificate ssc, KeyPair keyPair, String hostname) throws Exception {
|
||||||
return signKeyPair(
|
return signKeyPair(
|
||||||
ssc,
|
ssc, keyPair, hostname, DateTime.now(UTC).minusDays(1), DateTime.now(UTC).plusDays(1));
|
||||||
keyPair,
|
|
||||||
hostname,
|
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(1))),
|
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(1))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,7 +110,7 @@ public final class SslInitializerTestUtils {
|
||||||
* and verifies if it is echoed back correctly.
|
* and verifies if it is echoed back correctly.
|
||||||
*
|
*
|
||||||
* @param certs The certificate that the server should provide.
|
* @param certs The certificate that the server should provide.
|
||||||
* @return The SSL session in current channel, can be used for further validation.
|
* @return The SSL session in the current channel, can be used for further validation.
|
||||||
*/
|
*/
|
||||||
static SSLSession setUpSslChannel(Channel channel, X509Certificate... certs) throws Exception {
|
static SSLSession setUpSslChannel(Channel channel, X509Certificate... certs) throws Exception {
|
||||||
SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
|
SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import static google.registry.networking.handler.SslInitializerTestUtils.setUpSs
|
||||||
import static google.registry.networking.handler.SslInitializerTestUtils.signKeyPair;
|
import static google.registry.networking.handler.SslInitializerTestUtils.signKeyPair;
|
||||||
import static google.registry.networking.handler.SslInitializerTestUtils.verifySslException;
|
import static google.registry.networking.handler.SslInitializerTestUtils.verifySslException;
|
||||||
import static google.registry.networking.handler.SslServerInitializer.CLIENT_CERTIFICATE_PROMISE_KEY;
|
import static google.registry.networking.handler.SslServerInitializer.CLIENT_CERTIFICATE_PROMISE_KEY;
|
||||||
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
|
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -41,11 +42,8 @@ import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateExpiredException;
|
import java.security.cert.CertificateExpiredException;
|
||||||
import java.security.cert.CertificateNotYetValidException;
|
import java.security.cert.CertificateNotYetValidException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
|
@ -53,6 +51,7 @@ import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLHandshakeException;
|
import javax.net.ssl.SSLHandshakeException;
|
||||||
import javax.net.ssl.SSLParameters;
|
import javax.net.ssl.SSLParameters;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
@ -66,7 +65,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||||
* the overhead of routing traffic through the network layer, even if it were to go through
|
* the overhead of routing traffic through the network layer, even if it were to go through
|
||||||
* loopback. It also alleviates the need to pick a free port to use.
|
* loopback. It also alleviates the need to pick a free port to use.
|
||||||
*
|
*
|
||||||
* <p>The local addresses used in each test method must to be different, otherwise tests run in
|
* <p>The local addresses used in each test method must be different, otherwise tests run in
|
||||||
* parallel may interfere with each other.
|
* parallel may interfere with each other.
|
||||||
*/
|
*/
|
||||||
class SslServerInitializerTest {
|
class SslServerInitializerTest {
|
||||||
|
@ -202,9 +201,7 @@ class SslServerInitializerTest {
|
||||||
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
||||||
SelfSignedCaCertificate clientSsc =
|
SelfSignedCaCertificate clientSsc =
|
||||||
SelfSignedCaCertificate.create(
|
SelfSignedCaCertificate.create(
|
||||||
"CLIENT",
|
"CLIENT", DateTime.now(UTC).minusDays(2), DateTime.now(UTC).plusDays(1));
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(2))),
|
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(1))));
|
|
||||||
nettyExtension.setUpClient(
|
nettyExtension.setUpClient(
|
||||||
localAddress,
|
localAddress,
|
||||||
getClientHandler(
|
getClientHandler(
|
||||||
|
@ -237,9 +234,7 @@ class SslServerInitializerTest {
|
||||||
Suppliers.ofInstance(ImmutableList.of(serverSsc.cert()))));
|
Suppliers.ofInstance(ImmutableList.of(serverSsc.cert()))));
|
||||||
SelfSignedCaCertificate clientSsc =
|
SelfSignedCaCertificate clientSsc =
|
||||||
SelfSignedCaCertificate.create(
|
SelfSignedCaCertificate.create(
|
||||||
"CLIENT",
|
"CLIENT", DateTime.now(UTC).minusDays(2), DateTime.now(UTC).plusDays(1));
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(2))),
|
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(1))));
|
|
||||||
nettyExtension.setUpClient(
|
nettyExtension.setUpClient(
|
||||||
localAddress,
|
localAddress,
|
||||||
getClientHandler(
|
getClientHandler(
|
||||||
|
@ -271,20 +266,18 @@ class SslServerInitializerTest {
|
||||||
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
||||||
SelfSignedCaCertificate clientSsc =
|
SelfSignedCaCertificate clientSsc =
|
||||||
SelfSignedCaCertificate.create(
|
SelfSignedCaCertificate.create(
|
||||||
"CLIENT",
|
"CLIENT", DateTime.now(UTC).minusDays(2), DateTime.now(UTC).plusDays(1));
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(2))),
|
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(1))));
|
|
||||||
nettyExtension.setUpClient(
|
nettyExtension.setUpClient(
|
||||||
localAddress,
|
localAddress,
|
||||||
getClientHandler(
|
getClientHandler(
|
||||||
sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert(), "TLSv1.1", null));
|
sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert(), "TLSv1.1", null));
|
||||||
|
|
||||||
ImmutableList<Integer> jdkVersion =
|
ImmutableList<Integer> jdkVersion =
|
||||||
Arrays.asList(System.getProperty("java.version").split("\\.")).stream()
|
Arrays.stream(System.getProperty("java.version").split("\\."))
|
||||||
.map(Integer::parseInt)
|
.map(Integer::parseInt)
|
||||||
.collect(ImmutableList.toImmutableList());
|
.collect(ImmutableList.toImmutableList());
|
||||||
|
|
||||||
// In JDK v11.0.11 and above TLS 1.1 is not supported any more, in which case attempting to
|
// In JDK v11.0.11 and above, TLS 1.1 is not supported anymore, in which case attempting to
|
||||||
// connect with TLS 1.1 results in a ClosedChannelException instead of a SSLHandShakeException.
|
// connect with TLS 1.1 results in a ClosedChannelException instead of a SSLHandShakeException.
|
||||||
// See https://www.oracle.com/java/technologies/javase/11-0-11-relnotes.html#JDK-8202343
|
// See https://www.oracle.com/java/technologies/javase/11-0-11-relnotes.html#JDK-8202343
|
||||||
Class<? extends Exception> rootCause =
|
Class<? extends Exception> rootCause =
|
||||||
|
@ -309,9 +302,7 @@ class SslServerInitializerTest {
|
||||||
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
||||||
SelfSignedCaCertificate clientSsc =
|
SelfSignedCaCertificate clientSsc =
|
||||||
SelfSignedCaCertificate.create(
|
SelfSignedCaCertificate.create(
|
||||||
"CLIENT",
|
"CLIENT", DateTime.now(UTC).minusDays(2), DateTime.now(UTC).minusDays(1));
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(2))),
|
|
||||||
Date.from(Instant.now().minus(Duration.ofDays(1))));
|
|
||||||
nettyExtension.setUpClient(
|
nettyExtension.setUpClient(
|
||||||
localAddress,
|
localAddress,
|
||||||
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
||||||
|
@ -332,9 +323,7 @@ class SslServerInitializerTest {
|
||||||
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
localAddress, getServerHandler(true, true, sslProvider, serverSsc.key(), serverSsc.cert()));
|
||||||
SelfSignedCaCertificate clientSsc =
|
SelfSignedCaCertificate clientSsc =
|
||||||
SelfSignedCaCertificate.create(
|
SelfSignedCaCertificate.create(
|
||||||
"CLIENT",
|
"CLIENT", DateTime.now(UTC).plusDays(1), DateTime.now(UTC).plusDays(2));
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(1))),
|
|
||||||
Date.from(Instant.now().plus(Duration.ofDays(2))));
|
|
||||||
nettyExtension.setUpClient(
|
nettyExtension.setUpClient(
|
||||||
localAddress,
|
localAddress,
|
||||||
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
||||||
|
@ -446,8 +435,8 @@ class SslServerInitializerTest {
|
||||||
localAddress,
|
localAddress,
|
||||||
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
getClientHandler(sslProvider, serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
||||||
|
|
||||||
// When the client rejects the server cert due to wrong hostname, both the server and the client
|
// When the client rejects the server cert due to the wrong hostname, both the server and the
|
||||||
// throw exceptions.
|
// client throw exceptions.
|
||||||
nettyExtension.assertThatClientRootCause().isInstanceOf(CertificateException.class);
|
nettyExtension.assertThatClientRootCause().isInstanceOf(CertificateException.class);
|
||||||
nettyExtension.assertThatClientRootCause().hasMessageThat().contains(SSL_HOST);
|
nettyExtension.assertThatClientRootCause().hasMessageThat().contains(SSL_HOST);
|
||||||
nettyExtension.assertThatServerRootCause().isInstanceOf(SSLException.class);
|
nettyExtension.assertThatServerRootCause().isInstanceOf(SSLException.class);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package google.registry.util;
|
package google.registry.util;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
@ -23,9 +24,6 @@ import java.security.KeyPairGenerator;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
|
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
|
||||||
import org.bouncycastle.asn1.x500.X500Name;
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
|
@ -44,9 +42,8 @@ import org.joda.time.DateTime;
|
||||||
public class SelfSignedCaCertificate {
|
public class SelfSignedCaCertificate {
|
||||||
|
|
||||||
private static final String DEFAULT_ISSUER_FQDN = "registry-test";
|
private static final String DEFAULT_ISSUER_FQDN = "registry-test";
|
||||||
private static final Date DEFAULT_NOT_BEFORE =
|
private static final DateTime DEFAULT_NOT_BEFORE = DateTime.now(UTC).minusHours(1);
|
||||||
Date.from(Instant.now().minus(Duration.ofHours(1)));
|
private static final DateTime DEFAULT_NOT_AFTER = DateTime.now(UTC).plusDays(1);
|
||||||
private static final Date DEFAULT_NOT_AFTER = Date.from(Instant.now().plus(Duration.ofDays(1)));
|
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
private static final Random RANDOM = new Random();
|
||||||
private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider();
|
private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider();
|
||||||
|
@ -80,24 +77,14 @@ public class SelfSignedCaCertificate {
|
||||||
return create(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
|
return create(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SelfSignedCaCertificate create(String fqdn, Date from, Date to) throws Exception {
|
|
||||||
return create(keyGen.generateKeyPair(), fqdn, from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SelfSignedCaCertificate create(String fqdn, DateTime from, DateTime to)
|
public static SelfSignedCaCertificate create(String fqdn, DateTime from, DateTime to)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return create(keyGen.generateKeyPair(), fqdn, from.toDate(), to.toDate());
|
return create(keyGen.generateKeyPair(), fqdn, from, to);
|
||||||
}
|
|
||||||
|
|
||||||
public static SelfSignedCaCertificate create(KeyPair keyPair, String fqdn, Date from, Date to)
|
|
||||||
throws Exception {
|
|
||||||
return new SelfSignedCaCertificate(keyPair.getPrivate(), createCaCert(keyPair, fqdn, from, to));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SelfSignedCaCertificate create(
|
public static SelfSignedCaCertificate create(
|
||||||
KeyPair keyPair, String fqdn, DateTime from, DateTime to) throws Exception {
|
KeyPair keyPair, String fqdn, DateTime from, DateTime to) throws Exception {
|
||||||
return new SelfSignedCaCertificate(
|
return new SelfSignedCaCertificate(keyPair.getPrivate(), createCaCert(keyPair, fqdn, from, to));
|
||||||
keyPair.getPrivate(), createCaCert(keyPair, fqdn, from.toDate(), to.toDate()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static KeyPairGenerator createKeyPairGenerator() {
|
static KeyPairGenerator createKeyPairGenerator() {
|
||||||
|
@ -111,7 +98,7 @@ public class SelfSignedCaCertificate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a self-signed Certificate Authority (CA) certificate. */
|
/** Returns a self-signed Certificate Authority (CA) certificate. */
|
||||||
static X509Certificate createCaCert(KeyPair keyPair, String fqdn, Date from, Date to)
|
static X509Certificate createCaCert(KeyPair keyPair, String fqdn, DateTime from, DateTime to)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
X500Name owner = new X500Name("CN=" + fqdn);
|
X500Name owner = new X500Name("CN=" + fqdn);
|
||||||
String publicKeyAlg = keyPair.getPublic().getAlgorithm();
|
String publicKeyAlg = keyPair.getPublic().getAlgorithm();
|
||||||
|
@ -121,7 +108,12 @@ public class SelfSignedCaCertificate {
|
||||||
new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate());
|
new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate());
|
||||||
X509v3CertificateBuilder builder =
|
X509v3CertificateBuilder builder =
|
||||||
new JcaX509v3CertificateBuilder(
|
new JcaX509v3CertificateBuilder(
|
||||||
owner, new BigInteger(64, RANDOM), from, to, owner, keyPair.getPublic());
|
owner,
|
||||||
|
new BigInteger(64, RANDOM),
|
||||||
|
from.toDate(),
|
||||||
|
to.toDate(),
|
||||||
|
owner,
|
||||||
|
keyPair.getPublic());
|
||||||
|
|
||||||
// Mark cert as CA by adding basicConstraint with cA=true to the builder
|
// Mark cert as CA by adding basicConstraint with cA=true to the builder
|
||||||
BasicConstraints basicConstraints = new BasicConstraints(true);
|
BasicConstraints basicConstraints = new BasicConstraints(true);
|
||||||
|
|
|
@ -41,11 +41,11 @@ import java.security.cert.X509CRL;
|
||||||
import java.security.cert.X509CRLEntry;
|
import java.security.cert.X509CRLEntry;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.Tainted;
|
import javax.annotation.Tainted;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeComparator;
|
import org.joda.time.DateTimeComparator;
|
||||||
|
|
||||||
/** X.509 Public Key Infrastructure (PKI) helper functions. */
|
/** X.509 Public Key Infrastructure (PKI) helper functions. */
|
||||||
|
@ -140,13 +140,13 @@ public final class X509Utils {
|
||||||
* <p>Support for certificate chains has not been implemented.
|
* <p>Support for certificate chains has not been implemented.
|
||||||
*
|
*
|
||||||
* @throws GeneralSecurityException for unsupported protocols, certs not signed by the TMCH,
|
* @throws GeneralSecurityException for unsupported protocols, certs not signed by the TMCH,
|
||||||
* parsing errors, encoding errors, if the CRL is expired, or if the CRL is older than the
|
* parsing errors, encoding errors, if the CRL is expired, or if the CRL is older than the one
|
||||||
* one currently in memory.
|
* currently in memory.
|
||||||
*/
|
*/
|
||||||
public static void verifyCertificate(
|
public static void verifyCertificate(
|
||||||
X509Certificate rootCert, X509CRL crl, @Tainted X509Certificate cert, Date now)
|
X509Certificate rootCert, X509CRL crl, @Tainted X509Certificate cert, DateTime now)
|
||||||
throws GeneralSecurityException {
|
throws GeneralSecurityException {
|
||||||
cert.checkValidity(checkNotNull(now, "now"));
|
cert.checkValidity(checkNotNull(now, "now").toDate());
|
||||||
cert.verify(rootCert.getPublicKey());
|
cert.verify(rootCert.getPublicKey());
|
||||||
if (crl.isRevoked(cert)) {
|
if (crl.isRevoked(cert)) {
|
||||||
X509CRLEntry entry = crl.getRevokedCertificate(cert);
|
X509CRLEntry entry = crl.getRevokedCertificate(cert);
|
||||||
|
@ -168,7 +168,7 @@ public final class X509Utils {
|
||||||
* incorrect keys, and for invalid, old, not-yet-valid or revoked certificates.
|
* incorrect keys, and for invalid, old, not-yet-valid or revoked certificates.
|
||||||
*/
|
*/
|
||||||
public static void verifyCrl(
|
public static void verifyCrl(
|
||||||
X509Certificate rootCert, @Nullable X509CRL oldCrl, @Tainted X509CRL newCrl, Date now)
|
X509Certificate rootCert, @Nullable X509CRL oldCrl, @Tainted X509CRL newCrl, DateTime now)
|
||||||
throws GeneralSecurityException {
|
throws GeneralSecurityException {
|
||||||
if (oldCrl != null
|
if (oldCrl != null
|
||||||
&& DateTimeComparator.getInstance().compare(newCrl.getThisUpdate(), oldCrl.getThisUpdate())
|
&& DateTimeComparator.getInstance().compare(newCrl.getThisUpdate(), oldCrl.getThisUpdate())
|
||||||
|
@ -178,7 +178,7 @@ public final class X509Utils {
|
||||||
"New CRL is more out of date than our current CRL. %s < %s\n%s",
|
"New CRL is more out of date than our current CRL. %s < %s\n%s",
|
||||||
newCrl.getThisUpdate(), oldCrl.getThisUpdate(), newCrl));
|
newCrl.getThisUpdate(), oldCrl.getThisUpdate(), newCrl));
|
||||||
}
|
}
|
||||||
if (DateTimeComparator.getInstance().compare(newCrl.getNextUpdate(), now) < 0) {
|
if (DateTimeComparator.getInstance().compare(new DateTime(newCrl.getNextUpdate()), now) < 0) {
|
||||||
throw new CRLException("CRL has expired.\n" + newCrl);
|
throw new CRLException("CRL has expired.\n" + newCrl);
|
||||||
}
|
}
|
||||||
newCrl.verify(rootCert.getPublicKey());
|
newCrl.verify(rootCert.getPublicKey());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue