mirror of https://github.com/shred/acme4j
Support the acme-ip draft
parent
fdab98ad41
commit
1cffd3428d
|
@ -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)
|
* 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 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
|
* Easy to use Java API
|
||||||
* Requires JRE 8 (update 101) or higher
|
* 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)
|
* Built with maven, packages available at [Maven Central](http://search.maven.org/#search|ga|1|g%3A%22org.shredzone.acme4j%22)
|
||||||
|
|
|
@ -17,6 +17,8 @@ import static java.util.Objects.requireNonNull;
|
||||||
import static org.shredzone.acme4j.toolbox.AcmeUtils.toAce;
|
import static org.shredzone.acme4j.toolbox.AcmeUtils.toAce;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
@ -30,6 +32,7 @@ import org.shredzone.acme4j.toolbox.JSONBuilder;
|
||||||
* Represents an identifier.
|
* Represents an identifier.
|
||||||
* <p>
|
* <p>
|
||||||
* The ACME protocol only defines the DNS identifier, which identifies a domain name.
|
* The ACME protocol only defines the DNS identifier, which identifies a domain name.
|
||||||
|
* acme4j also supports IP identifiers.
|
||||||
* <p>
|
* <p>
|
||||||
* CAs may define further, proprietary identifier types.
|
* CAs may define further, proprietary identifier types.
|
||||||
*
|
*
|
||||||
|
@ -45,6 +48,13 @@ public class Identifier implements Serializable {
|
||||||
*/
|
*/
|
||||||
public static final String DNS = "dns";
|
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_TYPE = "type";
|
||||||
private static final String KEY_VALUE = "value";
|
private static final String KEY_VALUE = "value";
|
||||||
|
|
||||||
|
@ -62,6 +72,17 @@ public class Identifier implements Serializable {
|
||||||
return new Identifier(DNS, toAce(domain));
|
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}.
|
* Creates a new {@link Identifier}.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -119,6 +140,24 @@ public class Identifier implements Serializable {
|
||||||
return value;
|
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.
|
* Returns the identifier as JSON map.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,6 +16,8 @@ package org.shredzone.acme4j;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -30,6 +32,7 @@ public class IdentifierTest {
|
||||||
@Test
|
@Test
|
||||||
public void testConstants() {
|
public void testConstants() {
|
||||||
assertThat(Identifier.DNS, is("dns"));
|
assertThat(Identifier.DNS, is("dns"));
|
||||||
|
assertThat(Identifier.IP, is("ip"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -74,6 +77,24 @@ public class IdentifierTest {
|
||||||
new Identifier("foo", "example.com").getDomain();
|
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
|
@Test
|
||||||
public void testEquals() {
|
public void testEquals() {
|
||||||
Identifier idRef = new Identifier("foo", "123.456");
|
Identifier idRef = new Identifier("foo", "123.456");
|
||||||
|
|
|
@ -20,6 +20,7 @@ import static org.shredzone.acme4j.toolbox.TestUtils.*;
|
||||||
import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs;
|
import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -80,7 +81,7 @@ public class OrderBuilderTest {
|
||||||
.identifier(Identifier.dns("d.example.com"))
|
.identifier(Identifier.dns("d.example.com"))
|
||||||
.identifiers(Arrays.asList(
|
.identifiers(Arrays.asList(
|
||||||
Identifier.dns("d2.example.com"),
|
Identifier.dns("d2.example.com"),
|
||||||
new Identifier("ip", "192.168.1.2")))
|
Identifier.ip(InetAddress.getByName("192.168.1.2"))))
|
||||||
.notBefore(notBefore)
|
.notBefore(notBefore)
|
||||||
.notAfter(notAfter)
|
.notAfter(notAfter)
|
||||||
.create();
|
.create();
|
||||||
|
@ -99,7 +100,7 @@ public class OrderBuilderTest {
|
||||||
Identifier.dns("m.example.org"),
|
Identifier.dns("m.example.org"),
|
||||||
Identifier.dns("d.example.com"),
|
Identifier.dns("d.example.com"),
|
||||||
Identifier.dns("d2.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.getNotBefore(), is(parseTimestamp("2016-01-01T00:10:00Z")));
|
||||||
assertThat(order.getNotAfter(), is(parseTimestamp("2016-01-08T00:10:00Z")));
|
assertThat(order.getNotAfter(), is(parseTimestamp("2016-01-08T00:10:00Z")));
|
||||||
assertThat(order.getExpires(), is(parseTimestamp("2016-01-10T00:00:00Z")));
|
assertThat(order.getExpires(), is(parseTimestamp("2016-01-10T00:00:00Z")));
|
||||||
|
|
Loading…
Reference in New Issue