Add acme-star's recurrent-certificate-predate field

pull/81/head
Richard Körber 2019-03-16 16:53:14 +01:00
parent 33429c015b
commit 0afee7a9e8
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
9 changed files with 50 additions and 6 deletions

View File

@ -224,6 +224,19 @@ public class Order extends AcmeJsonResource {
.orElse(null);
}
/**
* Returns the predate period of each certificate, or {@code null}.
*
* @since 2.7
*/
@CheckForNull
public Duration getRecurrentCertificatePredate() {
return getJSON().get("recurrent-certificate-predate")
.optional()
.map(Value::asDuration)
.orElse(null);
}
/**
* Returns {@code true} if STAR certificates from this order can also be fetched via
* GET requests.

View File

@ -50,6 +50,7 @@ public class OrderBuilder {
private Instant recurrentStart;
private Instant recurrentEnd;
private Duration recurrentValidity;
private Duration recurrentPredate;
private boolean recurrentGet;
/**
@ -229,6 +230,23 @@ public class OrderBuilder {
return this;
}
/**
* Sets the amount of pre-dating each certificate. If not set, the CA's
* default (0) is used.
* <p>
* Implies {@link #recurrent()}.
*
* @param duration
* Duration of certificate pre-dating
* @return itself
* @since 2.7
*/
public OrderBuilder recurrentCertificatePredate(Duration duration) {
recurrent();
this.recurrentPredate = requireNonNull(duration, "duration");
return this;
}
/**
* Announces that the client wishes to fetch the recurring certificate via GET
* request. If not used, the STAR certificate can only be fetched via POST-as-GET
@ -288,6 +306,9 @@ public class OrderBuilder {
if (recurrentValidity != null) {
claims.put("recurrent-certificate-validity", recurrentValidity);
}
if (recurrentPredate != null) {
claims.put("recurrent-certificate-predate", recurrentPredate);
}
if (recurrentGet) {
claims.put("recurrent-certificate-get", recurrentGet);
}

View File

@ -115,6 +115,7 @@ public class OrderBuilderTest {
Instant recurrentStart = parseTimestamp("2018-01-01T00:00:00Z");
Instant recurrentEnd = parseTimestamp("2019-01-01T00:00:00Z");
Duration validity = Duration.ofDays(7);
Duration predate = Duration.ofDays(6);
TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override
@ -148,6 +149,7 @@ public class OrderBuilderTest {
.recurrentStart(recurrentStart)
.recurrentEnd(recurrentEnd)
.recurrentCertificateValidity(validity)
.recurrentCertificatePredate(predate)
.recurrentEnableGet()
.create();
@ -158,6 +160,7 @@ public class OrderBuilderTest {
assertThat(order.getRecurrentStart(), is(recurrentStart));
assertThat(order.getRecurrentEnd(), is(recurrentEnd));
assertThat(order.getRecurrentCertificateValidity(), is(validity));
assertThat(order.getRecurrentCertificatePredate(), is(predate));
assertThat(order.isRecurrentGetEnabled(), is(true));
assertThat(order.getLocation(), is(locationUrl));

View File

@ -84,6 +84,7 @@ public class OrderTest {
assertThat(order.getRecurrentStart(), is(nullValue()));
assertThat(order.getRecurrentEnd(), is(nullValue()));
assertThat(order.getRecurrentCertificateValidity(), is(nullValue()));
assertThat(order.getRecurrentCertificatePredate(), is(nullValue()));
assertThat(order.isRecurrentGetEnabled(), is(false));
assertThat(order.getError(), is(notNullValue()));
@ -243,6 +244,7 @@ public class OrderTest {
assertThat(order.getRecurrentStart(), is(parseTimestamp("2016-01-01T00:00:00Z")));
assertThat(order.getRecurrentEnd(), is(parseTimestamp("2017-01-01T00:00:00Z")));
assertThat(order.getRecurrentCertificateValidity(), is(Duration.ofHours(168)));
assertThat(order.getRecurrentCertificatePredate(), is(Duration.ofDays(6)));
assertThat(order.getNotBefore(), is(nullValue()));
assertThat(order.getNotAfter(), is(nullValue()));
assertThat(order.isRecurrentGetEnabled(), is(true));
@ -282,6 +284,7 @@ public class OrderTest {
assertThat(order.getRecurrentStart(), is(parseTimestamp("2018-01-01T00:00:00Z")));
assertThat(order.getRecurrentEnd(), is(parseTimestamp("2019-01-01T00:00:00Z")));
assertThat(order.getRecurrentCertificateValidity(), is(Duration.ofHours(168)));
assertThat(order.getRecurrentCertificatePredate(), is(Duration.ofDays(6)));
assertThat(order.getNotBefore(), is(nullValue()));
assertThat(order.getNotAfter(), is(nullValue()));
assertThat(order.isRecurrentGetEnabled(), is(true));

View File

@ -15,6 +15,7 @@
"recurrent-start-date": "2018-01-01T00:00:00Z",
"recurrent-end-date": "2019-01-01T00:00:00Z",
"recurrent-certificate-validity": 604800,
"recurrent-certificate-predate": 518400,
"recurrent-certificate-get": true,
"authorizations": [
"https://example.com/acme/authz/1234",

View File

@ -9,5 +9,6 @@
"recurrent-start-date": "2018-01-01T00:00:00Z",
"recurrent-end-date": "2019-01-01T00:00:00Z",
"recurrent-certificate-validity": 604800,
"recurrent-certificate-predate": 518400,
"recurrent-certificate-get": true
}

View File

@ -11,6 +11,7 @@
"recurrent-start-date": "2018-01-01T00:00:00Z",
"recurrent-end-date": "2019-01-01T00:00:00Z",
"recurrent-certificate-validity": 604800,
"recurrent-certificate-predate": 518400,
"recurrent-certificate-get": true,
"authorizations": [
"https://example.com/acme/authz/1234",

View File

@ -4,5 +4,6 @@
"recurrent-start-date": "2016-01-01T00:00:00Z",
"recurrent-end-date": "2017-01-01T00:00:00Z",
"recurrent-certificate-validity": 604800,
"recurrent-certificate-predate": 518400,
"recurrent-certificate-get": true
}

View File

@ -197,6 +197,11 @@ byte[] csr = csrb.getEncoded();
_acme4j_ supports the [ACME STAR](https://tools.ietf.org/html/draft-ietf-acme-star) extension for short-term automatic renewal of certificates.
<div class="alert alert-warning" role="alert">
The _ACME STAR_ support is experimental. There is currently no known ACME server implementing this extension.
</div>
To find out if the CA supports the STAR extension, check the metadata:
```java
@ -214,7 +219,7 @@ Order order = account.newOrder()
.create();
```
You can use `recurrentStart()`, `recurrentEnd()` and `recurrentCertificateValidity()` to change the time span and frequency of automatic renewals. You cannot use `notBefore()` and `notAfter()` in combination with `recurrent()` though.
You can use `recurrentStart()`, `recurrentEnd()`, `recurrentCertificateValidity()` and `recurrentCertificatePredate()` to change the time span and frequency of automatic renewals. You cannot use `notBefore()` and `notAfter()` in combination with `recurrent()` though.
The `Metadata` object also holds the accepted renewal limits (see `Metadata.getStarMinCertValidity()` and `Metadata.getStarMaxRenewal()`).
@ -239,8 +244,3 @@ X509Certificate latestCertificate = cert.getCertificate();
If supported by the CA, it is possible to negotiate that the certificate can also be downloaded via `GET` request. First use `Metadata.isStarCertificateGetAllowed()` to check if this option is supported by the CA. If it is, add `recurrentEnableGet()` to the order parameters to enable it. After the order was finalized, you can use any HTTP client to download the latest certificate from the certificate URL by a `GET` request.
Use `Order.cancelRecurrent()` to terminate automatical certificate renewals.
<div class="alert alert-warning" role="alert">
The _ACME STAR_ support is experimental. There is currently no known ACME server implementing this extension.
</div>