mirror of https://github.com/shred/acme4j
Remove methods for reading and writing certificates
parent
846e200e62
commit
4478228c5e
|
@ -21,6 +21,7 @@ import java.io.Writer;
|
|||
import java.net.URI;
|
||||
import java.security.KeyPair;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -34,6 +35,7 @@ import org.shredzone.acme4j.challenge.Http01Challenge;
|
|||
import org.shredzone.acme4j.challenge.TlsSni02Challenge;
|
||||
import org.shredzone.acme4j.exception.AcmeConflictException;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.util.AcmeUtils;
|
||||
import org.shredzone.acme4j.util.CSRBuilder;
|
||||
import org.shredzone.acme4j.util.CertificateUtils;
|
||||
import org.shredzone.acme4j.util.KeyPairUtils;
|
||||
|
@ -389,8 +391,8 @@ public class ClientTest {
|
|||
// Create a validation certificate
|
||||
try (FileWriter fw = new FileWriter("tlssni.crt")) {
|
||||
X509Certificate cert = CertificateUtils.createTlsSni02Certificate(domainKeyPair, subject, sanB);
|
||||
CertificateUtils.writeX509Certificate(cert, fw);
|
||||
} catch (IOException ex) {
|
||||
AcmeUtils.writeToPem(cert.getEncoded(), "CERTIFICATE", fw);
|
||||
} catch (IOException | CertificateEncodingException ex) {
|
||||
throw new AcmeException("Could not write certificate", ex);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,6 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.cert.CertificateException;
|
||||
|
@ -35,7 +32,6 @@ import org.bouncycastle.asn1.x509.GeneralName;
|
|||
import org.bouncycastle.asn1.x509.GeneralNames;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.openssl.PEMParser;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
|
||||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
|
||||
|
@ -52,103 +48,6 @@ public final class CertificateUtils {
|
|||
// utility class without constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an {@link X509Certificate} PEM file from an {@link InputStream}.
|
||||
*
|
||||
* @param in
|
||||
* {@link InputStream} to read the certificate from. The
|
||||
* {@link InputStream} is closed after use.
|
||||
* @return {@link X509Certificate} that was read
|
||||
*/
|
||||
public static X509Certificate readX509Certificate(InputStream in) throws IOException {
|
||||
try (InputStream uin = in) {
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
return (X509Certificate) certificateFactory.generateCertificate(uin);
|
||||
} catch (CertificateException ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an X.509 certificate PEM file.
|
||||
*
|
||||
* @param cert
|
||||
* {@link X509Certificate} to write
|
||||
* @param out
|
||||
* {@link OutputStream} to write the PEM file to. The {@link OutputStream}
|
||||
* is closed after use.
|
||||
*/
|
||||
public static void writeX509Certificate(X509Certificate cert, OutputStream out) throws IOException {
|
||||
writeX509Certificate(cert, new OutputStreamWriter(out, "utf-8"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an X.509 certificate PEM file.
|
||||
*
|
||||
* @param cert
|
||||
* {@link X509Certificate} to write
|
||||
* @param w
|
||||
* {@link Writer} to write the PEM file to. The {@link Writer} is closed
|
||||
* after use.
|
||||
*/
|
||||
public static void writeX509Certificate(X509Certificate cert, Writer w) throws IOException {
|
||||
try (JcaPEMWriter jw = new JcaPEMWriter(w)) {
|
||||
writeCertIfNotNull(jw, cert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a X.509 certificate chain to a PEM file.
|
||||
*
|
||||
* @param w
|
||||
* {@link Writer} to write the certificate chain to. The {@link Writer} is
|
||||
* closed after use.
|
||||
* @param cert
|
||||
* {@link X509Certificate} to write, {@code null} to skip this certificate
|
||||
* @param chain
|
||||
* {@link X509Certificate} chain to add to the certificate. {@code null}
|
||||
* values are ignored, array may be empty.
|
||||
*/
|
||||
public static void writeX509CertificateChain(Writer w, X509Certificate cert, X509Certificate... chain)
|
||||
throws IOException {
|
||||
try (JcaPEMWriter jw = new JcaPEMWriter(w)) {
|
||||
writeCertIfNotNull(jw, cert);
|
||||
for (X509Certificate c : chain) {
|
||||
writeCertIfNotNull(jw, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an {@link X509Certificate} unless it is {@code null}.
|
||||
*
|
||||
* @param jw
|
||||
* {@link JcaPEMWriter} to write to
|
||||
* @param cert
|
||||
* {@link X509Certificate} to write, or {@code null}
|
||||
*/
|
||||
private static void writeCertIfNotNull(JcaPEMWriter jw, X509Certificate cert) throws IOException {
|
||||
if (cert != null) {
|
||||
jw.writeObject(cert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an X.509 certificate chain PEM file.
|
||||
*
|
||||
* @param chain
|
||||
* {@link X509Certificate[]} to write
|
||||
* @param w
|
||||
* {@link Writer} to write the PEM file to. The {@link Writer} is closed
|
||||
* after use.
|
||||
* @deprecated Use
|
||||
* {@link #writeX509CertificateChain(Writer, X509Certificate, X509Certificate...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void writeX509CertificateChain(X509Certificate[] chain, Writer w) throws IOException {
|
||||
writeX509CertificateChain(w, null, chain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a CSR PEM file.
|
||||
*
|
||||
|
|
|
@ -20,12 +20,9 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.KeyPair;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CertificateParsingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
|
@ -37,90 +34,13 @@ import java.util.Set;
|
|||
|
||||
import org.bouncycastle.asn1.x509.GeneralName;
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.jcabi.matchers.RegexMatchers;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link CertificateUtils}.
|
||||
*/
|
||||
public class CertificateUtilsTest {
|
||||
|
||||
private CertificateFactory certificateFactory;
|
||||
|
||||
@Before
|
||||
public void setup() throws CertificateException {
|
||||
certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if {@link CertificateUtils#readX509Certificate(InputStream)} reads and
|
||||
* {@link CertificateUtils#writeX509Certificate(X509Certificate, java.io.Writer)}
|
||||
* writes a proper X.509 certificate.
|
||||
*/
|
||||
@Test
|
||||
public void testReadWriteX509Certificate() throws IOException, CertificateException {
|
||||
// Read a demonstration certificate
|
||||
X509Certificate original = createCertificate();
|
||||
|
||||
// Write to Byte Array
|
||||
byte[] pem;
|
||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
CertificateUtils.writeX509Certificate(original, out);
|
||||
pem = out.toByteArray();
|
||||
}
|
||||
|
||||
// Make sure it is a good PEM file
|
||||
assertThat(new String(pem, "utf-8"), RegexMatchers.matchesPattern(
|
||||
"-----BEGIN CERTIFICATE-----[\\r\\n]+"
|
||||
+ "([a-zA-Z0-9/+=]+[\\r\\n]+)+"
|
||||
+ "-----END CERTIFICATE-----[\\r\\n]*"));
|
||||
|
||||
// Read it back in
|
||||
X509Certificate written = CertificateUtils.readX509Certificate(new ByteArrayInputStream(pem));
|
||||
|
||||
// Verify that both certificates are the same
|
||||
assertThat(original.getEncoded(), is(equalTo(written.getEncoded())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if
|
||||
* {@link CertificateUtils#writeX509CertificateChain(java.io.Writer, X509Certificate, X509Certificate...)}
|
||||
* writes a correct chain.
|
||||
*/
|
||||
@Test
|
||||
public void testWriteX509CertificateChain() throws IOException, CertificateException {
|
||||
X509Certificate leaf = createCertificate();
|
||||
X509Certificate chain1 = createCertificate();
|
||||
X509Certificate chain2 = createCertificate();
|
||||
|
||||
String out;
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(1));
|
||||
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf, chain1);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(2));
|
||||
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf, chain1, chain2);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(3));
|
||||
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf, chain1, null, chain2);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if {@link CertificateUtils#createTlsSni02Certificate(KeyPair, String, String)}
|
||||
* creates a good certificate.
|
||||
|
@ -169,18 +89,6 @@ public class CertificateUtilsTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a test certificates.
|
||||
*/
|
||||
private X509Certificate createCertificate() throws IOException, CertificateException {
|
||||
X509Certificate original;
|
||||
try (InputStream cert = getClass().getResourceAsStream("/cert.pem")) {
|
||||
original = (X509Certificate) certificateFactory.generateCertificate(cert);
|
||||
}
|
||||
assertThat(original, is(notNullValue()));
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that constructor is private.
|
||||
*/
|
||||
|
@ -192,25 +100,6 @@ public class CertificateUtilsTest {
|
|||
constructor.newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts number of certificates in a PEM string.
|
||||
*
|
||||
* @param str
|
||||
* String containing certificates in PEM format
|
||||
* @return Number of certificates found
|
||||
*/
|
||||
private int countCertificates(String str) {
|
||||
int count = 0;
|
||||
int pos = 0;
|
||||
while (true) {
|
||||
pos = str.indexOf("-----BEGIN CERTIFICATE-----", pos);
|
||||
if (pos < 0) break;
|
||||
count++;
|
||||
pos++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all DNSName SANs from a certificate.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue