Skip to content

Commit 4f11537

Browse files
author
Marcus Linke
committed
Merge branch 'refactorKeys' of https://github.com/KostyaSha/docker-java into KostyaSha-refactorKeys
2 parents 84cf070 + 9639cb7 commit 4f11537

File tree

1 file changed

+128
-78
lines changed

1 file changed

+128
-78
lines changed

src/main/java/com/github/dockerjava/core/util/CertificateUtils.java

Lines changed: 128 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,38 @@
22

33
import java.io.BufferedReader;
44
import java.io.File;
5-
import java.io.FileReader;
65
import java.io.IOException;
6+
import java.io.Reader;
7+
import java.io.StringReader;
78
import java.security.KeyFactory;
8-
import java.security.KeyPair;
99
import java.security.KeyStore;
1010
import java.security.KeyStoreException;
1111
import java.security.NoSuchAlgorithmException;
1212
import java.security.PrivateKey;
13-
import java.security.PublicKey;
1413
import java.security.cert.Certificate;
1514
import java.security.cert.CertificateException;
1615
import java.security.spec.InvalidKeySpecException;
1716
import java.security.spec.PKCS8EncodedKeySpec;
18-
import java.security.spec.X509EncodedKeySpec;
1917
import java.util.ArrayList;
2018
import java.util.List;
2119

22-
import org.apache.commons.io.IOUtils;
20+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
21+
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
22+
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
2323
import org.bouncycastle.cert.X509CertificateHolder;
2424
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
2525
import org.bouncycastle.openssl.PEMKeyPair;
2626
import org.bouncycastle.openssl.PEMParser;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
29+
30+
import javax.annotation.CheckForNull;
31+
32+
import static java.util.Objects.requireNonNull;
2733

2834
public class CertificateUtils {
35+
private static final Logger LOG = LoggerFactory.getLogger(CertificateUtils.class);
36+
2937
private CertificateUtils() {
3038
// utility class
3139
}
@@ -41,115 +49,157 @@ public static boolean verifyCertificatesExist(String dockerCertPath) {
4149
return result;
4250
}
4351

52+
/**
53+
* @param dockerCertPath with standard named files.
54+
*/
4455
public static KeyStore createKeyStore(final String dockerCertPath) throws NoSuchAlgorithmException,
4556
InvalidKeySpecException, IOException, CertificateException, KeyStoreException {
46-
KeyPair keyPair = loadPrivateKey(dockerCertPath);
47-
List<Certificate> privateCertificates = loadCertificates(dockerCertPath);
57+
return createKeyStore("key.pem", "cert.pem");
58+
}
59+
60+
61+
@SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
62+
public static KeyStore createKeyStore(final String keypem, final String certpem) throws NoSuchAlgorithmException,
63+
InvalidKeySpecException, IOException, CertificateException, KeyStoreException {
64+
PrivateKey privateKey = loadPrivateKey(keypem);
65+
requireNonNull(privateKey);
66+
List<Certificate> privateCertificates = loadCertificates(certpem);
4867

4968
KeyStore keyStore = KeyStore.getInstance("JKS");
5069
keyStore.load(null);
5170

52-
keyStore.setKeyEntry("docker", keyPair.getPrivate(), "docker".toCharArray(),
53-
privateCertificates.toArray(new Certificate[privateCertificates.size()]));
71+
keyStore.setKeyEntry("docker",
72+
privateKey,
73+
"docker".toCharArray(),
74+
privateCertificates.toArray(new Certificate[privateCertificates.size()])
75+
);
76+
5477
return keyStore;
5578
}
5679

57-
public static KeyStore createTrustStore(final String dockerCertPath) throws IOException, CertificateException,
58-
KeyStoreException, NoSuchAlgorithmException {
59-
File caPath = new File(dockerCertPath, "ca.pem");
60-
BufferedReader reader = new BufferedReader(new FileReader(caPath));
61-
PEMParser pemParser = null;
62-
63-
try {
64-
pemParser = new PEMParser(reader);
65-
X509CertificateHolder certificateHolder = (X509CertificateHolder) pemParser.readObject();
66-
Certificate caCertificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(
67-
certificateHolder);
68-
69-
KeyStore trustStore = KeyStore.getInstance("JKS");
70-
trustStore.load(null);
71-
trustStore.setCertificateEntry("ca", caCertificate);
72-
return trustStore;
73-
74-
} finally {
75-
if (pemParser != null) {
76-
IOUtils.closeQuietly(pemParser);
77-
}
78-
79-
if (reader != null) {
80-
IOUtils.closeQuietly(reader);
81-
}
80+
/**
81+
* from "cert.pem" String
82+
*/
83+
private static List<Certificate> loadCertificates(final String certpem) throws IOException,
84+
CertificateException {
85+
final StringReader certReader = new StringReader(certpem);
86+
try (BufferedReader reader = new BufferedReader(certReader)) {
87+
return loadCertificates(reader);
8288
}
83-
8489
}
8590

86-
private static List<Certificate> loadCertificates(final String dockerCertPath) throws IOException,
91+
/**
92+
* "cert.pem" from reader
93+
*/
94+
private static List<Certificate> loadCertificates(final Reader reader) throws IOException,
8795
CertificateException {
88-
File certificate = new File(dockerCertPath, "cert.pem");
89-
BufferedReader reader = new BufferedReader(new FileReader(certificate));
90-
PEMParser pemParser = null;
91-
92-
try {
96+
try (PEMParser pemParser = new PEMParser(reader)) {
9397
List<Certificate> certificates = new ArrayList<>();
94-
pemParser = new PEMParser(reader);
98+
9599
JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter().setProvider("BC");
96100
Object certObj = pemParser.readObject();
97101

98-
while (certObj != null) {
102+
if (certObj instanceof X509CertificateHolder) {
99103
X509CertificateHolder certificateHolder = (X509CertificateHolder) certObj;
100104
certificates.add(certificateConverter.getCertificate(certificateHolder));
101-
102-
certObj = pemParser.readObject();
103105
}
104106

105107
return certificates;
106-
} finally {
107-
if (pemParser != null) {
108-
IOUtils.closeQuietly(pemParser);
109-
}
110-
111-
if (reader != null) {
112-
IOUtils.closeQuietly(reader);
113-
}
114108
}
115-
116109
}
117110

118-
private static KeyPair loadPrivateKey(final String dockerCertPath) throws IOException, NoSuchAlgorithmException,
119-
InvalidKeySpecException {
120-
File certificate = new File(dockerCertPath, "key.pem");
121-
BufferedReader reader = new BufferedReader(new FileReader(certificate));
122111

123-
PEMParser pemParser = null;
112+
/**
113+
* Return private key ("key.pem") from Reader
114+
*/
115+
@CheckForNull
116+
private static PrivateKey loadPrivateKey(final Reader reader) throws IOException, NoSuchAlgorithmException,
117+
InvalidKeySpecException {
118+
try (PEMParser pemParser = new PEMParser(reader)) {
119+
Object readObject = pemParser.readObject();
120+
while (readObject != null) {
121+
if (readObject instanceof PEMKeyPair) {
122+
PEMKeyPair pemKeyPair = (PEMKeyPair) readObject;
123+
PrivateKey privateKey = guessKey(pemKeyPair.getPrivateKeyInfo().getEncoded());
124+
if (privateKey != null) {
125+
return privateKey;
126+
}
127+
} else if (readObject instanceof PrivateKeyInfo) {
128+
PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) readObject;
129+
PrivateKey privateKey = guessKey(privateKeyInfo.getEncoded());
130+
if (privateKey != null) {
131+
return privateKey;
132+
}
133+
} else if (readObject instanceof ASN1ObjectIdentifier) {
134+
// no idea how it can be used
135+
final ASN1ObjectIdentifier asn1ObjectIdentifier = (ASN1ObjectIdentifier) readObject;
136+
LOG.trace("Ignoring asn1ObjectIdentifier {}", asn1ObjectIdentifier);
137+
} else {
138+
LOG.warn("Unknown object '{}' from PEMParser", readObject);
139+
}
140+
141+
readObject = pemParser.readObject();
142+
}
143+
}
124144

125-
try {
126-
pemParser = new PEMParser(reader);
145+
return null;
146+
}
127147

128-
PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject();
148+
@CheckForNull
149+
private static PrivateKey guessKey(byte[] encodedKey) throws NoSuchAlgorithmException {
150+
//no way to know, so iterate
151+
for (String guessFactory : new String[]{"RSA", "ECDSA"}) {
152+
try {
153+
KeyFactory factory = KeyFactory.getInstance(guessFactory);
129154

130-
byte[] pemPrivateKeyEncoded = pemKeyPair.getPrivateKeyInfo().getEncoded();
131-
byte[] pemPublicKeyEncoded = pemKeyPair.getPublicKeyInfo().getEncoded();
155+
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
156+
return factory.generatePrivate(privateKeySpec);
157+
} catch (InvalidKeySpecException ignore) {
158+
}
159+
}
132160

133-
KeyFactory factory = KeyFactory.getInstance("RSA");
161+
return null;
162+
}
134163

135-
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(pemPublicKeyEncoded);
136-
PublicKey publicKey = factory.generatePublic(publicKeySpec);
164+
/**
165+
* Return KeyPair from "key.pem"
166+
*/
167+
@CheckForNull
168+
private static PrivateKey loadPrivateKey(final String keypem) throws IOException, NoSuchAlgorithmException,
169+
InvalidKeySpecException {
170+
try (StringReader certReader = new StringReader(keypem);
171+
BufferedReader reader = new BufferedReader(certReader)) {
172+
return loadPrivateKey(reader);
173+
}
174+
}
137175

138-
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pemPrivateKeyEncoded);
139-
PrivateKey privateKey = factory.generatePrivate(privateKeySpec);
176+
/**
177+
* "ca.pem" from String
178+
*/
179+
public static KeyStore createTrustStore(String capem) throws IOException, CertificateException,
180+
KeyStoreException, NoSuchAlgorithmException {
181+
try (Reader certReader = new StringReader(capem)) {
182+
return createTrustStore(certReader);
183+
}
184+
}
140185

141-
return new KeyPair(publicKey, privateKey);
186+
/**
187+
* "ca.pem" from Reader
188+
*/
189+
public static KeyStore createTrustStore(final Reader certReader) throws IOException, CertificateException,
190+
KeyStoreException, NoSuchAlgorithmException {
191+
try (PEMParser pemParser = new PEMParser(certReader)) {
192+
X509CertificateHolder certificateHolder = (X509CertificateHolder) pemParser.readObject();
193+
Certificate caCertificate = new JcaX509CertificateConverter()
194+
.setProvider("BC")
195+
.getCertificate(certificateHolder);
142196

143-
} finally {
144-
if (pemParser != null) {
145-
IOUtils.closeQuietly(pemParser);
146-
}
197+
KeyStore trustStore = KeyStore.getInstance("JKS");
198+
trustStore.load(null);
199+
trustStore.setCertificateEntry("ca", caCertificate);
147200

148-
if (reader != null) {
149-
IOUtils.closeQuietly(reader);
150-
}
201+
return trustStore;
151202
}
152-
153203
}
154204

155205
}

0 commit comments

Comments
 (0)