2
2
3
3
import java .io .BufferedReader ;
4
4
import java .io .File ;
5
- import java .io .FileReader ;
6
5
import java .io .IOException ;
6
+ import java .io .Reader ;
7
+ import java .io .StringReader ;
7
8
import java .security .KeyFactory ;
8
- import java .security .KeyPair ;
9
9
import java .security .KeyStore ;
10
10
import java .security .KeyStoreException ;
11
11
import java .security .NoSuchAlgorithmException ;
12
12
import java .security .PrivateKey ;
13
- import java .security .PublicKey ;
14
13
import java .security .cert .Certificate ;
15
14
import java .security .cert .CertificateException ;
16
15
import java .security .spec .InvalidKeySpecException ;
17
16
import java .security .spec .PKCS8EncodedKeySpec ;
18
- import java .security .spec .X509EncodedKeySpec ;
19
17
import java .util .ArrayList ;
20
18
import java .util .List ;
21
19
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 ;
23
23
import org .bouncycastle .cert .X509CertificateHolder ;
24
24
import org .bouncycastle .cert .jcajce .JcaX509CertificateConverter ;
25
25
import org .bouncycastle .openssl .PEMKeyPair ;
26
26
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 ;
27
33
28
34
public class CertificateUtils {
35
+ private static final Logger LOG = LoggerFactory .getLogger (CertificateUtils .class );
36
+
29
37
private CertificateUtils () {
30
38
// utility class
31
39
}
@@ -41,115 +49,157 @@ public static boolean verifyCertificatesExist(String dockerCertPath) {
41
49
return result ;
42
50
}
43
51
52
+ /**
53
+ * @param dockerCertPath with standard named files.
54
+ */
44
55
public static KeyStore createKeyStore (final String dockerCertPath ) throws NoSuchAlgorithmException ,
45
56
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 );
48
67
49
68
KeyStore keyStore = KeyStore .getInstance ("JKS" );
50
69
keyStore .load (null );
51
70
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
+
54
77
return keyStore ;
55
78
}
56
79
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 );
82
88
}
83
-
84
89
}
85
90
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 ,
87
95
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 )) {
93
97
List <Certificate > certificates = new ArrayList <>();
94
- pemParser = new PEMParser ( reader );
98
+
95
99
JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter ().setProvider ("BC" );
96
100
Object certObj = pemParser .readObject ();
97
101
98
- while (certObj != null ) {
102
+ if (certObj instanceof X509CertificateHolder ) {
99
103
X509CertificateHolder certificateHolder = (X509CertificateHolder ) certObj ;
100
104
certificates .add (certificateConverter .getCertificate (certificateHolder ));
101
-
102
- certObj = pemParser .readObject ();
103
105
}
104
106
105
107
return certificates ;
106
- } finally {
107
- if (pemParser != null ) {
108
- IOUtils .closeQuietly (pemParser );
109
- }
110
-
111
- if (reader != null ) {
112
- IOUtils .closeQuietly (reader );
113
- }
114
108
}
115
-
116
109
}
117
110
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 ));
122
111
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
+ }
124
144
125
- try {
126
- pemParser = new PEMParser ( reader );
145
+ return null ;
146
+ }
127
147
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 );
129
154
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
+ }
132
160
133
- KeyFactory factory = KeyFactory .getInstance ("RSA" );
161
+ return null ;
162
+ }
134
163
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
+ }
137
175
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
+ }
140
185
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 );
142
196
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 );
147
200
148
- if (reader != null ) {
149
- IOUtils .closeQuietly (reader );
150
- }
201
+ return trustStore ;
151
202
}
152
-
153
203
}
154
204
155
205
}
0 commit comments