mirror of https://github.com/shred/acme4j
Make CertificateUtils.createTlsSniCertificate more useful for TLS-SNI challenge
parent
5e699df6c1
commit
7b6af21cd1
|
@ -95,19 +95,18 @@ public final class CertificateUtils {
|
||||||
* Creates a self-signed {@link X509Certificate} that can be used for
|
* Creates a self-signed {@link X509Certificate} that can be used for
|
||||||
* {@link TlsSniChallenge}. The certificate is valid for 7 days.
|
* {@link TlsSniChallenge}. The certificate is valid for 7 days.
|
||||||
*
|
*
|
||||||
|
* @param keypair
|
||||||
|
* A domain {@link KeyPair} to be used for the challenge
|
||||||
* @param subject
|
* @param subject
|
||||||
* Subject to create a certificate for
|
* Subject to create a certificate for
|
||||||
* @return Created certificate
|
* @return Created certificate
|
||||||
*/
|
*/
|
||||||
public static X509Certificate createTlsSniCertificate(String subject) throws IOException {
|
public static X509Certificate createTlsSniCertificate(KeyPair keypair, String subject) throws IOException {
|
||||||
final int certSize = 2048;
|
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
final long validSpanMs = 7 * 24 * 60 * 60 * 1000L;
|
final long validSpanMs = 7 * 24 * 60 * 60 * 1000L;
|
||||||
final String signatureAlg = "SHA256withRSA";
|
final String signatureAlg = "SHA256withRSA";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
KeyPair keypair = KeyPairUtils.createKeyPair(certSize);
|
|
||||||
|
|
||||||
X500Name issuer = new X500Name("CN=acme.invalid");
|
X500Name issuer = new X500Name("CN=acme.invalid");
|
||||||
BigInteger serial = BigInteger.valueOf(now);
|
BigInteger serial = BigInteger.valueOf(now);
|
||||||
Date notBefore = new Date(now);
|
Date notBefore = new Date(now);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.security.KeyPair;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.CertificateParsingException;
|
import java.security.cert.CertificateParsingException;
|
||||||
|
@ -84,17 +85,20 @@ public class CertificateUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if {@link CertificateUtils#createTlsSniCertificate(String)} creates a
|
* Test if {@link CertificateUtils#createTlsSniCertificate(KeyPair, String)} creates a
|
||||||
* good certificate.
|
* good certificate.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCreateTlsSniCertificate() throws IOException, CertificateParsingException {
|
public void testCreateTlsSniCertificate() throws IOException, CertificateParsingException {
|
||||||
String subject = "30c452b9bd088cdbc2c4094947025d7c.7364ea602ac325a1b55ceaae024fbe29.acme.invalid";
|
String subject = "30c452b9bd088cdbc2c4094947025d7c.7364ea602ac325a1b55ceaae024fbe29.acme.invalid";
|
||||||
|
|
||||||
|
KeyPair keypair = KeyPairUtils.createKeyPair(2048);
|
||||||
|
|
||||||
|
X509Certificate cert = CertificateUtils.createTlsSniCertificate(keypair, subject);
|
||||||
|
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date end = new Date(now.getTime() + (8 * 24 * 60 * 60 * 1000L));
|
Date end = new Date(now.getTime() + (8 * 24 * 60 * 60 * 1000L));
|
||||||
|
|
||||||
X509Certificate cert = CertificateUtils.createTlsSniCertificate(subject);
|
|
||||||
|
|
||||||
assertThat(cert, not(nullValue()));
|
assertThat(cert, not(nullValue()));
|
||||||
assertThat(cert.getNotAfter(), is(greaterThan(now)));
|
assertThat(cert.getNotAfter(), is(greaterThan(now)));
|
||||||
assertThat(cert.getNotAfter(), is(lessThan(end)));
|
assertThat(cert.getNotAfter(), is(lessThan(end)));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# TLS-SNI
|
# TLS-SNI
|
||||||
|
|
||||||
With the TLS-SNI 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 self-signed cert.
|
With the TLS-SNI 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.
|
||||||
|
|
||||||
After authorizing the challenge, `TlsSniChallenge` provides a subject:
|
After authorizing the challenge, `TlsSniChallenge` provides a subject:
|
||||||
|
|
||||||
|
@ -22,7 +22,20 @@ You need to create a self-signed certificate with the subject set as _Subject Al
|
||||||
The `TlsSniChallenge` class does not generate a self-signed certificate, as it would require _Bouncy Castle_. However, there is a utility method in the _acme4j-utils_ module for this use case:
|
The `TlsSniChallenge` class does not generate a self-signed certificate, as it would require _Bouncy Castle_. However, there is a utility method in the _acme4j-utils_ module for this use case:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
X509Certificate cert = CertificateUtils.createTlsSniCertificate(String subject);
|
KeyPair sniKeyPair = KeyPairUtils.createKeyPair(2048);
|
||||||
|
X509Certificate cert = CertificateUtils.createTlsSniCertificate(sniKeyPair, subject);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Now use `cert` and `sniKeyPair` to let your web server respond to a SNI request to `domain`.
|
||||||
|
|
||||||
The challenge is completed when the CA was able to send the SNI request and get the correct certificate in return.
|
The challenge is completed when the CA was able to send the SNI request and get the correct certificate in return.
|
||||||
|
|
||||||
|
This shell command line may be helpful to test your web server configuration:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
echo QUIT | \
|
||||||
|
openssl s_client -servername $domain -connect $server_ip:443 | \
|
||||||
|
openssl x509 -text -noout
|
||||||
|
```
|
||||||
|
|
||||||
|
It should return a certificate with `domain` set as `X509v3 Subject Alternative Name`.
|
||||||
|
|
Loading…
Reference in New Issue