mirror of https://github.com/shred/acme4j
Deprecate tls-sni challenges
parent
a01a9165a8
commit
1fd515912a
|
@ -19,7 +19,12 @@ import org.shredzone.acme4j.Session;
|
|||
|
||||
/**
|
||||
* Implements the {@value TYPE} challenge.
|
||||
*
|
||||
* @deprecated This challenge is vulnerable and will be removed from the ACME specs. Do
|
||||
* not use! Let's Encrypt does not offer this challenge to the general public
|
||||
* any more.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TlsSni01Challenge extends TokenChallenge {
|
||||
private static final long serialVersionUID = 7370329525205430573L;
|
||||
|
||||
|
|
|
@ -19,7 +19,11 @@ import org.shredzone.acme4j.Session;
|
|||
|
||||
/**
|
||||
* Implements the {@value TYPE} challenge.
|
||||
*
|
||||
* @deprecated This challenge is vulnerable and will be removed from the ACME specs. Do
|
||||
* not use!
|
||||
*/
|
||||
@Deprecated
|
||||
public class TlsSni02Challenge extends TokenChallenge {
|
||||
private static final long serialVersionUID = 8921833167878544518L;
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.shredzone.acme4j.toolbox.JSON;
|
|||
* Implementing classes must implement at least {@link AcmeProvider#accepts(URI)}
|
||||
* and {@link AbstractAcmeProvider#resolve(URI)}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class AbstractAcmeProvider implements AcmeProvider {
|
||||
|
||||
private static final Map<String, Function<Session, Challenge>> CHALLENGES = challengeMap();
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.shredzone.acme4j.toolbox.JSONBuilder;
|
|||
/**
|
||||
* Unit tests for {@link Authorization}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class AuthorizationTest {
|
||||
|
||||
private static final String SNAILMAIL_TYPE = "snail-01"; // a non-existent challenge
|
||||
|
|
|
@ -45,6 +45,7 @@ public class TlsSni01ChallengeTest {
|
|||
* Test that {@link TlsSni01Challenge} generates a correct authorization key.
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testTlsSniChallenge() throws IOException {
|
||||
TlsSni01Challenge challenge = new TlsSni01Challenge(session);
|
||||
challenge.unmarshall(getJsonAsObject("tlsSniChallenge"));
|
||||
|
|
|
@ -45,6 +45,7 @@ public class TlsSni02ChallengeTest {
|
|||
* Test that {@link TlsSni02Challenge} generates a correct authorization key.
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testTlsSni02Challenge() throws IOException {
|
||||
TlsSni02Challenge challenge = new TlsSni02Challenge(session);
|
||||
challenge.unmarshall(getJsonAsObject("tlsSni02Challenge"));
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.shredzone.acme4j.toolbox.TestUtils;
|
|||
/**
|
||||
* Unit tests for {@link AbstractAcmeProvider}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class AbstractAcmeProviderTest {
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,6 +41,7 @@ public class LetsEncryptHttpConnectorTest {
|
|||
*/
|
||||
@Test
|
||||
@Category(HttpURLConnection.class)
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testCertificate() throws IOException, URISyntaxException {
|
||||
LetsEncryptHttpConnector connector = new LetsEncryptHttpConnector();
|
||||
|
||||
|
@ -68,6 +69,7 @@ public class LetsEncryptHttpConnectorTest {
|
|||
* Test that the {@link SSLSocketFactory} can be instantiated and is cached.
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testCreateSocketFactory() throws IOException {
|
||||
LetsEncryptHttpConnector connector = new LetsEncryptHttpConnector();
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ public class ClientTest {
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ClientTest.class);
|
||||
|
||||
private enum ChallengeType { HTTP, DNS, TLSSNI }
|
||||
private enum ChallengeType { HTTP, DNS }
|
||||
|
||||
/**
|
||||
* Generates a certificate for the given domains. Also takes care for the registration
|
||||
|
@ -210,10 +210,6 @@ public class ClientTest {
|
|||
case DNS:
|
||||
challenge = dnsChallenge(auth, domain);
|
||||
break;
|
||||
|
||||
case TLSSNI:
|
||||
challenge = tlsSniChallenge(auth, domain);
|
||||
break;
|
||||
}
|
||||
|
||||
if (challenge == null) {
|
||||
|
@ -329,63 +325,6 @@ public class ClientTest {
|
|||
return challenge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a TLS-SNI challenge.
|
||||
* <p>
|
||||
* The verification of this challenge expects that the web server returns a special
|
||||
* validation certificate.
|
||||
* <p>
|
||||
* This example outputs instructions that need to be executed manually. In a
|
||||
* production environment, you would rather configure your web server automatically.
|
||||
*
|
||||
* @param auth
|
||||
* {@link Authorization} to find the challenge in
|
||||
* @param domain
|
||||
* Domain name to be authorized
|
||||
* @return {@link Challenge} to verify
|
||||
*/
|
||||
public Challenge tlsSniChallenge(Authorization auth, String domain) throws AcmeException {
|
||||
// Find a single tls-sni-01 challenge
|
||||
org.shredzone.acme4j.challenge.TlsSni01Challenge challenge = auth.findChallenge(org.shredzone.acme4j.challenge.TlsSni01Challenge.TYPE);
|
||||
if (challenge == null) {
|
||||
throw new AcmeException("Found no " + org.shredzone.acme4j.challenge.TlsSni01Challenge.TYPE + " challenge, don't know what to do...");
|
||||
}
|
||||
|
||||
// Get the Subject
|
||||
String subject = challenge.getSubject();
|
||||
|
||||
// Create a validation key pair
|
||||
KeyPair domainKeyPair;
|
||||
try (FileWriter fw = new FileWriter("tlssni.key")) {
|
||||
domainKeyPair = KeyPairUtils.createKeyPair(2048);
|
||||
KeyPairUtils.writeKeyPair(domainKeyPair, fw);
|
||||
} catch (IOException ex) {
|
||||
throw new AcmeException("Could not write keypair", ex);
|
||||
}
|
||||
|
||||
// Create a validation certificate
|
||||
try (FileWriter fw = new FileWriter("tlssni.crt")) {
|
||||
X509Certificate cert = CertificateUtils.createTlsSniCertificate(domainKeyPair, subject);
|
||||
CertificateUtils.writeX509Certificate(cert, fw);
|
||||
} catch (IOException ex) {
|
||||
throw new AcmeException("Could not write certificate", ex);
|
||||
}
|
||||
|
||||
// Output the challenge, wait for acknowledge...
|
||||
LOG.info("Please configure your web server.");
|
||||
LOG.info("It must return the certificate 'tlssni.crt' on a SNI request to:");
|
||||
LOG.info(subject);
|
||||
LOG.info("The matching keypair is available at 'tlssni.key'.");
|
||||
LOG.info("If you're ready, dismiss the dialog...");
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("Please use 'tlssni.key' and 'tlssni.crt' cert for SNI requests to:\n\n");
|
||||
message.append("https://").append(subject).append("\n\n");
|
||||
acceptChallenge(message.toString());
|
||||
|
||||
return challenge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the instructions for preparing the challenge validation, and waits for
|
||||
* dismissal. If the user cancelled the dialog, an exception is thrown.
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
|
|||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
|
||||
import org.shredzone.acme4j.challenge.TlsSni02Challenge;
|
||||
|
||||
/**
|
||||
* Utility class offering convenience methods for certificates.
|
||||
|
@ -177,14 +176,17 @@ public final class CertificateUtils {
|
|||
* @param subject
|
||||
* Subject to create a certificate for
|
||||
* @return Created certificate
|
||||
* @deprecated The tls-sni-01 challenge is deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public static X509Certificate createTlsSniCertificate(KeyPair keypair, String subject) throws IOException {
|
||||
return createCertificate(keypair, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a self-signed {@link X509Certificate} that can be used for
|
||||
* {@link TlsSni02Challenge}. The certificate is valid for 7 days.
|
||||
* {@link org.shredzone.acme4j.challenge.TlsSni02Challenge}. The certificate is valid
|
||||
* for 7 days.
|
||||
*
|
||||
* @param keypair
|
||||
* A domain {@link KeyPair} to be used for the challenge
|
||||
|
@ -193,7 +195,9 @@ public final class CertificateUtils {
|
|||
* @param sanB
|
||||
* SAN-B to be used in the certificate
|
||||
* @return Created certificate
|
||||
* @deprecated The tls-sni-02 challenge is deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public static X509Certificate createTlsSni02Certificate(KeyPair keypair, String sanA, String sanB)
|
||||
throws IOException {
|
||||
return createCertificate(keypair, sanA, sanB);
|
||||
|
|
|
@ -125,8 +125,8 @@ public class CertificateUtilsTest {
|
|||
* Test if {@link CertificateUtils#createTlsSniCertificate(KeyPair, String)} creates a
|
||||
* good certificate.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
@SuppressWarnings("deprecation") // test deprecated method
|
||||
public void testCreateTlsSniCertificate() throws IOException, CertificateParsingException {
|
||||
String subject = "30c452b9bd088cdbc2c4094947025d7c.7364ea602ac325a1b55ceaae024fbe29.acme.invalid";
|
||||
|
||||
|
@ -149,6 +149,7 @@ public class CertificateUtilsTest {
|
|||
* Test if {@link CertificateUtils#createTlsSni02Certificate(KeyPair, String, String)}
|
||||
* creates a good certificate.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testCreateTlsSni02Certificate() throws IOException, CertificateParsingException {
|
||||
String sanA = "1082909237a535173c8415a44539f84e.248317530d8d1a0c71de8fd23f1beae4.token.acme.invalid";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# tls-sni-01 Challenge
|
||||
|
||||
> **NOTE:** In ACMEv2, this challenge is going to be replaced by [tls-sni-02](./tls-sni-02.html). However, the _Let's Encrypt_ ACMEv1 server is still offering this challenge as the only TLS-SNI based challenge. To be on the safe side, request both challenges and process the one that is returned.
|
||||
> **SECURITY:** [This challenge is vulnerable in shared hosting environments](https://community.letsencrypt.org/t/2018-01-09-issue-with-tls-sni-01-and-shared-hosting-infrastructure/49996), and is going to be removed from the ACME specs. _Let's Encrypt_ does not offer this challenge to the general public any more.
|
||||
|
||||
With the `tls-sni-01` challenge, you prove to the CA that you are able to control the web server of the domain to be authorized, by letting it respond to a SNI request with a specific self-signed cert.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# tls-sni-02 Challenge
|
||||
|
||||
> **NOTE:** According to the ACME specifications, this challenge will replace [tls-sni-01](./tls-sni-01.html). However, _Let's Encrypt_ does not currently support `tls-sni-02`. To be on the safe side, request both challenges and process the one that is returned.
|
||||
> **SECURITY:** [This challenge is vulnerable in shared hosting environments](https://community.letsencrypt.org/t/2018-01-09-issue-with-tls-sni-01-and-shared-hosting-infrastructure/49996), and is going to be removed from the ACME specs.
|
||||
|
||||
With the `tls-sni-02` challenge, you prove to the CA that you are able to control the web server of the domain to be authorized, by letting it respond to a SNI request with a specific self-signed cert.
|
||||
|
||||
|
|
Loading…
Reference in New Issue