mirror of https://github.com/shred/acme4j
Handle IDE domain names
parent
dc74a54116
commit
ef42e04793
|
@ -39,6 +39,7 @@ import org.shredzone.acme4j.exception.AcmeNetworkException;
|
||||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||||
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
||||||
import org.shredzone.acme4j.util.ClaimBuilder;
|
import org.shredzone.acme4j.util.ClaimBuilder;
|
||||||
|
import org.shredzone.acme4j.util.DomainUtils;
|
||||||
import org.shredzone.acme4j.util.SignatureUtils;
|
import org.shredzone.acme4j.util.SignatureUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -173,6 +174,8 @@ public class Registration extends AcmeResource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorizes a domain. The domain is associated with this registration.
|
* Authorizes a domain. The domain is associated with this registration.
|
||||||
|
* <p>
|
||||||
|
* IDN domain names will be ACE encoded automatically.
|
||||||
*
|
*
|
||||||
* @param domain
|
* @param domain
|
||||||
* Domain name to be authorized
|
* Domain name to be authorized
|
||||||
|
@ -189,7 +192,7 @@ public class Registration extends AcmeResource {
|
||||||
claims.putResource(Resource.NEW_AUTHZ);
|
claims.putResource(Resource.NEW_AUTHZ);
|
||||||
claims.object("identifier")
|
claims.object("identifier")
|
||||||
.put("type", "dns")
|
.put("type", "dns")
|
||||||
.put("value", domain);
|
.put("value", DomainUtils.toAce(domain));
|
||||||
|
|
||||||
int rc = conn.sendSignedRequest(getSession().resourceUri(Resource.NEW_AUTHZ), claims, getSession());
|
int rc = conn.sendSignedRequest(getSession().resourceUri(Resource.NEW_AUTHZ), claims, getSession());
|
||||||
if (rc != HttpURLConnection.HTTP_CREATED) {
|
if (rc != HttpURLConnection.HTTP_CREATED) {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* acme4j - Java ACME client
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Richard "Shred" Körber
|
||||||
|
* http://acme4j.shredzone.org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
package org.shredzone.acme4j.util;
|
||||||
|
|
||||||
|
import java.net.IDN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for domains and domain names.
|
||||||
|
*/
|
||||||
|
public final class DomainUtils {
|
||||||
|
|
||||||
|
private DomainUtils() {
|
||||||
|
// Utility class without constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ASCII encodes a domain name.
|
||||||
|
* <p>
|
||||||
|
* The conversion is done as described in
|
||||||
|
* <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>. Additionally, all
|
||||||
|
* leading and trailing white spaces are trimmed, and the result is lowercased.
|
||||||
|
* <p>
|
||||||
|
* It is safe to pass in ACE encoded domains, they will be returned unchanged.
|
||||||
|
*
|
||||||
|
* @param domain
|
||||||
|
* Domain name to encode
|
||||||
|
* @return Encoded domain name, white space trimmed and lower cased. {@code null} if
|
||||||
|
* {@code null} was passed in.
|
||||||
|
*/
|
||||||
|
public static String toAce(String domain) {
|
||||||
|
if (domain == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return IDN.toASCII(domain.trim()).toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* acme4j - Java ACME client
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Richard "Shred" Körber
|
||||||
|
* http://acme4j.shredzone.org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
package org.shredzone.acme4j.util;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link DomainUtils}.
|
||||||
|
*/
|
||||||
|
public class DomainUtilsTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test ACE conversion.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testToAce() {
|
||||||
|
// Test ASCII domains in different notations
|
||||||
|
assertThat(DomainUtils.toAce("example.com"), is("example.com"));
|
||||||
|
assertThat(DomainUtils.toAce(" example.com "), is("example.com"));
|
||||||
|
assertThat(DomainUtils.toAce("ExAmPlE.CoM"), is("example.com"));
|
||||||
|
assertThat(DomainUtils.toAce("foo.example.com"), is("foo.example.com"));
|
||||||
|
assertThat(DomainUtils.toAce("bar.foo.example.com"), is("bar.foo.example.com"));
|
||||||
|
|
||||||
|
// Test IDN domains
|
||||||
|
assertThat(DomainUtils.toAce("ExÄmþle.¢öM"), is("xn--exmle-hra7p.xn--m-7ba6w"));
|
||||||
|
|
||||||
|
// Test alternate separators
|
||||||
|
assertThat(DomainUtils.toAce("example\u3002com"), is("example.com"));
|
||||||
|
assertThat(DomainUtils.toAce("example\uff0ecom"), is("example.com"));
|
||||||
|
assertThat(DomainUtils.toAce("example\uff61com"), is("example.com"));
|
||||||
|
|
||||||
|
// Test ACE encoded domains, they must not change
|
||||||
|
assertThat(DomainUtils.toAce("xn--exmle-hra7p.xn--m-7ba6w"),
|
||||||
|
is("xn--exmle-hra7p.xn--m-7ba6w"));
|
||||||
|
|
||||||
|
// Test null
|
||||||
|
assertThat(DomainUtils.toAce(null), is(nullValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -59,17 +59,22 @@ public class CSRBuilder {
|
||||||
* <em>Common Name</em>. All domain names will be added as <em>Subject
|
* <em>Common Name</em>. All domain names will be added as <em>Subject
|
||||||
* Alternative Name</em>.
|
* Alternative Name</em>.
|
||||||
* <p>
|
* <p>
|
||||||
|
* IDN domain names are ACE encoded automatically.
|
||||||
|
* <p>
|
||||||
* Note that ACME servers may not accept wildcard domains!
|
* Note that ACME servers may not accept wildcard domains!
|
||||||
*/
|
*/
|
||||||
public void addDomain(String domain) {
|
public void addDomain(String domain) {
|
||||||
|
String ace = DomainUtils.toAce(domain);
|
||||||
if (namelist.isEmpty()) {
|
if (namelist.isEmpty()) {
|
||||||
namebuilder.addRDN(BCStyle.CN, domain);
|
namebuilder.addRDN(BCStyle.CN, ace);
|
||||||
}
|
}
|
||||||
namelist.add(domain);
|
namelist.add(ace);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a {@link Collection} of domains.
|
* Adds a {@link Collection} of domains.
|
||||||
|
* <p>
|
||||||
|
* IDN domain names are ACE encoded automatically.
|
||||||
*/
|
*/
|
||||||
public void addDomains(Collection<String> domains) {
|
public void addDomains(Collection<String> domains) {
|
||||||
for (String domain : domains) {
|
for (String domain : domains) {
|
||||||
|
@ -79,6 +84,8 @@ public class CSRBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds multiple domain names.
|
* Adds multiple domain names.
|
||||||
|
* <p>
|
||||||
|
* IDN domain names are ACE encoded automatically.
|
||||||
*/
|
*/
|
||||||
public void addDomains(String... domains) {
|
public void addDomains(String... domains) {
|
||||||
for (String domain : domains) {
|
for (String domain : domains) {
|
||||||
|
|
Loading…
Reference in New Issue