mirror of https://github.com/shred/acme4j
Use new date/time API
parent
0ed0a9219f
commit
c1b677f310
|
@ -17,11 +17,11 @@ import static org.shredzone.acme4j.util.AcmeUtils.parseTimestamp;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.shredzone.acme4j.challenge.Challenge;
|
import org.shredzone.acme4j.challenge.Challenge;
|
||||||
|
@ -43,7 +43,7 @@ public class Authorization extends AcmeResource {
|
||||||
|
|
||||||
private String domain;
|
private String domain;
|
||||||
private Status status;
|
private Status status;
|
||||||
private Date expires;
|
private Instant expires;
|
||||||
private List<Challenge> challenges;
|
private List<Challenge> challenges;
|
||||||
private List<List<Challenge>> combinations;
|
private List<List<Challenge>> combinations;
|
||||||
private boolean loaded = false;
|
private boolean loaded = false;
|
||||||
|
@ -86,7 +86,7 @@ public class Authorization extends AcmeResource {
|
||||||
/**
|
/**
|
||||||
* Gets the expiry date of the authorization, if set by the server.
|
* Gets the expiry date of the authorization, if set by the server.
|
||||||
*/
|
*/
|
||||||
public Date getExpires() {
|
public Instant getExpires() {
|
||||||
load();
|
load();
|
||||||
return expires;
|
return expires;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -234,7 +234,7 @@ public class Registration extends AcmeResource {
|
||||||
* for default. May be ignored by the server.
|
* for default. May be ignored by the server.
|
||||||
* @return The {@link Certificate}
|
* @return The {@link Certificate}
|
||||||
*/
|
*/
|
||||||
public Certificate requestCertificate(byte[] csr, Date notBefore, Date notAfter)
|
public Certificate requestCertificate(byte[] csr, Instant notBefore, Instant notAfter)
|
||||||
throws AcmeException {
|
throws AcmeException {
|
||||||
Objects.requireNonNull(csr, "csr");
|
Objects.requireNonNull(csr, "csr");
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,9 @@ package org.shredzone.acme4j;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -48,7 +49,7 @@ public class Session {
|
||||||
private JSON directoryJson;
|
private JSON directoryJson;
|
||||||
private Metadata metadata;
|
private Metadata metadata;
|
||||||
private Locale locale = Locale.getDefault();
|
private Locale locale = Locale.getDefault();
|
||||||
protected Date directoryCacheExpiry;
|
protected Instant directoryCacheExpiry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link Session}.
|
* Creates a new {@link Session}.
|
||||||
|
@ -210,10 +211,10 @@ public class Session {
|
||||||
*/
|
*/
|
||||||
private void readDirectory() throws AcmeException {
|
private void readDirectory() throws AcmeException {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Date now = new Date();
|
Instant now = Instant.now();
|
||||||
if (directoryJson == null || !directoryCacheExpiry.after(now)) {
|
if (directoryJson == null || !directoryCacheExpiry.isAfter(now)) {
|
||||||
directoryJson = provider().directory(this, getServerUri());
|
directoryJson = provider().directory(this, getServerUri());
|
||||||
directoryCacheExpiry = new Date(now.getTime() + 60 * 60 * 1000L);
|
directoryCacheExpiry = now.plus(Duration.ofHours(1));
|
||||||
|
|
||||||
JSON meta = directoryJson.get("meta").asObject();
|
JSON meta = directoryJson.get("meta").asObject();
|
||||||
if (meta != null) {
|
if (meta != null) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ package org.shredzone.acme4j.challenge;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Date;
|
import java.time.Instant;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.shredzone.acme4j.AcmeResource;
|
import org.shredzone.acme4j.AcmeResource;
|
||||||
|
@ -113,8 +113,8 @@ public class Challenge extends AcmeResource {
|
||||||
/**
|
/**
|
||||||
* Returns the validation date, if returned by the server.
|
* Returns the validation date, if returned by the server.
|
||||||
*/
|
*/
|
||||||
public Date getValidated() {
|
public Instant getValidated() {
|
||||||
return data.get(KEY_VALIDATED).asDate();
|
return data.get(KEY_VALIDATED).asInstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,12 +27,13 @@ import java.security.KeyPair;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -253,9 +254,9 @@ public class DefaultConnection implements Connection {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {
|
||||||
Date retryAfter = getRetryAfterHeader();
|
Optional<Instant> retryAfter = getRetryAfterHeader();
|
||||||
if (retryAfter != null) {
|
if (retryAfter.isPresent()) {
|
||||||
throw new AcmeRetryAfterException(message, retryAfter);
|
throw new AcmeRetryAfterException(message, retryAfter.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
@ -338,29 +339,31 @@ public class DefaultConnection implements Connection {
|
||||||
/**
|
/**
|
||||||
* Gets the instant sent with the Retry-After header.
|
* Gets the instant sent with the Retry-After header.
|
||||||
*/
|
*/
|
||||||
private Date getRetryAfterHeader() {
|
private Optional<Instant> getRetryAfterHeader() {
|
||||||
// See RFC 2616 section 14.37
|
// See RFC 2616 section 14.37
|
||||||
String header = conn.getHeaderField(RETRY_AFTER_HEADER);
|
String header = conn.getHeaderField(RETRY_AFTER_HEADER);
|
||||||
if (header == null) {
|
if (header != null) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// delta-seconds
|
// delta-seconds
|
||||||
if (header.matches("^\\d+$")) {
|
if (header.matches("^\\d+$")) {
|
||||||
int delta = Integer.parseInt(header);
|
int delta = Integer.parseInt(header);
|
||||||
long date = conn.getHeaderFieldDate(DATE_HEADER, System.currentTimeMillis());
|
long date = conn.getHeaderFieldDate(DATE_HEADER, System.currentTimeMillis());
|
||||||
return new Date(date + delta * 1000L);
|
return Optional.of(Instant.ofEpochMilli(date).plusSeconds(delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP-date
|
// HTTP-date
|
||||||
long date = conn.getHeaderFieldDate(RETRY_AFTER_HEADER, 0L);
|
long date = conn.getHeaderFieldDate(RETRY_AFTER_HEADER, 0L);
|
||||||
return date != 0 ? new Date(date) : null;
|
if (date != 0) {
|
||||||
|
return Optional.of(Instant.ofEpochMilli(date));
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new AcmeProtocolException("Bad retry-after header value: " + header, ex);
|
throw new AcmeProtocolException("Bad retry-after header value: " + header, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a problem by throwing an exception. If a JSON problem was returned, an
|
* Handles a problem by throwing an exception. If a JSON problem was returned, an
|
||||||
* {@link AcmeServerException} or subtype will be thrown. Otherwise a generic
|
* {@link AcmeServerException} or subtype will be thrown. Otherwise a generic
|
||||||
|
@ -386,9 +389,9 @@ public class DefaultConnection implements Connection {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("rateLimited".equals(error)) {
|
if ("rateLimited".equals(error)) {
|
||||||
Date retryAfter = getRetryAfterHeader();
|
Optional<Instant> retryAfter = getRetryAfterHeader();
|
||||||
Collection<URI> rateLimits = getLinks("rate-limit");
|
Collection<URI> rateLimits = getLinks("rate-limit");
|
||||||
return new AcmeRateLimitExceededException(type, detail, retryAfter, rateLimits);
|
return new AcmeRateLimitExceededException(type, detail, retryAfter.orElse(null), rateLimits);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AcmeServerException(type, detail);
|
return new AcmeServerException(type, detail);
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
package org.shredzone.acme4j.exception;
|
package org.shredzone.acme4j.exception;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An exception that is thrown when a rate limit was exceeded.
|
* An exception that is thrown when a rate limit was exceeded.
|
||||||
|
@ -24,7 +24,7 @@ import java.util.Date;
|
||||||
public class AcmeRateLimitExceededException extends AcmeServerException {
|
public class AcmeRateLimitExceededException extends AcmeServerException {
|
||||||
private static final long serialVersionUID = 4150484059796413069L;
|
private static final long serialVersionUID = 4150484059796413069L;
|
||||||
|
|
||||||
private final Date retryAfter;
|
private final Instant retryAfter;
|
||||||
private final Collection<URI> documents;
|
private final Collection<URI> documents;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +41,7 @@ public class AcmeRateLimitExceededException extends AcmeServerException {
|
||||||
* @param documents
|
* @param documents
|
||||||
* URIs pointing to documents about the rate limit that was hit
|
* URIs pointing to documents about the rate limit that was hit
|
||||||
*/
|
*/
|
||||||
public AcmeRateLimitExceededException(String type, String detail, Date retryAfter, Collection<URI> documents) {
|
public AcmeRateLimitExceededException(String type, String detail, Instant retryAfter, Collection<URI> documents) {
|
||||||
super(type, detail);
|
super(type, detail);
|
||||||
this.retryAfter = retryAfter;
|
this.retryAfter = retryAfter;
|
||||||
this.documents =
|
this.documents =
|
||||||
|
@ -52,8 +52,8 @@ public class AcmeRateLimitExceededException extends AcmeServerException {
|
||||||
* Returns the moment the request is expected to succeed again. {@code null} if this
|
* Returns the moment the request is expected to succeed again. {@code null} if this
|
||||||
* moment is not known.
|
* moment is not known.
|
||||||
*/
|
*/
|
||||||
public Date getRetryAfter() {
|
public Instant getRetryAfter() {
|
||||||
return retryAfter != null ? new Date(retryAfter.getTime()) : null;
|
return retryAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
*/
|
*/
|
||||||
package org.shredzone.acme4j.exception;
|
package org.shredzone.acme4j.exception;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.time.Instant;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +23,7 @@ import java.util.Objects;
|
||||||
public class AcmeRetryAfterException extends AcmeException {
|
public class AcmeRetryAfterException extends AcmeException {
|
||||||
private static final long serialVersionUID = 4461979121063649905L;
|
private static final long serialVersionUID = 4461979121063649905L;
|
||||||
|
|
||||||
private final Date retryAfter;
|
private final Instant retryAfter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link AcmeRetryAfterException}.
|
* Creates a new {@link AcmeRetryAfterException}.
|
||||||
|
@ -33,7 +33,7 @@ public class AcmeRetryAfterException extends AcmeException {
|
||||||
* @param retryAfter
|
* @param retryAfter
|
||||||
* retry-after date returned by the server
|
* retry-after date returned by the server
|
||||||
*/
|
*/
|
||||||
public AcmeRetryAfterException(String msg, Date retryAfter) {
|
public AcmeRetryAfterException(String msg, Instant retryAfter) {
|
||||||
super(msg);
|
super(msg);
|
||||||
this.retryAfter = Objects.requireNonNull(retryAfter);
|
this.retryAfter = Objects.requireNonNull(retryAfter);
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,8 @@ public class AcmeRetryAfterException extends AcmeException {
|
||||||
/**
|
/**
|
||||||
* Returns the retry-after date returned by the server.
|
* Returns the retry-after date returned by the server.
|
||||||
*/
|
*/
|
||||||
public Date getRetryAfter() {
|
public Instant getRetryAfter() {
|
||||||
return new Date(retryAfter.getTime());
|
return retryAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,9 @@ import java.io.UnsupportedEncodingException;
|
||||||
import java.net.IDN;
|
import java.net.IDN;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Calendar;
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.time.ZoneId;
|
||||||
import java.util.GregorianCalendar;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -164,12 +163,12 @@ public final class AcmeUtils {
|
||||||
*
|
*
|
||||||
* @param str
|
* @param str
|
||||||
* Date string
|
* Date string
|
||||||
* @return {@link Date} that was parsed
|
* @return {@link Instant} that was parsed
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* if the date string was not RFC 3339 formatted
|
* if the date string was not RFC 3339 formatted
|
||||||
* @see <a href="https://www.ietf.org/rfc/rfc3339.txt">RFC 3339</a>
|
* @see <a href="https://www.ietf.org/rfc/rfc3339.txt">RFC 3339</a>
|
||||||
*/
|
*/
|
||||||
public static Date parseTimestamp(String str) {
|
public static Instant parseTimestamp(String str) {
|
||||||
Matcher m = DATE_PATTERN.matcher(str);
|
Matcher m = DATE_PATTERN.matcher(str);
|
||||||
if (!m.matches()) {
|
if (!m.matches()) {
|
||||||
throw new IllegalArgumentException("Illegal date: " + str);
|
throw new IllegalArgumentException("Illegal date: " + str);
|
||||||
|
@ -198,11 +197,9 @@ public final class AcmeUtils {
|
||||||
tz = TZ_PATTERN.matcher(tz).replaceAll("GMT$1$2:$3");
|
tz = TZ_PATTERN.matcher(tz).replaceAll("GMT$1$2:$3");
|
||||||
}
|
}
|
||||||
|
|
||||||
Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone(tz));
|
return ZonedDateTime.of(
|
||||||
cal.clear();
|
year, month, dom, hour, minute, second, ms * 1_000_000,
|
||||||
cal.set(year, month - 1, dom, hour, minute, second);
|
ZoneId.of(tz)).toInstant();
|
||||||
cal.set(Calendar.MILLISECOND, ms);
|
|
||||||
return cal.getTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,8 +27,8 @@ import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -349,12 +349,11 @@ public final class JSON implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value as {@link Date}.
|
* Returns the value as {@link Instant}.
|
||||||
*
|
*
|
||||||
* @return {@link Date}, or {@code null} if the value was not set. The returned
|
* @return {@link Instant}, or {@code null} if the value was not set.
|
||||||
* {@link Date} object is not shared and can be modified safely.
|
|
||||||
*/
|
*/
|
||||||
public Date asDate() {
|
public Instant asInstant() {
|
||||||
if (val == null) {
|
if (val == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,11 @@ import static org.shredzone.acme4j.util.AcmeUtils.base64UrlEncode;
|
||||||
|
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.text.SimpleDateFormat;
|
import java.time.Instant;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import org.jose4j.json.JsonUtil;
|
import org.jose4j.json.JsonUtil;
|
||||||
|
@ -62,25 +61,22 @@ public class JSONBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Puts a {@link Date} to the JSON. If a property with the key exists, it will be
|
* Puts an {@link Instant} to the JSON. If a property with the key exists, it will be
|
||||||
* replaced.
|
* replaced.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* Property key
|
* Property key
|
||||||
* @param value
|
* @param value
|
||||||
* Property {@link Date} value
|
* Property {@link Instant} value
|
||||||
* @return {@code this}
|
* @return {@code this}
|
||||||
*/
|
*/
|
||||||
public JSONBuilder put(String key, Date value) {
|
public JSONBuilder put(String key, Instant value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
put(key, (Object) null);
|
put(key, (Object) null);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
put(key, DateTimeFormatter.ISO_INSTANT.format(value));
|
||||||
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
|
|
||||||
String date = fmt.format(value);
|
|
||||||
put(key, date);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,9 @@ import static org.shredzone.acme4j.util.TestUtils.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -228,7 +229,7 @@ public class AuthorizationTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateRetryAfter() throws Exception {
|
public void testUpdateRetryAfter() throws Exception {
|
||||||
final long retryAfter = System.currentTimeMillis() + 30 * 1000L;
|
final Instant retryAfter = Instant.now().plus(Duration.ofSeconds(30));
|
||||||
|
|
||||||
TestableConnectionProvider provider = new TestableConnectionProvider() {
|
TestableConnectionProvider provider = new TestableConnectionProvider() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -250,7 +251,7 @@ public class AuthorizationTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRetryAfter(String message) throws AcmeException {
|
public void handleRetryAfter(String message) throws AcmeException {
|
||||||
throw new AcmeRetryAfterException(message, new Date(retryAfter));
|
throw new AcmeRetryAfterException(message, retryAfter);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -267,7 +268,7 @@ public class AuthorizationTest {
|
||||||
auth.update();
|
auth.update();
|
||||||
fail("Expected AcmeRetryAfterException");
|
fail("Expected AcmeRetryAfterException");
|
||||||
} catch (AcmeRetryAfterException ex) {
|
} catch (AcmeRetryAfterException ex) {
|
||||||
assertThat(ex.getRetryAfter(), is(new Date(retryAfter)));
|
assertThat(ex.getRetryAfter(), is(retryAfter));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(auth.getDomain(), is("example.org"));
|
assertThat(auth.getDomain(), is("example.org"));
|
||||||
|
|
|
@ -22,7 +22,8 @@ import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Date;
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.shredzone.acme4j.connector.Resource;
|
import org.shredzone.acme4j.connector.Resource;
|
||||||
|
@ -107,7 +108,7 @@ public class CertificateTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testRetryAfter() throws AcmeException, IOException {
|
public void testRetryAfter() throws AcmeException, IOException {
|
||||||
final long retryAfter = System.currentTimeMillis() + 30 * 1000L;
|
final Instant retryAfter = Instant.now().plus(Duration.ofSeconds(30));
|
||||||
|
|
||||||
TestableConnectionProvider provider = new TestableConnectionProvider() {
|
TestableConnectionProvider provider = new TestableConnectionProvider() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -125,7 +126,7 @@ public class CertificateTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRetryAfter(String message) throws AcmeException {
|
public void handleRetryAfter(String message) throws AcmeException {
|
||||||
throw new AcmeRetryAfterException(message, new Date(retryAfter));
|
throw new AcmeRetryAfterException(message, retryAfter);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@ public class CertificateTest {
|
||||||
cert.download();
|
cert.download();
|
||||||
fail("Expected AcmeRetryAfterException");
|
fail("Expected AcmeRetryAfterException");
|
||||||
} catch (AcmeRetryAfterException ex) {
|
} catch (AcmeRetryAfterException ex) {
|
||||||
assertThat(ex.getRetryAfter(), is(new Date(retryAfter)));
|
assertThat(ex.getRetryAfter(), is(retryAfter));
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.close();
|
provider.close();
|
||||||
|
|
|
@ -23,9 +23,10 @@ import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Calendar;
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.jose4j.jws.JsonWebSignature;
|
import org.jose4j.jws.JsonWebSignature;
|
||||||
|
@ -335,15 +336,12 @@ public class RegistrationTest {
|
||||||
provider.putTestResource(Resource.NEW_CERT, resourceUri);
|
provider.putTestResource(Resource.NEW_CERT, resourceUri);
|
||||||
|
|
||||||
byte[] csr = TestUtils.getResourceAsByteArray("/csr.der");
|
byte[] csr = TestUtils.getResourceAsByteArray("/csr.der");
|
||||||
Calendar notBefore = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
ZoneId utc = ZoneId.of("UTC");
|
||||||
notBefore.clear();
|
Instant notBefore = LocalDate.of(2016, 1, 1).atStartOfDay(utc).toInstant();
|
||||||
notBefore.set(2016, Calendar.JANUARY, 1);
|
Instant notAfter = LocalDate.of(2016, 1, 8).atStartOfDay(utc).toInstant();
|
||||||
Calendar notAfter = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
|
||||||
notAfter.clear();
|
|
||||||
notAfter.set(2016, Calendar.JANUARY, 8);
|
|
||||||
|
|
||||||
Registration registration = new Registration(provider.createSession(), locationUri);
|
Registration registration = new Registration(provider.createSession(), locationUri);
|
||||||
Certificate cert = registration.requestCertificate(csr, notBefore.getTime(), notAfter.getTime());
|
Certificate cert = registration.requestCertificate(csr, notBefore, notAfter);
|
||||||
|
|
||||||
assertThat(cert.download(), is(originalCert));
|
assertThat(cert.download(), is(originalCert));
|
||||||
assertThat(cert.getLocation(), is(locationUri));
|
assertThat(cert.getLocation(), is(locationUri));
|
||||||
|
|
|
@ -21,7 +21,7 @@ import static org.shredzone.acme4j.util.TestUtils.getJsonAsObject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.util.Date;
|
import java.time.Instant;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
|
@ -173,7 +173,7 @@ public class SessionTest {
|
||||||
ArgumentMatchers.any(URI.class));
|
ArgumentMatchers.any(URI.class));
|
||||||
|
|
||||||
// Simulate a cache expiry
|
// Simulate a cache expiry
|
||||||
session.directoryCacheExpiry = new Date();
|
session.directoryCacheExpiry = Instant.now();
|
||||||
|
|
||||||
// Make sure directory is read once again
|
// Make sure directory is read once again
|
||||||
assertSession(session);
|
assertSession(session);
|
||||||
|
|
|
@ -25,7 +25,8 @@ import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
import org.jose4j.lang.JoseException;
|
import org.jose4j.lang.JoseException;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -229,7 +230,7 @@ public class ChallengeTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateRetryAfter() throws Exception {
|
public void testUpdateRetryAfter() throws Exception {
|
||||||
final long retryAfter = System.currentTimeMillis() + 30 * 1000L;
|
final Instant retryAfter = Instant.now().plus(Duration.ofSeconds(30));
|
||||||
|
|
||||||
TestableConnectionProvider provider = new TestableConnectionProvider() {
|
TestableConnectionProvider provider = new TestableConnectionProvider() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -252,7 +253,7 @@ public class ChallengeTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRetryAfter(String message) throws AcmeException {
|
public void handleRetryAfter(String message) throws AcmeException {
|
||||||
throw new AcmeRetryAfterException(message, new Date(retryAfter));
|
throw new AcmeRetryAfterException(message, retryAfter);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -265,7 +266,7 @@ public class ChallengeTest {
|
||||||
challenge.update();
|
challenge.update();
|
||||||
fail("Expected AcmeRetryAfterException");
|
fail("Expected AcmeRetryAfterException");
|
||||||
} catch (AcmeRetryAfterException ex) {
|
} catch (AcmeRetryAfterException ex) {
|
||||||
assertThat(ex.getRetryAfter(), is(new Date(retryAfter)));
|
assertThat(ex.getRetryAfter(), is(retryAfter));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(challenge.getStatus(), is(Status.VALID));
|
assertThat(challenge.getStatus(), is(Status.VALID));
|
||||||
|
|
|
@ -25,9 +25,10 @@ import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
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.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -254,12 +255,12 @@ public class DefaultConnectionTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testHandleRetryAfterHeaderDate() throws AcmeException, IOException {
|
public void testHandleRetryAfterHeaderDate() throws AcmeException, IOException {
|
||||||
Date retryDate = new Date(System.currentTimeMillis() + 10 * 60 * 60 * 1000L);
|
Instant retryDate = Instant.now().plus(Duration.ofHours(10));
|
||||||
String retryMsg = "absolute date";
|
String retryMsg = "absolute date";
|
||||||
|
|
||||||
when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_ACCEPTED);
|
when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_ACCEPTED);
|
||||||
when(mockUrlConnection.getHeaderField("Retry-After")).thenReturn(retryDate.toString());
|
when(mockUrlConnection.getHeaderField("Retry-After")).thenReturn(retryDate.toString());
|
||||||
when(mockUrlConnection.getHeaderFieldDate("Retry-After", 0L)).thenReturn(retryDate.getTime());
|
when(mockUrlConnection.getHeaderFieldDate("Retry-After", 0L)).thenReturn(retryDate.toEpochMilli());
|
||||||
|
|
||||||
try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) {
|
try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) {
|
||||||
conn.conn = mockUrlConnection;
|
conn.conn = mockUrlConnection;
|
||||||
|
@ -297,7 +298,7 @@ public class DefaultConnectionTest {
|
||||||
conn.handleRetryAfter(retryMsg);
|
conn.handleRetryAfter(retryMsg);
|
||||||
fail("no AcmeRetryAfterException was thrown");
|
fail("no AcmeRetryAfterException was thrown");
|
||||||
} catch (AcmeRetryAfterException ex) {
|
} catch (AcmeRetryAfterException ex) {
|
||||||
assertThat(ex.getRetryAfter(), is(new Date(now + delta * 1000L)));
|
assertThat(ex.getRetryAfter(), is(Instant.ofEpochMilli(now).plusSeconds(delta)));
|
||||||
assertThat(ex.getMessage(), is(retryMsg));
|
assertThat(ex.getMessage(), is(retryMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,10 @@ import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ public class AcmeRateLimitExceededExceptionTest {
|
||||||
public void testAcmeRateLimitExceededException() {
|
public void testAcmeRateLimitExceededException() {
|
||||||
String type = "urn:ietf:params:acme:error:rateLimited";
|
String type = "urn:ietf:params:acme:error:rateLimited";
|
||||||
String detail = "Too many requests per minute";
|
String detail = "Too many requests per minute";
|
||||||
Date retryAfter = new Date(System.currentTimeMillis() + 60 * 1000L);
|
Instant retryAfter = Instant.now().plus(Duration.ofMinutes(1));
|
||||||
Collection<URI> documents = Arrays.asList(
|
Collection<URI> documents = Arrays.asList(
|
||||||
URI.create("http://example.com/doc1.html"),
|
URI.create("http://example.com/doc1.html"),
|
||||||
URI.create("http://example.com/doc2.html"));
|
URI.create("http://example.com/doc2.html"));
|
||||||
|
|
|
@ -16,7 +16,8 @@ package org.shredzone.acme4j.exception;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -31,16 +32,12 @@ public class AcmeRetryAfterExceptionTest {
|
||||||
@Test
|
@Test
|
||||||
public void testAcmeRetryAfterException() {
|
public void testAcmeRetryAfterException() {
|
||||||
String detail = "Too early";
|
String detail = "Too early";
|
||||||
Date retryAfter = new Date(System.currentTimeMillis() + 60 * 1000L);
|
Instant retryAfter = Instant.now().plus(Duration.ofMinutes(1));
|
||||||
|
|
||||||
AcmeRetryAfterException ex
|
AcmeRetryAfterException ex = new AcmeRetryAfterException(detail, retryAfter);
|
||||||
= new AcmeRetryAfterException(detail, retryAfter);
|
|
||||||
|
|
||||||
assertThat(ex.getMessage(), is(detail));
|
assertThat(ex.getMessage(), is(detail));
|
||||||
assertThat(ex.getRetryAfter(), is(retryAfter));
|
assertThat(ex.getRetryAfter(), is(retryAfter));
|
||||||
|
|
||||||
// make sure we get a copy of the Date object
|
|
||||||
assertThat(ex.getRetryAfter(), not(sameInstance(retryAfter)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,16 +45,12 @@ public class AcmeRetryAfterExceptionTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNullAcmeRetryAfterException() {
|
public void testNullAcmeRetryAfterException() {
|
||||||
Date retryAfter = new Date(System.currentTimeMillis() + 60 * 1000L);
|
Instant retryAfter = Instant.now().plus(Duration.ofMinutes(1));
|
||||||
|
|
||||||
AcmeRetryAfterException ex
|
AcmeRetryAfterException ex = new AcmeRetryAfterException(null, retryAfter);
|
||||||
= new AcmeRetryAfterException(null, retryAfter);
|
|
||||||
|
|
||||||
assertThat(ex.getMessage(), nullValue());
|
assertThat(ex.getMessage(), nullValue());
|
||||||
assertThat(ex.getRetryAfter(), is(retryAfter));
|
assertThat(ex.getRetryAfter(), is(retryAfter));
|
||||||
|
|
||||||
// make sure we get a copy of the Date object
|
|
||||||
assertThat(ex.getRetryAfter(), not(sameInstance(retryAfter)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,11 +21,10 @@ import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.text.SimpleDateFormat;
|
import java.time.Instant;
|
||||||
import java.util.Calendar;
|
import java.time.ZoneId;
|
||||||
import java.util.Date;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Locale;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
|
||||||
|
@ -247,57 +246,55 @@ public class AcmeUtilsTest {
|
||||||
/**
|
/**
|
||||||
* Matches the given time.
|
* Matches the given time.
|
||||||
*/
|
*/
|
||||||
private DateMatcher isDate(int year, int month, int dom, int hour, int minute, int second) {
|
private InstantMatcher isDate(int year, int month, int dom, int hour, int minute, int second) {
|
||||||
return isDate(year, month, dom, hour, minute, second, 0);
|
return isDate(year, month, dom, hour, minute, second, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the given time and milliseconds.
|
* Matches the given time and milliseconds.
|
||||||
*/
|
*/
|
||||||
private DateMatcher isDate(int year, int month, int dom, int hour, int minute, int second, int ms) {
|
private InstantMatcher isDate(int year, int month, int dom, int hour, int minute, int second, int ms) {
|
||||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
Instant cmp = ZonedDateTime.of(
|
||||||
cal.clear();
|
year, month, dom, hour, minute, second, ms * 1_000_000,
|
||||||
cal.set(year, month - 1, dom, hour, minute, second);
|
ZoneId.of("UTC")).toInstant();
|
||||||
cal.set(Calendar.MILLISECOND, ms);
|
return new InstantMatcher(cmp);
|
||||||
return new DateMatcher(cal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date matcher that gives a readable output on mismatch.
|
* Date matcher that gives a readable output on mismatch.
|
||||||
*/
|
*/
|
||||||
private static class DateMatcher extends BaseMatcher<Date> {
|
private static class InstantMatcher extends BaseMatcher<Instant> {
|
||||||
private final Calendar cal;
|
private final Instant cmp;
|
||||||
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
|
private final DateTimeFormatter dtf = DateTimeFormatter.ISO_INSTANT;
|
||||||
|
|
||||||
public DateMatcher(Calendar cal) {
|
public InstantMatcher(Instant cmp) {
|
||||||
this.cal = cal;
|
this.cmp = cmp;
|
||||||
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Object item) {
|
public boolean matches(Object item) {
|
||||||
if (!(item instanceof Date)) {
|
if (!(item instanceof Instant)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Date date = (Date) item;
|
Instant date = (Instant) item;
|
||||||
return date.equals(cal.getTime());
|
return date.equals(cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void describeTo(Description description) {
|
public void describeTo(Description description) {
|
||||||
description.appendValue(sdf.format(cal.getTime()));
|
description.appendValue(dtf.format(cmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void describeMismatch(Object item, Description description) {
|
public void describeMismatch(Object item, Description description) {
|
||||||
if (!(item instanceof Date)) {
|
if (!(item instanceof Instant)) {
|
||||||
description.appendText("is not a Date");
|
description.appendText("is not an Instant");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Date date = (Date) item;
|
Instant date = (Instant) item;
|
||||||
description.appendText("was ").appendValue(sdf.format(date));
|
description.appendText("was ").appendValue(dtf.format(date));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,10 @@ import static org.junit.Assert.assertThat;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Calendar;
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import org.jose4j.json.JsonUtil;
|
import org.jose4j.json.JsonUtil;
|
||||||
import org.jose4j.lang.JoseException;
|
import org.jose4j.lang.JoseException;
|
||||||
|
@ -81,13 +81,11 @@ public class JSONBuilderTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDate() {
|
public void testDate() {
|
||||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"));
|
Instant date = ZonedDateTime.of(2016, 6, 1, 5, 13, 46, 0, ZoneId.of("GMT+2")).toInstant();
|
||||||
cal.clear();
|
|
||||||
cal.set(2016, Calendar.JUNE, 1, 5, 13, 46);
|
|
||||||
|
|
||||||
JSONBuilder cb = new JSONBuilder();
|
JSONBuilder cb = new JSONBuilder();
|
||||||
cb.put("fooDate", cal.getTime());
|
cb.put("fooDate", date);
|
||||||
cb.put("fooNull", (Date) null);
|
cb.put("fooNull", (Instant) null);
|
||||||
|
|
||||||
assertThat(cb.toString(), is("{\"fooDate\":\"2016-06-01T03:13:46Z\",\"fooNull\":null}"));
|
assertThat(cb.toString(), is("{\"fooDate\":\"2016-06-01T03:13:46Z\",\"fooNull\":null}"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,11 @@ import java.io.ObjectOutputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Calendar;
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||||
|
@ -145,9 +146,7 @@ public class JSONTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetter() throws MalformedURLException {
|
public void testGetter() throws MalformedURLException {
|
||||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
Instant date = LocalDate.of(2016, 1, 8).atStartOfDay(ZoneId.of("UTC")).toInstant();
|
||||||
cal.clear();
|
|
||||||
cal.set(2016, 0, 8);
|
|
||||||
|
|
||||||
JSON json = TestUtils.getJsonAsObject("json");
|
JSON json = TestUtils.getJsonAsObject("json");
|
||||||
|
|
||||||
|
@ -155,7 +154,7 @@ public class JSONTest {
|
||||||
assertThat(json.get("number").asInt(), is(123));
|
assertThat(json.get("number").asInt(), is(123));
|
||||||
assertThat(json.get("uri").asURI(), is(URI.create("mailto:foo@example.com")));
|
assertThat(json.get("uri").asURI(), is(URI.create("mailto:foo@example.com")));
|
||||||
assertThat(json.get("url").asURL(), is(new URL("http://example.com")));
|
assertThat(json.get("url").asURL(), is(new URL("http://example.com")));
|
||||||
assertThat(json.get("date").asDate(), is(cal.getTime()));
|
assertThat(json.get("date").asInstant(), is(date));
|
||||||
|
|
||||||
JSON.Array array = json.get("array").asArray();
|
JSON.Array array = json.get("array").asArray();
|
||||||
assertThat(array.get(0).asString(), is("foo"));
|
assertThat(array.get(0).asString(), is("foo"));
|
||||||
|
@ -181,7 +180,7 @@ public class JSONTest {
|
||||||
assertThat(json.get("none").asString(), is(nullValue()));
|
assertThat(json.get("none").asString(), is(nullValue()));
|
||||||
assertThat(json.get("none").asURI(), is(nullValue()));
|
assertThat(json.get("none").asURI(), is(nullValue()));
|
||||||
assertThat(json.get("none").asURL(), is(nullValue()));
|
assertThat(json.get("none").asURL(), is(nullValue()));
|
||||||
assertThat(json.get("none").asDate(), is(nullValue()));
|
assertThat(json.get("none").asInstant(), is(nullValue()));
|
||||||
assertThat(json.get("none").asArray(), is(nullValue()));
|
assertThat(json.get("none").asArray(), is(nullValue()));
|
||||||
assertThat(json.get("none").asObject(), is(nullValue()));
|
assertThat(json.get("none").asObject(), is(nullValue()));
|
||||||
|
|
||||||
|
@ -246,7 +245,7 @@ public class JSONTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
json.get("text").asDate();
|
json.get("text").asInstant();
|
||||||
fail("no exception was thrown");
|
fail("no exception was thrown");
|
||||||
} catch (AcmeProtocolException ex) {
|
} catch (AcmeProtocolException ex) {
|
||||||
// expected
|
// expected
|
||||||
|
|
|
@ -25,6 +25,8 @@ import java.security.KeyPair;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
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.Date;
|
||||||
|
|
||||||
import org.bouncycastle.asn1.x500.X500Name;
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
|
@ -212,17 +214,17 @@ public final class CertificateUtils {
|
||||||
*/
|
*/
|
||||||
private static X509Certificate createCertificate(KeyPair keypair, String... subject) throws IOException {
|
private static X509Certificate createCertificate(KeyPair keypair, String... subject) throws IOException {
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
final long validSpanMs = 7 * 24 * 60 * 60 * 1000L;
|
|
||||||
final String signatureAlg = "SHA256withRSA";
|
final String signatureAlg = "SHA256withRSA";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
X500Name issuer = new X500Name("CN=acme.invalid");
|
X500Name issuer = new X500Name("CN=acme.invalid");
|
||||||
BigInteger serial = BigInteger.valueOf(now);
|
BigInteger serial = BigInteger.valueOf(now);
|
||||||
Date notBefore = new Date(now);
|
Instant notBefore = Instant.ofEpochMilli(now);
|
||||||
Date notAfter = new Date(now + validSpanMs);
|
Instant notAfter = notBefore.plus(Duration.ofDays(7));
|
||||||
|
|
||||||
JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
|
JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
|
||||||
issuer, serial, notBefore, notAfter, issuer, keypair.getPublic());
|
issuer, serial, Date.from(notBefore), Date.from(notAfter),
|
||||||
|
issuer, keypair.getPublic());
|
||||||
|
|
||||||
GeneralName[] gns = new GeneralName[subject.length];
|
GeneralName[] gns = new GeneralName[subject.length];
|
||||||
for (int ix = 0; ix < subject.length; ix++) {
|
for (int ix = 0; ix < subject.length; ix++) {
|
||||||
|
|
|
@ -28,6 +28,8 @@ import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.CertificateParsingException;
|
import java.security.cert.CertificateParsingException;
|
||||||
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.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -132,13 +134,13 @@ public class CertificateUtilsTest {
|
||||||
|
|
||||||
X509Certificate cert = CertificateUtils.createTlsSniCertificate(keypair, subject);
|
X509Certificate cert = CertificateUtils.createTlsSniCertificate(keypair, subject);
|
||||||
|
|
||||||
Date now = new Date();
|
Instant now = Instant.now();
|
||||||
Date end = new Date(now.getTime() + (8 * 24 * 60 * 60 * 1000L));
|
Instant end = now.plus(Duration.ofDays(8));
|
||||||
|
|
||||||
assertThat(cert, not(nullValue()));
|
assertThat(cert, not(nullValue()));
|
||||||
assertThat(cert.getNotAfter(), is(greaterThan(now)));
|
assertThat(cert.getNotAfter(), is(greaterThan(Date.from(now))));
|
||||||
assertThat(cert.getNotAfter(), is(lessThan(end)));
|
assertThat(cert.getNotAfter(), is(lessThan(Date.from(end))));
|
||||||
assertThat(cert.getNotBefore(), is(lessThanOrEqualTo(now)));
|
assertThat(cert.getNotBefore(), is(lessThanOrEqualTo(Date.from(now))));
|
||||||
assertThat(cert.getSubjectX500Principal().getName(), is("CN=acme.invalid"));
|
assertThat(cert.getSubjectX500Principal().getName(), is("CN=acme.invalid"));
|
||||||
assertThat(getSANs(cert), containsInAnyOrder(subject));
|
assertThat(getSANs(cert), containsInAnyOrder(subject));
|
||||||
}
|
}
|
||||||
|
@ -156,13 +158,13 @@ public class CertificateUtilsTest {
|
||||||
|
|
||||||
X509Certificate cert = CertificateUtils.createTlsSni02Certificate(keypair, sanA, sanB);
|
X509Certificate cert = CertificateUtils.createTlsSni02Certificate(keypair, sanA, sanB);
|
||||||
|
|
||||||
Date now = new Date();
|
Instant now = Instant.now();
|
||||||
Date end = new Date(now.getTime() + (8 * 24 * 60 * 60 * 1000L));
|
Instant end = now.plus(Duration.ofDays(8));
|
||||||
|
|
||||||
assertThat(cert, not(nullValue()));
|
assertThat(cert, not(nullValue()));
|
||||||
assertThat(cert.getNotAfter(), is(greaterThan(now)));
|
assertThat(cert.getNotAfter(), is(greaterThan(Date.from(now))));
|
||||||
assertThat(cert.getNotAfter(), is(lessThan(end)));
|
assertThat(cert.getNotAfter(), is(lessThan(Date.from(end))));
|
||||||
assertThat(cert.getNotBefore(), is(lessThanOrEqualTo(now)));
|
assertThat(cert.getNotBefore(), is(lessThanOrEqualTo(Date.from(now))));
|
||||||
assertThat(cert.getSubjectX500Principal().getName(), is("CN=acme.invalid"));
|
assertThat(cert.getSubjectX500Principal().getName(), is("CN=acme.invalid"));
|
||||||
assertThat(getSANs(cert), containsInAnyOrder(sanA, sanB));
|
assertThat(getSANs(cert), containsInAnyOrder(sanA, sanB));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue