From 148c98d673517c36b425242bac8309e02c2a5a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20K=C3=B6rber?= Date: Wed, 20 Sep 2017 20:58:52 +0200 Subject: [PATCH] Remove local truststore for Let's Encrypt servers --- README.md | 2 +- .../letsencrypt/LetsEncryptAcmeProvider.java | 9 +- .../letsencrypt/LetsEncryptHttpConnector.java | 75 ---------------- .../shredzone/acme4j/letsencrypt.truststore | Bin 1878 -> 0 bytes .../LetsEncryptHttpConnectorTest.java | 80 ------------------ src/site/markdown/ca/letsencrypt.md | 12 +-- 6 files changed, 4 insertions(+), 174 deletions(-) delete mode 100644 acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnector.java delete mode 100644 acme4j-client/src/main/resources/org/shredzone/acme4j/letsencrypt.truststore delete mode 100644 acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnectorTest.java diff --git a/README.md b/README.md index 2d6514f1..8c258e00 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ It is an independent open source implementation that is not affiliated with or e * Fully supports the ACME v2 protocol * Easy to use Java API -* Requires JRE 8 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) * Small, only requires [jose4j](https://bitbucket.org/b_c/jose4j/wiki/Home) and [slf4j](http://www.slf4j.org/) as dependencies * Extensive unit and integration tests diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java index 7d064b00..e9501003 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java @@ -17,7 +17,6 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URL; -import org.shredzone.acme4j.connector.HttpConnector; import org.shredzone.acme4j.exception.AcmeProtocolException; import org.shredzone.acme4j.provider.AbstractAcmeProvider; import org.shredzone.acme4j.provider.AcmeProvider; @@ -28,8 +27,7 @@ import org.shredzone.acme4j.provider.AcmeProvider; * The {@code serverUri} is {@code "acme://letsencrypt.org"} for the production server, * and {@code "acme://letsencrypt.org/staging"} for a testing server. *

- * If you want to use Let's Encrypt, always prefer to use this provider, as it - * takes care for the correct connection and SSL certificates. + * If you want to use Let's Encrypt, always prefer to use this provider. * * @see Let's Encrypt */ @@ -63,9 +61,4 @@ public class LetsEncryptAcmeProvider extends AbstractAcmeProvider { } } - @Override - protected HttpConnector createHttpConnector() { - return new LetsEncryptHttpConnector(); - } - } diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnector.java b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnector.java deleted file mode 100644 index 262638c5..00000000 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnector.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * acme4j - Java ACME client - * - * Copyright (C) 2015 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.provider.letsencrypt; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManagerFactory; - -import org.shredzone.acme4j.connector.HttpConnector; - -/** - * {@link HttpConnector} to be used for Let's Encrypt. It is pinned to the Let's Encrypt - * server certificate. - */ -public class LetsEncryptHttpConnector extends HttpConnector { - - private static SSLSocketFactory sslSocketFactory; - - @Override - public HttpURLConnection openConnection(URL url) throws IOException { - HttpURLConnection conn = super.openConnection(url); - if (conn instanceof HttpsURLConnection) { - ((HttpsURLConnection) conn).setSSLSocketFactory(createSocketFactory()); - } - return conn; - } - - /** - * Lazily creates an {@link SSLSocketFactory} that exclusively accepts the Let's - * Encrypt certificate. - */ - protected synchronized SSLSocketFactory createSocketFactory() throws IOException { - if (sslSocketFactory == null) { - try { - KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - keystore.load(getClass().getResourceAsStream("/org/shredzone/acme4j/letsencrypt.truststore"), - "acme4j".toCharArray()); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(keystore); - - SSLContext ctx = SSLContext.getInstance("TLS"); - ctx.init(null, tmf.getTrustManagers(), null); - - sslSocketFactory = ctx.getSocketFactory(); - } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException - | KeyManagementException ex) { - throw new IOException("Could not create truststore", ex); - } - } - return sslSocketFactory; - } - -} diff --git a/acme4j-client/src/main/resources/org/shredzone/acme4j/letsencrypt.truststore b/acme4j-client/src/main/resources/org/shredzone/acme4j/letsencrypt.truststore deleted file mode 100644 index f0631cb44e66cb48ae62376dd232f3ea446a868f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1878 zcmezO_TO6u1_mY|W(3n*MX9;@C8@=kC8)FR?K>|cBR4C9L6jl40Vf-CC<~h~Q)sZE zkbwY*!zIk=nUb0pQdC-8VkmAP3KHWM<^%IRT@->-i^@`q4CM@DKoZQtqNoxI&W;L> zrbY&G;=G2Y24+TPhUNyQCZ7 zUP)qRoh&j1wXVrpV! zWSHi3aM{;9OS9~yi=UiJF#J7vj`j-qn#C{XAGDfuDb4J}{dKYjd~a}VkKI~$;NP3x z2du~Pp1y9o7G5;x{fFcE85J3hU8)pVN=B{;9;OIS`Y|wJ#+H1{cyUyxdHq+@gb$jjqcKgPCkMnO{+@$W^tC(bwlskF* ztmlC?)nRA876Z3onK456d@-s62XJKJxVqIX+!~}{WSp}9R zCOIHS3K(qMY+MO#9*k{2^%>Zh4I2L#IIwYOvoW%=vNJJ?nPild6ck(O>lddcmlmb! zWdajg2`HiICFkerC#M#bWTs^%Cjt|=enEatW^$!|NwK~`<94_aOa_gsq#BopWMmdA zpeHZ@S+ zrCq?eVFhpXi@mnDtP{2;@g(d2bJ}#$IA?Wdje^^ZYd+>#D~{K%OVV!9$64z0x1acw(;AktELEXfa;>tI(648%hBLBuJ9@pz zvNlrYxRXE0CD*XwY@$Tc>Bas=7fdEixWI95trdrOiRRXCo|`rLHG{seaTTs9EXtqC zB$qk+)`ish0k8WrU)G=N2njm5ZOSZzDV<5*>jTS0rKWon>_6>%J*(m51lHUCcbr}u zySZCm!rpP0bNU9JOLtt)u3DEB5jD|SV{+<;IlW7dl--$h;(|!Wxp|^y4ScG7Tb_IO RJFq!jxmRA%W_w^)D*!c`k-h)` diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnectorTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnectorTest.java deleted file mode 100644 index c8396c82..00000000 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptHttpConnectorTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * acme4j - Java ACME client - * - * Copyright (C) 2015 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.provider.letsencrypt; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.SSLSocketFactory; - -import org.junit.Test; -import org.junit.experimental.categories.Category; - -/** - * Unit test for {@link LetsEncryptHttpConnector}. - */ -public class LetsEncryptHttpConnectorTest { - - /** - * Test if the connector accepts only the Let's Encrypt certificate. - *

- * This test requires a network connection. It should be excluded from automated - * builds. - */ - @Test - @Category(HttpURLConnection.class) - public void testCertificate() throws IOException { - LetsEncryptHttpConnector connector = new LetsEncryptHttpConnector(); - - try { - HttpURLConnection goodConn = connector.openConnection( - new URL("https://acme-staging.api.letsencrypt.org/directory")); - assertThat(goodConn, is(instanceOf(HttpsURLConnection.class))); - goodConn.connect(); - } catch (SSLHandshakeException ex) { - fail("Connection does not accept Let's Encrypt certificate"); - } - - try { - HttpURLConnection badConn = connector.openConnection( - new URL("https://www.google.com")); - assertThat(badConn, is(instanceOf(HttpsURLConnection.class))); - badConn.connect(); - fail("Connection accepts foreign certificate"); - } catch (SSLHandshakeException ex) { - // expected - } - } - - /** - * Test that the {@link SSLSocketFactory} can be instantiated and is cached. - */ - @Test - public void testCreateSocketFactory() throws IOException { - LetsEncryptHttpConnector connector = new LetsEncryptHttpConnector(); - - SSLSocketFactory factory1 = connector.createSocketFactory(); - assertThat(factory1, is(notNullValue())); - - SSLSocketFactory factory2 = connector.createSocketFactory(); - assertThat(factory1, is(sameInstance(factory2))); - } - -} diff --git a/src/site/markdown/ca/letsencrypt.md b/src/site/markdown/ca/letsencrypt.md index 34a9da9d..11705640 100644 --- a/src/site/markdown/ca/letsencrypt.md +++ b/src/site/markdown/ca/letsencrypt.md @@ -7,14 +7,6 @@ Web site: [Let's Encrypt](https://letsencrypt.org) * `acme://letsencrypt.org` - Production server * `acme://letsencrypt.org/staging` - Testing server -## Features +## Note -* Accepts the ACME server certificate of Let's Encrypt even on older Java versions - -## Limits - -* Registrations per IP: 10 per 3 hours -* Certificates per Domain: 5 per 7 days -* SANs per Certificate: 100 - -See [here](https://community.letsencrypt.org/t/public-beta-rate-limits/4772) for the current limits. +* Java 8u101 or higher is required for connecting to the _Let's Encrypt_ servers.