Support the acme-ip draft

pull/81/head
Richard Körber 2018-08-20 23:36:38 +02:00
parent fdab98ad41
commit 1cffd3428d
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
4 changed files with 64 additions and 2 deletions

View File

@ -12,6 +12,7 @@ It is an independent open source implementation that is not affiliated with or e
* Fully supports the ACME v2 protocol up to [draft 13](https://tools.ietf.org/html/draft-ietf-acme-acme-13)
* Supports all ACME challenges and the `tls-alpn-01` challenge
* Supports the [acme-ip draft](https://tools.ietf.org/html/draft-ietf-acme-ip)
* Easy to use Java API
* Requires JRE 8 (update 101) or higher
* Built with maven, packages available at [Maven Central](http://search.maven.org/#search|ga|1|g%3A%22org.shredzone.acme4j%22)

View File

@ -17,6 +17,8 @@ import static java.util.Objects.requireNonNull;
import static org.shredzone.acme4j.toolbox.AcmeUtils.toAce;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import javax.annotation.ParametersAreNonnullByDefault;
@ -30,6 +32,7 @@ import org.shredzone.acme4j.toolbox.JSONBuilder;
* Represents an identifier.
* <p>
* The ACME protocol only defines the DNS identifier, which identifies a domain name.
* acme4j also supports IP identifiers.
* <p>
* CAs may define further, proprietary identifier types.
*
@ -45,6 +48,13 @@ public class Identifier implements Serializable {
*/
public static final String DNS = "dns";
/**
* Type constant for IP identifiers.
*
* @see <a href="https://tools.ietf.org/html/draft-ietf-acme-ip">draft-ietf-acme-ip</a>
*/
public static final String IP = "ip";
private static final String KEY_TYPE = "type";
private static final String KEY_VALUE = "value";
@ -62,6 +72,17 @@ public class Identifier implements Serializable {
return new Identifier(DNS, toAce(domain));
}
/**
* Creates a new IP identifier for the given {@link InetAddress}.
*
* @param ip
* {@link InetAddress}
* @return New {@link Identifier}
*/
public static Identifier ip(InetAddress ip) {
return new Identifier(IP, ip.getHostAddress());
}
/**
* Creates a new {@link Identifier}.
* <p>
@ -119,6 +140,24 @@ public class Identifier implements Serializable {
return value;
}
/**
* Returns the IP address if this is an IP identifier.
*
* @return {@link InetAddress}
* @throws AcmeProtocolException
* if this is not a DNS identifier.
*/
public InetAddress getIP() {
if (!IP.equals(type)) {
throw new AcmeProtocolException("expected 'ip' identifier, but found '" + type + "'");
}
try {
return InetAddress.getByName(value);
} catch (UnknownHostException ex) {
throw new AcmeProtocolException("bad ip identifier value", ex);
}
}
/**
* Returns the identifier as JSON map.
*/

View File

@ -16,6 +16,8 @@ package org.shredzone.acme4j;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import org.junit.Test;
@ -30,6 +32,7 @@ public class IdentifierTest {
@Test
public void testConstants() {
assertThat(Identifier.DNS, is("dns"));
assertThat(Identifier.IP, is("ip"));
}
@Test
@ -74,6 +77,24 @@ public class IdentifierTest {
new Identifier("foo", "example.com").getDomain();
}
@Test
public void testIp() throws UnknownHostException {
Identifier id1 = Identifier.ip(InetAddress.getByName("192.168.1.2"));
assertThat(id1.getType(), is(Identifier.IP));
assertThat(id1.getValue(), is("192.168.1.2"));
assertThat(id1.getIP().getHostAddress(), is("192.168.1.2"));
Identifier id2 = Identifier.ip(InetAddress.getByName("2001:db8:85a3::8a2e:370:7334"));
assertThat(id2.getType(), is(Identifier.IP));
assertThat(id2.getValue(), is("2001:db8:85a3:0:0:8a2e:370:7334"));
assertThat(id2.getIP().getHostAddress(), is("2001:db8:85a3:0:0:8a2e:370:7334"));
}
@Test(expected = AcmeProtocolException.class)
public void testNoIp() {
new Identifier("foo", "example.com").getIP();
}
@Test
public void testEquals() {
Identifier idRef = new Identifier("foo", "123.456");

View File

@ -20,6 +20,7 @@ import static org.shredzone.acme4j.toolbox.TestUtils.*;
import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.time.Instant;
import java.util.Arrays;
@ -80,7 +81,7 @@ public class OrderBuilderTest {
.identifier(Identifier.dns("d.example.com"))
.identifiers(Arrays.asList(
Identifier.dns("d2.example.com"),
new Identifier("ip", "192.168.1.2")))
Identifier.ip(InetAddress.getByName("192.168.1.2"))))
.notBefore(notBefore)
.notAfter(notAfter)
.create();
@ -99,7 +100,7 @@ public class OrderBuilderTest {
Identifier.dns("m.example.org"),
Identifier.dns("d.example.com"),
Identifier.dns("d2.example.com"),
new Identifier("ip", "192.168.1.2")));
Identifier.ip(InetAddress.getByName("192.168.1.2"))));
assertThat(order.getNotBefore(), is(parseTimestamp("2016-01-01T00:10:00Z")));
assertThat(order.getNotAfter(), is(parseTimestamp("2016-01-08T00:10:00Z")));
assertThat(order.getExpires(), is(parseTimestamp("2016-01-10T00:00:00Z")));