Skip to content

Commit

Permalink
Use URL instead of URI for accessible resources
Browse files Browse the repository at this point in the history
  • Loading branch information
shred committed Apr 17, 2017
1 parent d1b313a commit f38002c
Show file tree
Hide file tree
Showing 51 changed files with 557 additions and 486 deletions.
17 changes: 12 additions & 5 deletions acme4j-client/src/main/java/org/shredzone/acme4j/AcmeResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@
package org.shredzone.acme4j;

import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Objects;

import org.shredzone.acme4j.exception.AcmeProtocolException;

/**
* A generic ACME resource.
*/
public abstract class AcmeResource implements Serializable {
private static final long serialVersionUID = -7930580802257379731L;

private transient Session session;
private URI location;
private URL location;

/**
* Create a new {@link AcmeResource}.
Expand Down Expand Up @@ -57,9 +60,13 @@ protected void setSession(Session session) {
/**
* Sets the resource's location.
*/
protected void setLocation(URI location) {
protected void setLocation(URL location) {
this.location = Objects.requireNonNull(location, "location");
session.setKeyIdentifier(this.location);
try {
session.setKeyIdentifier(this.location.toURI());
} catch (URISyntaxException ex) {
throw new AcmeProtocolException("Location cannot be used as key identifier", ex);
}
}

/**
Expand All @@ -82,7 +89,7 @@ public void rebind(Session session) {
/**
* Gets the resource's location.
*/
public URI getLocation() {
public URL getLocation() {
return location;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import static org.shredzone.acme4j.util.AcmeUtils.parseTimestamp;

import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -49,7 +49,7 @@ public class Authorization extends AcmeResource {
private List<List<Challenge>> combinations;
private boolean loaded = false;

protected Authorization(Session session, URI location) {
protected Authorization(Session session, URL location) {
super(session);
setLocation(location);
}
Expand All @@ -64,7 +64,7 @@ protected Authorization(Session session, URI location) {
* Location of the Authorization
* @return {@link Authorization} bound to the session and location
*/
public static Authorization bind(Session session, URI location) {
public static Authorization bind(Session session, URL location) {
return new Authorization(session, location);
}

Expand Down
38 changes: 19 additions & 19 deletions acme4j-client/src/main/java/org/shredzone/acme4j/Certificate.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
package org.shredzone.acme4j;

import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
Expand All @@ -37,19 +37,19 @@ public class Certificate extends AcmeResource {
private static final Logger LOG = LoggerFactory.getLogger(Certificate.class);
private static final int MAX_CHAIN_LENGTH = 10;

private URI chainCertUri;
private URL chainCertUrl;
private X509Certificate cert = null;
private X509Certificate[] chain = null;

protected Certificate(Session session, URI certUri) {
protected Certificate(Session session, URL certUrl) {
super(session);
setLocation(certUri);
setLocation(certUrl);
}

protected Certificate(Session session, URI certUri, URI chainUri, X509Certificate cert) {
protected Certificate(Session session, URL certUrl, URL chainUrl, X509Certificate cert) {
super(session);
setLocation(certUri);
this.chainCertUri = chainUri;
setLocation(certUrl);
this.chainCertUrl = chainUrl;
this.cert = cert;
}

Expand All @@ -62,16 +62,16 @@ protected Certificate(Session session, URI certUri, URI chainUri, X509Certificat
* Location of the Certificate
* @return {@link Certificate} bound to the session and location
*/
public static Certificate bind(Session session, URI location) {
public static Certificate bind(Session session, URL location) {
return new Certificate(session, location);
}

/**
* Returns the URI of the certificate chain. {@code null} if not known or not
* Returns the URL of the certificate chain. {@code null} if not known or not
* available.
*/
public URI getChainLocation() {
return chainCertUri;
public URL getChainLocation() {
return chainCertUrl;
}

/**
Expand All @@ -92,7 +92,7 @@ public X509Certificate download() throws AcmeException {
conn.accept(HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_ACCEPTED);
conn.handleRetryAfter("certificate is not available for download yet");

chainCertUri = conn.getLink("up");
chainCertUrl = conn.getLink("up");
cert = conn.readCertificate();
}
}
Expand All @@ -111,21 +111,21 @@ public X509Certificate download() throws AcmeException {
*/
public X509Certificate[] downloadChain() throws AcmeException {
if (chain == null) {
if (chainCertUri == null) {
if (chainCertUrl == null) {
download();
}

if (chainCertUri == null) {
if (chainCertUrl == null) {
throw new AcmeProtocolException("No certificate chain provided");
}

LOG.debug("downloadChain");

List<X509Certificate> certChain = new ArrayList<>();
URI link = chainCertUri;
URL link = chainCertUrl;
while (link != null && certChain.size() < MAX_CHAIN_LENGTH) {
try (Connection conn = getSession().provider().connect()) {
conn.sendRequest(chainCertUri, getSession());
conn.sendRequest(chainCertUrl, getSession());
conn.accept(HttpURLConnection.HTTP_OK);

certChain.add(conn.readCertificate());
Expand Down Expand Up @@ -159,8 +159,8 @@ public void revoke() throws AcmeException {
*/
public void revoke(RevocationReason reason) throws AcmeException {
LOG.debug("revoke");
URI resUri = getSession().resourceUri(Resource.REVOKE_CERT);
if (resUri == null) {
URL resUrl = getSession().resourceUrl(Resource.REVOKE_CERT);
if (resUrl == null) {
throw new AcmeProtocolException("CA does not support certificate revocation");
}

Expand All @@ -176,7 +176,7 @@ public void revoke(RevocationReason reason) throws AcmeException {
claims.put("reason", reason.getReasonCode());
}

conn.sendSignedRequest(resUri, claims, getSession());
conn.sendSignedRequest(resUrl, claims, getSession());
conn.accept(HttpURLConnection.HTTP_OK);
} catch (CertificateEncodingException ex) {
throw new AcmeProtocolException("Invalid certificate", ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static java.util.stream.Collectors.toList;

import java.net.URI;
import java.net.URL;
import java.util.Collection;

import org.shredzone.acme4j.util.JSON;
Expand Down Expand Up @@ -47,11 +48,11 @@ public URI getTermsOfService() {
}

/**
* Returns an {@link URI} to a website providing more information about the ACME
* Returns an {@link URL} to a website providing more information about the ACME
* server. {@code null} if not available.
*/
public URI getWebsite() {
return meta.get("website").asURI();
public URL getWebsite() {
return meta.get("website").asURL();
}

/**
Expand Down
29 changes: 15 additions & 14 deletions acme4j-client/src/main/java/org/shredzone/acme4j/Registration.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
import java.security.cert.X509Certificate;
import java.time.Instant;
Expand Down Expand Up @@ -57,11 +58,11 @@ public class Registration extends AcmeResource {
private final List<URI> contacts = new ArrayList<>();
private Status status;
private Boolean termsOfServiceAgreed;
private URI authorizations;
private URI certificates;
private URL authorizations;
private URL certificates;
private boolean loaded = false;

protected Registration(Session session, URI location) {
protected Registration(Session session, URL location) {
super(session);
setLocation(location);
}
Expand All @@ -75,7 +76,7 @@ protected Registration(Session session, URI location) {
* Location URI of the registration
* @return {@link Registration} bound to the session and location
*/
public static Registration bind(Session session, URI location) {
public static Registration bind(Session session, URL location) {
return new Registration(session, location);
}

Expand Down Expand Up @@ -180,7 +181,7 @@ public Authorization authorizeDomain(String domain) throws AcmeException {
.put("type", "dns")
.put("value", toAce(domain));

conn.sendSignedRequest(getSession().resourceUri(Resource.NEW_AUTHZ), claims, getSession());
conn.sendSignedRequest(getSession().resourceUrl(Resource.NEW_AUTHZ), claims, getSession());
conn.accept(HttpURLConnection.HTTP_CREATED);

JSON json = conn.readJsonResponse();
Expand Down Expand Up @@ -235,7 +236,7 @@ public Certificate requestCertificate(byte[] csr, Instant notBefore, Instant not
claims.put("notAfter", notAfter);
}

conn.sendSignedRequest(getSession().resourceUri(Resource.NEW_CERT), claims, getSession());
conn.sendSignedRequest(getSession().resourceUrl(Resource.NEW_CERT), claims, getSession());
int rc = conn.accept(HttpURLConnection.HTTP_CREATED, HttpURLConnection.HTTP_ACCEPTED);

X509Certificate cert = null;
Expand All @@ -247,9 +248,9 @@ public Certificate requestCertificate(byte[] csr, Instant notBefore, Instant not
}
}

URI chainCertUri = conn.getLink("up");
URL chainCertUrl = conn.getLink("up");

return new Certificate(getSession(), conn.getLocation(), chainCertUri, cert);
return new Certificate(getSession(), conn.getLocation(), chainCertUrl, cert);
}
}

Expand All @@ -272,7 +273,7 @@ public void changeKey(KeyPair newKeyPair) throws AcmeException {
LOG.debug("key-change");

try (Connection conn = getSession().provider().connect()) {
URI keyChangeUri = getSession().resourceUri(Resource.KEY_CHANGE);
URL keyChangeUrl = getSession().resourceUrl(Resource.KEY_CHANGE);
PublicJsonWebKey newKeyJwk = PublicJsonWebKey.Factory.newPublicJwk(newKeyPair.getPublic());

JSONBuilder payloadClaim = new JSONBuilder();
Expand All @@ -281,7 +282,7 @@ public void changeKey(KeyPair newKeyPair) throws AcmeException {

JsonWebSignature innerJws = new JsonWebSignature();
innerJws.setPayload(payloadClaim.toString());
innerJws.getHeaders().setObjectHeaderValue("url", keyChangeUri);
innerJws.getHeaders().setObjectHeaderValue("url", keyChangeUrl);
innerJws.getHeaders().setJwkHeaderValue("jwk", newKeyJwk);
innerJws.setAlgorithmHeaderValue(keyAlgorithm(newKeyJwk));
innerJws.setKey(newKeyPair.getPrivate());
Expand All @@ -293,7 +294,7 @@ public void changeKey(KeyPair newKeyPair) throws AcmeException {
outerClaim.put("signature", innerJws.getEncodedSignature());
outerClaim.put("payload", innerJws.getEncodedPayload());

conn.sendSignedRequest(keyChangeUri, outerClaim, getSession());
conn.sendSignedRequest(keyChangeUrl, outerClaim, getSession());
conn.accept(HttpURLConnection.HTTP_OK);

getSession().setKeyPair(newKeyPair);
Expand Down Expand Up @@ -356,14 +357,14 @@ private void unmarshal(JSON json, Connection conn) {
.forEach(contacts::add);
}

this.authorizations = json.get(KEY_AUTHORIZATIONS).asURI();
this.certificates = json.get(KEY_CERTIFICATES).asURI();
this.authorizations = json.get(KEY_AUTHORIZATIONS).asURL();
this.certificates = json.get(KEY_CERTIFICATES).asURL();

if (json.contains(KEY_STATUS)) {
this.status = Status.parse(json.get(KEY_STATUS).asString());
}

URI location = conn.getLocation();
URL location = conn.getLocation();
if (location != null) {
setLocation(location);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -101,10 +102,10 @@ public Registration create(Session session) throws AcmeException {
claims.put("terms-of-service-agreed", termsOfServiceAgreed);
}

conn.sendJwkSignedRequest(session.resourceUri(Resource.NEW_REG), claims, session);
conn.sendJwkSignedRequest(session.resourceUrl(Resource.NEW_REG), claims, session);
conn.accept(HttpURLConnection.HTTP_CREATED);

URI location = conn.getLocation();
URL location = conn.getLocation();

return new Registration(session, location);
}
Expand Down
19 changes: 10 additions & 9 deletions acme4j-client/src/main/java/org/shredzone/acme4j/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package org.shredzone.acme4j;

import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
import java.time.Duration;
import java.time.Instant;
Expand All @@ -40,7 +41,7 @@
* volatile data.
*/
public class Session {
private final AtomicReference<Map<Resource, URI>> resourceMap = new AtomicReference<>();
private final AtomicReference<Map<Resource, URL>> resourceMap = new AtomicReference<>();
private final AtomicReference<Metadata> metadata = new AtomicReference<>();
private final URI serverUri;
private final AcmeProvider provider;
Expand Down Expand Up @@ -190,14 +191,14 @@ public Challenge createChallenge(JSON data) {
}

/**
* Gets the {@link URI} of the given {@link Resource}. This may involve connecting to
* Gets the {@link URL} of the given {@link Resource}. This may involve connecting to
* the server and getting a directory. The result is cached.
*
* @param resource
* {@link Resource} to get the {@link URI} of
* @return {@link URI}, or {@code null} if the server does not offer that resource
* {@link Resource} to get the {@link URL} of
* @return {@link URL}, or {@code null} if the server does not offer that resource
*/
public URI resourceUri(Resource resource) throws AcmeException {
public URL resourceUrl(Resource resource) throws AcmeException {
readDirectory();
return resourceMap.get().get(Objects.requireNonNull(resource, "resource"));
}
Expand Down Expand Up @@ -234,11 +235,11 @@ private void readDirectory() throws AcmeException {
metadata.set(new Metadata(JSON.empty()));
}

Map<Resource, URI> map = new EnumMap<>(Resource.class);
Map<Resource, URL> map = new EnumMap<>(Resource.class);
for (Resource res : Resource.values()) {
URI uri = directoryJson.get(res.path()).asURI();
if (uri != null) {
map.put(res, uri);
URL url = directoryJson.get(res.path()).asURL();
if (url != null) {
map.put(res, url);
}
}
resourceMap.set(map);
Expand Down

0 comments on commit f38002c

Please sign in to comment.