1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.ldap.client.api;
21
22
23 import org.apache.directory.api.i18n.I18n;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import javax.net.ssl.TrustManager;
28 import javax.net.ssl.TrustManagerFactory;
29 import javax.net.ssl.X509TrustManager;
30
31 import java.io.FileInputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.Serializable;
35 import java.security.KeyStore;
36 import java.security.KeyStoreException;
37 import java.security.NoSuchAlgorithmException;
38 import java.security.cert.CertificateException;
39 import java.security.cert.X509Certificate;
40 import java.util.ArrayList;
41 import java.util.Date;
42 import java.util.List;
43
44
45
46
47
48
49
50
51
52
53
54 public final class LdapClientTrustStoreManager implements X509TrustManager, Serializable
55 {
56
57 private static final long serialVersionUID = 1L;
58
59
60 private static final String CLS_NM = LdapClientTrustStoreManager.class.getName();
61 private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
62
63
64 private boolean isExamineValidityDates;
65 private char[] trustStorePw;
66
67
68 private String trustStoreFile;
69 private String trustStoreFormat;
70
71 private X509TrustManager[] x509TrustManagers;
72
73
74
75
76
77
78
79
80
81
82 public LdapClientTrustStoreManager( String trustStoreFile, char[] trustStorePw,
83 String trustStoreFormat, boolean isExamineValidity )
84 {
85 if ( trustStoreFile == null )
86 {
87
88 throw new RuntimeException( I18n.err( I18n.ERR_04174_INPUT_FILE_NAME_NULL ) );
89 }
90
91
92 this.trustStoreFile = trustStoreFile;
93
94
95 this.trustStorePw = trustStorePw.clone();
96
97
98 this.isExamineValidityDates = isExamineValidity;
99
100 if ( trustStoreFormat == null )
101 {
102 this.trustStoreFormat = KeyStore.getDefaultType();
103 }
104 else
105 {
106 this.trustStoreFormat = trustStoreFormat;
107 }
108 }
109
110
111
112
113
114
115
116
117
118 public synchronized void checkClientTrusted( X509Certificate[] x509Chain, String authNType ) throws CertificateException
119 {
120
121 for ( X509TrustManager trustMgr : getTrustManagers( x509Chain ) )
122 {
123 trustMgr.checkClientTrusted( x509Chain, authNType );
124 }
125 }
126
127
128
129
130
131
132
133
134
135 public synchronized void checkServerTrusted( X509Certificate[] x509Chain, String authNType ) throws
136 CertificateException
137 {
138 for ( X509TrustManager trustManager : getTrustManagers( x509Chain ) )
139 {
140 trustManager.checkServerTrusted( x509Chain, authNType );
141 }
142 }
143
144
145
146
147
148
149
150 public synchronized X509Certificate[] getAcceptedIssuers()
151 {
152 List<X509Certificate> certificates = new ArrayList<>();
153
154 for ( X509TrustManager trustManager : x509TrustManagers )
155 {
156 for ( X509Certificate certificate : trustManager.getAcceptedIssuers() )
157 {
158 certificates.add( certificate );
159 }
160 }
161
162 return certificates.toArray( new X509Certificate[]{} );
163 }
164
165
166
167
168
169
170
171
172
173 private synchronized X509TrustManager[] getTrustManagers( X509Certificate[] x509Chain ) throws
174 CertificateException
175 {
176 if ( LOG.isInfoEnabled() )
177 {
178 LOG.info( I18n.msg( I18n.MSG_04176_TRUST_MANAGER_ON_CLASSPATH, CLS_NM ) );
179 }
180
181 return getTrustManagersOnClasspath( x509Chain );
182 }
183
184
185
186
187
188
189
190
191
192 private synchronized X509TrustManager[] getTrustManagersOnClasspath( X509Certificate[] x509Chain ) throws
193 CertificateException
194 {
195
196 if ( isExamineValidityDates )
197 {
198 Date currentDate = new Date();
199
200 for ( X509Certificate x509Cert : x509Chain )
201 {
202 x509Cert.checkValidity( currentDate );
203 }
204 }
205
206 InputStream trustStoreInputStream;
207
208 if ( trustStoreFile != null )
209 {
210 try
211 {
212 trustStoreInputStream = new FileInputStream( trustStoreFile );
213 }
214 catch ( IOException ioe )
215 {
216 throw new CertificateException( I18n.err( I18n.ERR_04175_TRUST_STORE_FILE_NULL ) );
217 }
218 }
219 else
220 {
221 trustStoreInputStream = getTrustStoreInputStream();
222 }
223
224 if ( trustStoreInputStream == null )
225 {
226 throw new CertificateException( I18n.err( I18n.ERR_04176_TRUST_MANAGER_NOT_FOUND ) );
227 }
228 try
229 {
230 trustStoreInputStream.close();
231 }
232 catch ( IOException e )
233 {
234
235 LOG.warn( I18n.msg( I18n.MSG_04175_TRUST_MANAGER_IO_EXCEPTION, e.getMessage() ) );
236 }
237
238 return loadTrustManagers( getTrustStore() );
239 }
240
241
242
243
244
245
246
247
248
249 private X509TrustManager[] loadTrustManagers( KeyStore trustStore ) throws CertificateException
250 {
251 try
252 {
253 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory
254 .getDefaultAlgorithm() );
255 trustManagerFactory.init( trustStore );
256 TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
257 x509TrustManagers = new X509TrustManager[trustManagers.length];
258
259 for ( int i = 0; i < trustManagers.length; i++ )
260 {
261 x509TrustManagers[i] = ( X509TrustManager ) trustManagers[i];
262 }
263 }
264 catch ( NoSuchAlgorithmException e )
265 {
266 throw new CertificateException( I18n.err( I18n.ERR_04177_NO_SUCH_ALGORITHM ), e );
267 }
268 catch ( KeyStoreException e )
269 {
270 throw new CertificateException( I18n.err( I18n.ERR_04178_CANT_LOAD_KEY_STORE ), e );
271 }
272
273 return x509TrustManagers;
274 }
275
276
277
278
279
280
281
282
283 private KeyStore getTrustStore() throws CertificateException
284 {
285 KeyStore trustStore;
286
287 try
288 {
289 trustStore = KeyStore.getInstance( trustStoreFormat );
290 }
291 catch ( KeyStoreException e )
292 {
293 throw new CertificateException( I18n.err( I18n.ERR_04178_CANT_LOAD_KEY_STORE ), e );
294 }
295
296 InputStream trustStoreInputStream = null;
297
298 try
299 {
300 if ( trustStoreFile != null )
301 {
302 trustStoreInputStream = new FileInputStream( trustStoreFile );
303 }
304 else
305 {
306 trustStoreInputStream = getTrustStoreInputStream();
307 }
308
309 trustStore.load( trustStoreInputStream, trustStorePw );
310 }
311 catch ( NoSuchAlgorithmException e )
312 {
313 throw new CertificateException( I18n.err( I18n.ERR_04177_NO_SUCH_ALGORITHM ), e );
314 }
315 catch ( IOException e )
316 {
317 throw new CertificateException( I18n.err( I18n.ERR_04178_CANT_LOAD_KEY_STORE ), e );
318 }
319 finally
320 {
321
322 if ( trustStoreInputStream != null )
323 {
324 try
325 {
326 trustStoreInputStream.close();
327 }
328 catch ( IOException e )
329 {
330
331 LOG.warn( I18n.err( I18n.ERR_04179_TRUST_STORE_CANT_BE_READ, e.getMessage() ) );
332 }
333 }
334 }
335
336 return trustStore;
337 }
338
339
340
341
342
343
344
345
346 private InputStream getTrustStoreInputStream() throws CertificateException
347 {
348 ClassLoader classloader = Thread.currentThread().getContextClassLoader();
349 InputStream result = classloader.getResourceAsStream( trustStoreFile );
350
351 if ( null == result )
352 {
353 throw new CertificateException( I18n.err( I18n.ERR_04180_FILE_DOES_NOT_EXIST_ON_CLASSPATH ) );
354 }
355
356 return result;
357 }
358 }