mirror of https://github.com/shred/acme4j
Allow custom pebble.minica.pem files
Also changes from a Java proprietary truststore file to the official Pebble PEM file.pull/168/head
parent
793bcd7ce1
commit
e589b16d98
|
@ -20,7 +20,9 @@ import java.security.KeyStore;
|
|||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
@ -28,12 +30,15 @@ import javax.net.ssl.TrustManagerFactory;
|
|||
|
||||
import org.shredzone.acme4j.connector.HttpConnector;
|
||||
import org.shredzone.acme4j.connector.NetworkSettings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* {@link HttpConnector} to be used for Pebble. Pebble uses a static, self-signed SSL
|
||||
* certificate.
|
||||
*/
|
||||
public class PebbleHttpConnector extends HttpConnector {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PebbleHttpConnector.class);
|
||||
private static final AtomicReference<SSLContext> SSL_CONTEXT_REF = new AtomicReference<>();
|
||||
|
||||
public PebbleHttpConnector(NetworkSettings settings) {
|
||||
|
@ -53,9 +58,11 @@ public class PebbleHttpConnector extends HttpConnector {
|
|||
*/
|
||||
protected SSLContext createSSLContext() {
|
||||
if (SSL_CONTEXT_REF.get() == null) {
|
||||
try (var in = getClass().getResourceAsStream("/org/shredzone/acme4j/provider/pebble/pebble.truststore")) {
|
||||
var keystore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keystore.load(in, "acme4j".toCharArray());
|
||||
try {
|
||||
var keystore = readPemFile("/pebble.minica.pem")
|
||||
.or(() -> readPemFile("/META-INF/pebble.minica.pem"))
|
||||
.or(() -> readPemFile("/org/shredzone/acme4j/provider/pebble/pebble.minica.pem"))
|
||||
.orElseThrow(() -> new RuntimeException("Could not find a Pebble root certificate"));
|
||||
|
||||
var tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(keystore);
|
||||
|
@ -63,12 +70,38 @@ public class PebbleHttpConnector extends HttpConnector {
|
|||
var sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, tmf.getTrustManagers(), null);
|
||||
SSL_CONTEXT_REF.set(sslContext);
|
||||
} catch (IOException | KeyStoreException | CertificateException
|
||||
| NoSuchAlgorithmException | KeyManagementException ex) {
|
||||
} catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException ex) {
|
||||
throw new RuntimeException("Could not create truststore", ex);
|
||||
}
|
||||
}
|
||||
return Objects.requireNonNull(SSL_CONTEXT_REF.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a PEM file from a resource, and returns a {@link KeyStore} that uses this
|
||||
* certificate as root CA.
|
||||
*
|
||||
* @param resource
|
||||
* Resource name
|
||||
* @return A {@link KeyStore} if the resource could be read successfully, otherwise
|
||||
* empty.
|
||||
*/
|
||||
private Optional<KeyStore> readPemFile(String resource) {
|
||||
try (var in = getClass().getResourceAsStream(resource)) {
|
||||
if (in == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
var cf = CertificateFactory.getInstance("X.509");
|
||||
var cert = cf.generateCertificate(in);
|
||||
var keystore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keystore.load(null, "acme4j".toCharArray());
|
||||
keystore.setCertificateEntry("pebble", cert);
|
||||
return Optional.of(keystore);
|
||||
} catch (IOException | KeyStoreException | CertificateException
|
||||
| NoSuchAlgorithmException ex) {
|
||||
LOG.error("Failed to read PEM from resource '{}'", resource, ex);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCTCCAfGgAwIBAgIIJOLbes8sTr4wDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgMjRlMmRiMCAXDTE3MTIwNjE5NDIxMFoYDzIxMTcx
|
||||
MjA2MTk0MjEwWjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyNGUyZGIwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5WgZNoVJandj43kkLyU50vzCZ
|
||||
alozvdRo3OFiKoDtmqKPNWRNO2hC9AUNxTDJco51Yc42u/WV3fPbbhSznTiOOVtn
|
||||
Ajm6iq4I5nZYltGGZetGDOQWr78y2gWY+SG078MuOO2hyDIiKtVc3xiXYA+8Hluu
|
||||
9F8KbqSS1h55yxZ9b87eKR+B0zu2ahzBCIHKmKWgc6N13l7aDxxY3D6uq8gtJRU0
|
||||
toumyLbdzGcupVvjbjDP11nl07RESDWBLG1/g3ktJvqIa4BWgU2HMh4rND6y8OD3
|
||||
Hy3H8MY6CElL+MOCbFJjWqhtOxeFyZZV9q3kYnk9CAuQJKMEGuN4GU6tzhW1AgMB
|
||||
AAGjRTBDMA4GA1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
|
||||
BQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsFAAOCAQEAF85v
|
||||
d40HK1ouDAtWeO1PbnWfGEmC5Xa478s9ddOd9Clvp2McYzNlAFfM7kdcj6xeiNhF
|
||||
WPIfaGAi/QdURSL/6C1KsVDqlFBlTs9zYfh2g0UXGvJtj1maeih7zxFLvet+fqll
|
||||
xseM4P9EVJaQxwuK/F78YBt0tCNfivC6JNZMgxKF59h0FBpH70ytUSHXdz7FKwix
|
||||
Mfn3qEb9BXSk0Q3prNV5sOV3vgjEtB4THfDxSz9z3+DepVnW3vbbqwEbkXdk3j82
|
||||
2muVldgOUgTwK8eT+XdofVdntzU/kzygSAtAQwLJfn51fS1GvEcYGBc1bDryIqmF
|
||||
p9BI7gVKtWSZYegicA==
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
Loading…
Reference in New Issue