1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.crypto.ssl;
21
22 import org.joda.time.DateTime;
23 import org.waarp.common.exception.CryptoException;
24 import org.waarp.common.file.FileUtils;
25 import org.waarp.common.logging.WaarpLogger;
26 import org.waarp.common.logging.WaarpLoggerFactory;
27
28 import javax.net.ssl.KeyManagerFactory;
29 import javax.net.ssl.TrustManagerFactory;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileNotFoundException;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.security.Key;
36 import java.security.KeyStore;
37 import java.security.KeyStoreException;
38 import java.security.NoSuchAlgorithmException;
39 import java.security.UnrecoverableKeyException;
40 import java.security.cert.Certificate;
41 import java.security.cert.CertificateException;
42 import java.security.cert.CertificateFactory;
43 import java.security.cert.X509Certificate;
44 import java.util.Date;
45 import java.util.Enumeration;
46
47 import static org.waarp.common.digest.WaarpBC.*;
48
49
50
51
52 public class WaarpSecureKeyStore {
53 private static final String CANNOT_SAVE_TO_FILE_KEY_STORE_INSTANCE =
54 "Cannot save to file KeyStore Instance";
55
56 private static final String CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE =
57 "Cannot create KeyManagerFactory Instance";
58
59 private static final String CANNOT_CREATE_KEY_STORE_INSTANCE =
60 "Cannot create KeyStore Instance";
61
62
63
64
65 private static final WaarpLogger logger =
66 WaarpLoggerFactory.getLogger(WaarpSecureKeyStore.class);
67 private static final String CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE =
68 "Cannot create TrustManagerFactory Instance";
69 private static final String CANNOT_CREATE_KEY_TRUST_STORE_INSTANCE =
70 "Cannot create keyTrustStore Instance";
71 private static final String CANNOT_SAVE_TO_FILE_KEY_TRUST_STORE_INSTANCE =
72 "Cannot save to file keyTrustStore Instance";
73
74 static {
75 initializedTlsContext();
76 }
77
78 private String keyStoreFilename;
79 private KeyStore keyStore;
80 private KeyManagerFactory keyManagerFactory;
81 private String keyStorePasswd;
82 private String keyPassword;
83 private WaarpSecureTrustManagerFactory secureTrustManagerFactory;
84 private KeyStore keyTrustStore;
85 private String trustStorePasswd;
86
87
88
89
90
91
92
93
94
95 public WaarpSecureKeyStore(final String keyStorePasswd,
96 final String keyPassword) throws CryptoException {
97 this.keyStorePasswd = keyStorePasswd;
98 this.keyPassword = keyPassword;
99 try {
100 keyStore = KeyStore.getInstance("JKS");
101 } catch (final KeyStoreException e) {
102 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
103 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
104 }
105 try {
106
107 keyStore.load(null, getKeyStorePassword());
108 } catch (final NoSuchAlgorithmException e) {
109 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
110 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
111 } catch (final CertificateException e) {
112 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
113 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
114 } catch (final FileNotFoundException e) {
115 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
116 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
117 } catch (final IOException e) {
118 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
119 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
120 }
121 initKeyManagerFactory();
122 }
123
124
125
126
127
128
129
130
131
132
133 public WaarpSecureKeyStore(final String keyStoreFilename,
134 final String keyStorePasswd,
135 final String keyPassword) throws CryptoException {
136 initKeyStore(keyStoreFilename, keyStorePasswd, keyPassword);
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 public WaarpSecureKeyStore(final String keyStoreFilename,
155 final String keyStorePasswd,
156 final String keyPassword,
157 final String trustStoreFilename,
158 final String trustStorePasswd,
159 final boolean needClientAuthent)
160 throws CryptoException {
161
162 initKeyStore(keyStoreFilename, keyStorePasswd, keyPassword);
163
164 if (trustStoreFilename != null) {
165 initTrustStore(trustStoreFilename, trustStorePasswd, needClientAuthent);
166 } else {
167 initEmptyTrustStore();
168 }
169 }
170
171
172
173
174
175
176
177
178
179
180 public final void initKeyStore(final String keystoreFilename,
181 final String keystorePasswd,
182 final String keyPasswordNew)
183 throws CryptoException {
184 keyStoreFilename = keystoreFilename;
185 keyStorePasswd = keystorePasswd;
186 keyPassword = keyPasswordNew;
187
188 try {
189 keyStore = KeyStore.getInstance("JKS");
190 } catch (final KeyStoreException e) {
191 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
192 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
193 }
194 FileInputStream inputStream = null;
195 try {
196 final File temp = new File(keystoreFilename).getAbsoluteFile();
197 inputStream = new FileInputStream(temp);
198 keyStore.load(inputStream, getKeyStorePassword());
199 } catch (final NoSuchAlgorithmException e) {
200 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
201 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
202 } catch (final CertificateException e) {
203 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
204 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
205 } catch (final FileNotFoundException e) {
206 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
207 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
208 } catch (final IOException e) {
209 logger.error(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
210 throw new CryptoException(CANNOT_CREATE_KEY_STORE_INSTANCE, e);
211 } finally {
212 FileUtils.close(inputStream);
213 }
214 checkExpiryDate(keyStore);
215 initKeyManagerFactory();
216 }
217
218
219
220
221
222
223 final void initKeyManagerFactory() throws CryptoException {
224 try {
225 keyManagerFactory = KeyManagerFactory.getInstance(
226 KeyManagerFactory.getDefaultAlgorithm());
227 } catch (final NoSuchAlgorithmException e) {
228 logger.error(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
229 throw new CryptoException(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
230 }
231 try {
232 keyManagerFactory.init(keyStore, getCertificatePassword());
233 } catch (final UnrecoverableKeyException e) {
234 logger.error(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
235 throw new CryptoException(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
236 } catch (final KeyStoreException e) {
237 logger.error(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
238 throw new CryptoException(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
239 } catch (final NoSuchAlgorithmException e) {
240 logger.error(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
241 throw new CryptoException(CANNOT_CREATE_KEY_MANAGER_FACTORY_INSTANCE, e);
242 }
243 }
244
245
246
247
248
249
250
251
252 public final boolean deleteKeyFromKeyStore(final String alias) {
253 try {
254 keyStore.deleteEntry(alias);
255 } catch (final KeyStoreException e) {
256 logger.error("Cannot delete Key from KeyStore Instance", e);
257 return false;
258 }
259 return true;
260 }
261
262
263
264
265
266
267
268
269
270
271 public final boolean setKeytoKeyStore(final String alias, final Key key,
272 final Certificate[] chain) {
273 try {
274 keyStore.setKeyEntry(alias, key, getCertificatePassword(), chain);
275 } catch (final KeyStoreException e) {
276 logger.error("Cannot add Key and Certificates to KeyStore Instance", e);
277 return false;
278 }
279 return true;
280 }
281
282
283
284
285
286
287
288
289 public final boolean saveKeyStore(final String filename) {
290 FileOutputStream fos = null;
291 try {
292 fos = new FileOutputStream(filename);
293 try {
294 keyStore.store(fos, getKeyStorePassword());
295 } catch (final KeyStoreException e) {
296 logger.error(CANNOT_SAVE_TO_FILE_KEY_STORE_INSTANCE, e);
297 return false;
298 } catch (final NoSuchAlgorithmException e) {
299 logger.error(CANNOT_SAVE_TO_FILE_KEY_STORE_INSTANCE, e);
300 return false;
301 } catch (final CertificateException e) {
302 logger.error(CANNOT_SAVE_TO_FILE_KEY_STORE_INSTANCE, e);
303 return false;
304 } catch (final IOException e) {
305 logger.error(CANNOT_SAVE_TO_FILE_KEY_STORE_INSTANCE, e);
306 return false;
307 }
308 } catch (final FileNotFoundException e) {
309 logger.error(CANNOT_SAVE_TO_FILE_KEY_STORE_INSTANCE, e);
310 return false;
311 } finally {
312 FileUtils.close(fos);
313 }
314 return true;
315 }
316
317
318
319
320
321
322
323
324
325
326
327
328 public final void initTrustStore(final String truststoreFilename,
329 final String truststorePasswd,
330 final boolean needClientAuthent)
331 throws CryptoException {
332 trustStorePasswd = truststorePasswd;
333 try {
334 keyTrustStore = KeyStore.getInstance("JKS");
335 } catch (final KeyStoreException e) {
336 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e);
337 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
338 e);
339 }
340 FileInputStream inputStream = null;
341 try {
342 final File temp = new File(truststoreFilename).getAbsoluteFile();
343 inputStream = new FileInputStream(temp);
344 keyTrustStore.load(inputStream, getKeyTrustStorePassword());
345 } catch (final NoSuchAlgorithmException e) {
346 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e);
347 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
348 e);
349 } catch (final CertificateException e) {
350 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e);
351 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
352 e);
353 } catch (final FileNotFoundException e) {
354 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e);
355 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
356 e);
357 } catch (final IOException e) {
358 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e);
359 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
360 e);
361 } finally {
362 FileUtils.close(inputStream);
363 }
364 checkExpiryDate(keyTrustStore);
365 final TrustManagerFactory trustManagerFactory;
366 try {
367 trustManagerFactory = TrustManagerFactory.getInstance(
368 KeyManagerFactory.getDefaultAlgorithm());
369 } catch (final NoSuchAlgorithmException e1) {
370 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e1);
371 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
372 e1);
373 }
374 try {
375 trustManagerFactory.init(keyTrustStore);
376 } catch (final KeyStoreException e1) {
377 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e1);
378 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
379 e1);
380 }
381 try {
382 secureTrustManagerFactory =
383 new WaarpSecureTrustManagerFactory(trustManagerFactory,
384 needClientAuthent);
385 } catch (final CryptoException e) {
386 logger.error(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE, e);
387 throw new CryptoException(CANNOT_CREATE_TRUST_MANAGER_FACTORY_INSTANCE,
388 e);
389 }
390 }
391
392
393
394
395
396
397 public final boolean initEmptyTrustStore() {
398 trustStorePasswd = "secret";
399 try {
400 keyTrustStore = KeyStore.getInstance("JKS");
401 } catch (final KeyStoreException e) {
402 logger.error(CANNOT_CREATE_KEY_TRUST_STORE_INSTANCE, e);
403 return false;
404 }
405 try {
406
407 keyTrustStore.load(null, getKeyTrustStorePassword());
408 } catch (final NoSuchAlgorithmException e) {
409 logger.error(CANNOT_CREATE_KEY_TRUST_STORE_INSTANCE, e);
410 return false;
411 } catch (final CertificateException e) {
412 logger.error(CANNOT_CREATE_KEY_TRUST_STORE_INSTANCE, e);
413 return false;
414 } catch (final FileNotFoundException e) {
415 logger.error(CANNOT_CREATE_KEY_TRUST_STORE_INSTANCE, e);
416 return false;
417 } catch (final IOException e) {
418 logger.error(CANNOT_CREATE_KEY_TRUST_STORE_INSTANCE, e);
419 return false;
420 }
421 secureTrustManagerFactory = new WaarpSecureTrustManagerFactory();
422 return true;
423 }
424
425
426
427
428
429
430
431
432 public final boolean deleteKeyFromTrustStore(final String alias) {
433 try {
434 keyStore.deleteEntry(alias);
435 } catch (final KeyStoreException e) {
436 logger.error("Cannot delete Key from keyTrustStore Instance", e);
437 return false;
438 }
439 return true;
440 }
441
442
443
444
445
446
447
448
449
450 public final boolean setKeytoTrustStore(final String alias,
451 final Certificate cert) {
452 try {
453 keyStore.setCertificateEntry(alias, cert);
454 } catch (final KeyStoreException e) {
455 logger.error("Cannot add Certificate to keyTrustStore Instance", e);
456 return false;
457 }
458 return true;
459 }
460
461
462
463
464
465
466
467
468 public final boolean saveTrustStore(final String filename) {
469 FileOutputStream fos = null;
470 try {
471 fos = new FileOutputStream(filename);
472 try {
473 keyTrustStore.store(fos, getKeyTrustStorePassword());
474 } catch (final KeyStoreException e) {
475 logger.error(CANNOT_SAVE_TO_FILE_KEY_TRUST_STORE_INSTANCE, e);
476 return false;
477 } catch (final NoSuchAlgorithmException e) {
478 logger.error(CANNOT_SAVE_TO_FILE_KEY_TRUST_STORE_INSTANCE, e);
479 return false;
480 } catch (final CertificateException e) {
481 logger.error(CANNOT_SAVE_TO_FILE_KEY_TRUST_STORE_INSTANCE, e);
482 return false;
483 } catch (final IOException e) {
484 logger.error(CANNOT_SAVE_TO_FILE_KEY_TRUST_STORE_INSTANCE, e);
485 return false;
486 }
487 } catch (final FileNotFoundException e) {
488 logger.error(CANNOT_SAVE_TO_FILE_KEY_TRUST_STORE_INSTANCE, e);
489 return false;
490 } finally {
491 FileUtils.close(fos);
492 }
493 return true;
494 }
495
496
497
498
499
500
501
502
503
504
505
506 public static Certificate loadX509Certificate(final String filename)
507 throws CertificateException, FileNotFoundException {
508 final CertificateFactory cf = CertificateFactory.getInstance("X.509");
509 final FileInputStream in = new FileInputStream(filename);
510 try {
511 return cf.generateCertificate(in);
512 } finally {
513 FileUtils.close(in);
514 }
515 }
516
517
518
519
520 public final char[] getCertificatePassword() {
521 if (keyPassword != null) {
522 return keyPassword.toCharArray();
523 }
524 return "nopwd".toCharArray();
525 }
526
527
528
529
530 public final char[] getKeyStorePassword() {
531 if (keyStorePasswd != null) {
532 return keyStorePasswd.toCharArray();
533 }
534 return "nopwd".toCharArray();
535 }
536
537
538
539
540 public final char[] getKeyTrustStorePassword() {
541 if (trustStorePasswd != null) {
542 return trustStorePasswd.toCharArray();
543 }
544 return "nopwd".toCharArray();
545 }
546
547
548
549
550 public final String getKeyStoreFilename() {
551 return keyStoreFilename;
552 }
553
554
555
556
557 public final WaarpSecureTrustManagerFactory getSecureTrustManagerFactory() {
558 return secureTrustManagerFactory;
559 }
560
561
562
563
564 public final KeyManagerFactory getKeyManagerFactory() {
565 return keyManagerFactory;
566 }
567
568
569
570
571 public final KeyStore getKeyStore() {
572 return keyStore;
573 }
574
575
576
577
578 public final KeyStore getKeyTrustStore() {
579 return keyTrustStore;
580 }
581
582
583
584
585
586
587 public static boolean checkExpiryDate(final KeyStore keystore) {
588 final Enumeration<String> aliases;
589 try {
590 aliases = keystore.aliases();
591 } catch (final KeyStoreException e) {
592 logger.warn("Cannot get Aliases: {}", e.getMessage());
593 return true;
594 }
595 Date expiryDate;
596 boolean valid = true;
597 for (; aliases.hasMoreElements(); ) {
598 final String alias = aliases.nextElement();
599 try {
600 expiryDate =
601 ((X509Certificate) keystore.getCertificate(alias)).getNotAfter();
602 final DateTime dateTime = new DateTime(expiryDate);
603 if (dateTime.isBeforeNow()) {
604 logger.error("Certificate {} has an expiry date before today: {}",
605 alias, dateTime);
606 valid = false;
607 } else {
608 logger.debug("Certificate {} has an expiry date over today: {}",
609 alias, dateTime);
610 }
611 } catch (final KeyStoreException e) {
612 logger.warn("Cannot get Expiry Date: {}", e.getMessage());
613 }
614 }
615 return valid;
616 }
617 }