1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.net.util;
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.net.Socket;
25 import java.security.GeneralSecurityException;
26 import java.security.KeyStore;
27 import java.security.KeyStoreException;
28 import java.security.Principal;
29 import java.security.PrivateKey;
30 import java.security.cert.Certificate;
31 import java.security.cert.X509Certificate;
32 import java.util.Enumeration;
33
34 import javax.net.ssl.KeyManager;
35 import javax.net.ssl.X509ExtendedKeyManager;
36
37 import org.apache.commons.net.io.Util;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public final class KeyManagerUtils {
66
67 private static final String DEFAULT_STORE_TYPE = KeyStore.getDefaultType();
68
69 private KeyManagerUtils(){
70
71 }
72
73
74
75
76
77
78
79
80
81
82 public static KeyManager createClientKeyManager(KeyStore ks, String keyAlias, String keyPass)
83 throws GeneralSecurityException
84 {
85 ClientKeyStore cks = new ClientKeyStore(ks, keyAlias != null ? keyAlias : findAlias(ks), keyPass);
86 return new X509KeyManager(cks);
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100 public static KeyManager createClientKeyManager(String storeType, File storePath, String storePass, String keyAlias, String keyPass)
101 throws IOException, GeneralSecurityException
102 {
103 KeyStore ks = loadStore(storeType, storePath, storePass);
104 return createClientKeyManager(ks, keyAlias, keyPass);
105 }
106
107
108
109
110
111
112
113
114
115
116
117 public static KeyManager createClientKeyManager(File storePath, String storePass, String keyAlias)
118 throws IOException, GeneralSecurityException
119 {
120 return createClientKeyManager(DEFAULT_STORE_TYPE, storePath, storePass, keyAlias, storePass);
121 }
122
123
124
125
126
127
128
129
130
131
132
133 public static KeyManager createClientKeyManager(File storePath, String storePass)
134 throws IOException, GeneralSecurityException
135 {
136 return createClientKeyManager(DEFAULT_STORE_TYPE, storePath, storePass, null, storePass);
137 }
138
139 private static KeyStore loadStore(String storeType, File storePath, String storePass)
140 throws KeyStoreException, IOException, GeneralSecurityException {
141 KeyStore ks = KeyStore.getInstance(storeType);
142 FileInputStream stream = null;
143 try {
144 stream = new FileInputStream(storePath);
145 ks.load(stream, storePass.toCharArray());
146 } finally {
147 Util.closeQuietly(stream);
148 }
149 return ks;
150 }
151
152 private static String findAlias(KeyStore ks) throws KeyStoreException {
153 Enumeration<String> e = ks.aliases();
154 while(e.hasMoreElements()) {
155 String entry = e.nextElement();
156 if (ks.isKeyEntry(entry)) {
157 return entry;
158 }
159 }
160 throw new KeyStoreException("Cannot find a private key entry");
161 }
162
163 private static class ClientKeyStore {
164
165 private final X509Certificate[] certChain;
166 private final PrivateKey key;
167 private final String keyAlias;
168
169 ClientKeyStore(KeyStore ks, String keyAlias, String keyPass) throws GeneralSecurityException
170 {
171 this.keyAlias = keyAlias;
172 this.key = (PrivateKey) ks.getKey(this.keyAlias, keyPass.toCharArray());
173 Certificate[] certs = ks.getCertificateChain(this.keyAlias);
174 X509Certificate[] X509certs = new X509Certificate[certs.length];
175 for (int i=0; i < certs.length; i++) {
176 X509certs[i] = (X509Certificate) certs[i];
177 }
178 this.certChain = X509certs;
179 }
180
181 final X509Certificate[] getCertificateChain() {
182 return this.certChain;
183 }
184
185 final PrivateKey getPrivateKey() {
186 return this.key;
187 }
188
189 final String getAlias() {
190 return this.keyAlias;
191 }
192 }
193
194 private static class X509KeyManager extends X509ExtendedKeyManager {
195
196 private final ClientKeyStore keyStore;
197
198 X509KeyManager(final ClientKeyStore keyStore) {
199 this.keyStore = keyStore;
200 }
201
202
203
204 public String chooseClientAlias(String[] keyType, Principal[] issuers,
205 Socket socket) {
206 return keyStore.getAlias();
207 }
208
209
210
211 public X509Certificate[] getCertificateChain(String alias) {
212 return keyStore.getCertificateChain();
213 }
214
215
216 public String[] getClientAliases(String keyType, Principal[] issuers) {
217 return new String[]{ keyStore.getAlias()};
218 }
219
220
221
222 public PrivateKey getPrivateKey(String alias) {
223 return keyStore.getPrivateKey();
224 }
225
226
227 public String[] getServerAliases(String keyType, Principal[] issuers) {
228 return null;
229 }
230
231
232 public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
233 return null;
234 }
235
236 }
237
238 }