mirror of https://github.com/shred/acme4j
Update to draft-ietf-acme-ari-05
parent
afa60ae76f
commit
0ccd68c09a
|
@ -15,7 +15,7 @@ This Java client helps connecting to an ACME server, and performing all necessar
|
|||
* Supports [RFC 8739](https://tools.ietf.org/html/rfc8739) short-term automatic certificate renewal (experimental)
|
||||
* Supports [RFC 8823](https://tools.ietf.org/html/rfc8823) for S/MIME certificates (experimental)
|
||||
* Supports [RFC 9444](https://tools.ietf.org/html/rfc9444) for subdomain validation
|
||||
* Supports [draft-ietf-acme-ari-04](https://www.ietf.org/archive/id/draft-ietf-acme-ari-04.html) for renewal information (experimental)
|
||||
* Supports [draft-ietf-acme-ari-05](https://www.ietf.org/archive/id/draft-ietf-acme-ari-05.html) for renewal information (experimental)
|
||||
* Easy to use Java API
|
||||
* Requires JRE 11 or higher
|
||||
* Supports [Let's Encrypt](https://letsencrypt.org/), [SSL.com](https://www.ssl.com/), [ZeroSSL](https://zerossl.com), and all other CAs that comply with the ACME protocol (RFC 8555). Note that _acme4j_ is an independent project that is not supported or endorsed by any of the CAs.
|
||||
|
|
|
@ -343,6 +343,10 @@ public class OrderBuilder {
|
|||
throw new AcmeNotSupportedException("auto-renewal");
|
||||
}
|
||||
|
||||
if (replaces != null && session.resourceUrlOptional(Resource.RENEWAL_INFO).isEmpty()) {
|
||||
throw new AcmeNotSupportedException("renewal-information");
|
||||
}
|
||||
|
||||
var hasAncestorDomain = identifierSet.stream()
|
||||
.filter(id -> Identifier.TYPE_DNS.equals(id.getType()))
|
||||
.anyMatch(id -> id.toMap().containsKey(Identifier.KEY_ANCESTOR_DOMAIN));
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
package org.shredzone.acme4j;
|
||||
|
||||
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.shredzone.acme4j.toolbox.AcmeUtils.parseTimestamp;
|
||||
import static org.shredzone.acme4j.toolbox.TestUtils.getJSON;
|
||||
|
@ -169,7 +168,6 @@ public class OrderBuilderTest {
|
|||
.autoRenewalLifetime(validity)
|
||||
.autoRenewalLifetimeAdjust(predate)
|
||||
.autoRenewalEnableGet()
|
||||
.replaces("aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE")
|
||||
.create();
|
||||
|
||||
try (var softly = new AutoCloseableSoftAssertions()) {
|
||||
|
@ -335,4 +333,73 @@ public class OrderBuilderTest {
|
|||
provider.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the ARI replaces field is set.
|
||||
*/
|
||||
@Test
|
||||
public void testARIReplaces() throws Exception {
|
||||
var provider = new TestableConnectionProvider() {
|
||||
@Override
|
||||
public int sendSignedRequest(URL url, JSONBuilder claims, Login login) {
|
||||
assertThat(url).isEqualTo(resourceUrl);
|
||||
assertThatJson(claims.toString()).isEqualTo(getJSON("requestReplacesRequest").toString());
|
||||
assertThat(login).isNotNull();
|
||||
return HttpURLConnection.HTTP_CREATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSON readJsonResponse() {
|
||||
return getJSON("requestReplacesResponse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getLocation() {
|
||||
return locationUrl;
|
||||
}
|
||||
};
|
||||
|
||||
var login = provider.createLogin();
|
||||
|
||||
provider.putTestResource(Resource.NEW_ORDER, resourceUrl);
|
||||
provider.putTestResource(Resource.RENEWAL_INFO, resourceUrl);
|
||||
|
||||
var account = new Account(login);
|
||||
account.newOrder()
|
||||
.domain("example.org")
|
||||
.replaces("aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE")
|
||||
.create();
|
||||
|
||||
provider.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that exception is thrown if the ARI replaces field is set but ARI is not
|
||||
* supported.
|
||||
*/
|
||||
@Test
|
||||
public void testARIReplaceFails() throws Exception {
|
||||
var provider = new TestableConnectionProvider() {
|
||||
@Override
|
||||
public int sendSignedRequest(URL url, JSONBuilder claims, Login login) {
|
||||
fail("Request was sent");
|
||||
return HttpURLConnection.HTTP_FORBIDDEN;
|
||||
}
|
||||
};
|
||||
|
||||
var login = provider.createLogin();
|
||||
|
||||
provider.putTestResource(Resource.NEW_ORDER, resourceUrl);
|
||||
|
||||
var account = new Account(login);
|
||||
assertThatExceptionOfType(AcmeNotSupportedException.class).isThrownBy(() -> {
|
||||
account.newOrder()
|
||||
.domain("example.org")
|
||||
.replaces("aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE")
|
||||
.create();
|
||||
})
|
||||
.withMessage("Server does not support renewal-information");
|
||||
|
||||
provider.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,5 @@
|
|||
"lifetime": 604800,
|
||||
"lifetime-adjust": 518400,
|
||||
"allow-certificate-get": true
|
||||
},
|
||||
"replaces": "aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"identifiers": [
|
||||
{
|
||||
"type": "dns",
|
||||
"value": "example.org"
|
||||
}
|
||||
],
|
||||
"replaces": "aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE"
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"status": "pending",
|
||||
"expires": "2016-01-10T00:00:00Z",
|
||||
"identifiers": [
|
||||
{
|
||||
"type": "dns",
|
||||
"value": "example.org"
|
||||
}
|
||||
],
|
||||
"authorizations": [
|
||||
"https://example.com/acme/authz/1234",
|
||||
"https://example.com/acme/authz/2345"
|
||||
],
|
||||
"finalize": "https://example.com/acme/acct/1/order/1/finalize"
|
||||
}
|
|
@ -19,7 +19,7 @@ Latest version:  short-term automatic certificate renewal (experimental)
|
||||
* Supports [RFC 8823](https://tools.ietf.org/html/rfc8823) for S/MIME certificates (experimental)
|
||||
* Supports [RFC 9444](https://tools.ietf.org/html/rfc9444) for subdomain validation
|
||||
* Supports [draft-ietf-acme-ari-04](https://www.ietf.org/archive/id/draft-ietf-acme-ari-04.html) for renewal information (experimental)
|
||||
* Supports [draft-ietf-acme-ari-05](https://www.ietf.org/archive/id/draft-ietf-acme-ari-05.html) for renewal information (experimental)
|
||||
* Easy to use Java API
|
||||
* Requires JRE 11 or higher
|
||||
* Supports [Let's Encrypt](https://letsencrypt.org/), [SSL.com](https://www.ssl.com/), [ZeroSSL](https://zerossl.com), and all other CAs that comply with the ACME protocol (RFC 8555). Note that _acme4j_ is an independent project that is not supported or endorsed by any of the CAs.
|
||||
|
|
|
@ -13,7 +13,7 @@ There is no special path for renewing a certificate. To renew it, just [order](o
|
|||
|
||||
## Renewal Information
|
||||
|
||||
_acme4j_ supports the [draft-ietf-acme-ari-04](https://www.ietf.org/archive/id/draft-ietf-acme-ari-04.html) draft.
|
||||
_acme4j_ supports the [draft-ietf-acme-ari-05](https://www.ietf.org/archive/id/draft-ietf-acme-ari-05.html) draft.
|
||||
|
||||
You can check if the CA offers renewal information by invoking `Certificate.hasRenewalInfo()`. If it does, you can get a suggested time window for certificate nenewal by invoking `Certificate.getRenewalInfo()`.
|
||||
|
||||
|
|
Loading…
Reference in New Issue