1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.util.ssl;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.IOException;
23 import java.net.InetAddress;
24 import java.net.InetSocketAddress;
25 import java.security.KeyStore;
26 import java.security.NoSuchAlgorithmException;
27 import java.security.SecureRandom;
28 import java.security.Security;
29 import java.security.cert.CRL;
30 import java.security.cert.CertStore;
31 import java.security.cert.Certificate;
32 import java.security.cert.CollectionCertStoreParameters;
33 import java.security.cert.PKIXBuilderParameters;
34 import java.security.cert.X509CertSelector;
35 import java.security.cert.X509Certificate;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Collection;
39 import java.util.Collections;
40 import java.util.Comparator;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.LinkedHashSet;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Set;
47 import java.util.function.Consumer;
48 import java.util.regex.Matcher;
49 import java.util.regex.Pattern;
50
51 import javax.net.ssl.CertPathTrustManagerParameters;
52 import javax.net.ssl.KeyManager;
53 import javax.net.ssl.KeyManagerFactory;
54 import javax.net.ssl.SNIHostName;
55 import javax.net.ssl.SNIMatcher;
56 import javax.net.ssl.SNIServerName;
57 import javax.net.ssl.SSLContext;
58 import javax.net.ssl.SSLEngine;
59 import javax.net.ssl.SSLParameters;
60 import javax.net.ssl.SSLPeerUnverifiedException;
61 import javax.net.ssl.SSLServerSocket;
62 import javax.net.ssl.SSLServerSocketFactory;
63 import javax.net.ssl.SSLSession;
64 import javax.net.ssl.SSLSessionContext;
65 import javax.net.ssl.SSLSocket;
66 import javax.net.ssl.SSLSocketFactory;
67 import javax.net.ssl.StandardConstants;
68 import javax.net.ssl.TrustManager;
69 import javax.net.ssl.TrustManagerFactory;
70 import javax.net.ssl.X509ExtendedKeyManager;
71 import javax.net.ssl.X509TrustManager;
72
73 import org.eclipse.jetty.util.StringUtil;
74 import org.eclipse.jetty.util.component.AbstractLifeCycle;
75 import org.eclipse.jetty.util.component.ContainerLifeCycle;
76 import org.eclipse.jetty.util.component.Dumpable;
77 import org.eclipse.jetty.util.log.Log;
78 import org.eclipse.jetty.util.log.Logger;
79 import org.eclipse.jetty.util.resource.Resource;
80 import org.eclipse.jetty.util.security.CertificateUtils;
81 import org.eclipse.jetty.util.security.CertificateValidator;
82 import org.eclipse.jetty.util.security.Password;
83
84
85
86
87
88
89
90 public class SslContextFactory extends AbstractLifeCycle implements Dumpable
91 {
92 public final static TrustManager[] TRUST_ALL_CERTS = new X509TrustManager[]{new X509TrustManager()
93 {
94 public java.security.cert.X509Certificate[] getAcceptedIssuers()
95 {
96 return new java.security.cert.X509Certificate[]{};
97 }
98
99 public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
100 {
101 }
102
103 public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
104 {
105 }
106 }};
107
108 private static final Logger LOG = Log.getLogger(SslContextFactory.class);
109
110 public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM =
111 (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ?
112 KeyManagerFactory.getDefaultAlgorithm() : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
113
114 public static final String DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM =
115 (Security.getProperty("ssl.TrustManagerFactory.algorithm") == null ?
116 TrustManagerFactory.getDefaultAlgorithm() : Security.getProperty("ssl.TrustManagerFactory.algorithm"));
117
118
119 public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword";
120
121
122 public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
123
124 private final Set<String> _excludeProtocols = new LinkedHashSet<>();
125 private final Set<String> _includeProtocols = new LinkedHashSet<>();
126 private final Set<String> _excludeCipherSuites = new LinkedHashSet<>();
127 private final List<String> _includeCipherSuites = new ArrayList<>();
128 private final Map<String, X509> _aliasX509 = new HashMap<>();
129 private final Map<String, X509> _certHosts = new HashMap<>();
130 private final Map<String, X509> _certWilds = new HashMap<>();
131 private String[] _selectedProtocols;
132 private boolean _useCipherSuitesOrder = true;
133 private Comparator<String> _cipherComparator;
134 private String[] _selectedCipherSuites;
135 private Resource _keyStoreResource;
136 private String _keyStoreProvider;
137 private String _keyStoreType = "JKS";
138 private String _certAlias;
139 private Resource _trustStoreResource;
140 private String _trustStoreProvider;
141 private String _trustStoreType = "JKS";
142 private boolean _needClientAuth = false;
143 private boolean _wantClientAuth = false;
144 private Password _keyStorePassword;
145 private Password _keyManagerPassword;
146 private Password _trustStorePassword;
147 private String _sslProvider;
148 private String _sslProtocol = "TLS";
149 private String _secureRandomAlgorithm;
150 private String _keyManagerFactoryAlgorithm = DEFAULT_KEYMANAGERFACTORY_ALGORITHM;
151 private String _trustManagerFactoryAlgorithm = DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM;
152 private boolean _validateCerts;
153 private boolean _validatePeerCerts;
154 private int _maxCertPathLength = -1;
155 private String _crlPath;
156 private boolean _enableCRLDP = false;
157 private boolean _enableOCSP = false;
158 private String _ocspResponderURL;
159 private KeyStore _setKeyStore;
160 private KeyStore _setTrustStore;
161 private boolean _sessionCachingEnabled = true;
162 private int _sslSessionCacheSize = -1;
163 private int _sslSessionTimeout = -1;
164 private SSLContext _setContext;
165 private String _endpointIdentificationAlgorithm = null;
166 private boolean _trustAll;
167 private boolean _renegotiationAllowed = true;
168 private Factory _factory;
169
170
171
172
173
174 public SslContextFactory()
175 {
176 this(false);
177 }
178
179
180
181
182
183
184
185
186 public SslContextFactory(boolean trustAll)
187 {
188 this(trustAll, null);
189 }
190
191
192
193
194
195
196 public SslContextFactory(String keyStorePath)
197 {
198 this(false, keyStorePath);
199 }
200
201 private SslContextFactory(boolean trustAll, String keyStorePath)
202 {
203 setTrustAll(trustAll);
204 addExcludeProtocols("SSL", "SSLv2", "SSLv2Hello", "SSLv3");
205 setExcludeCipherSuites("^.*_(MD5|SHA|SHA1)$");
206 if (keyStorePath != null)
207 setKeyStorePath(keyStorePath);
208 }
209
210
211
212
213 @Override
214 protected void doStart() throws Exception
215 {
216 super.doStart();
217 synchronized (this)
218 {
219 load();
220 }
221 }
222
223 private void load() throws Exception
224 {
225 SSLContext context = _setContext;
226 KeyStore keyStore = _setKeyStore;
227 KeyStore trustStore = _setTrustStore;
228
229 if (context == null)
230 {
231
232 if (keyStore == null && _keyStoreResource == null && trustStore == null && _trustStoreResource == null)
233 {
234 TrustManager[] trust_managers = null;
235
236 if (isTrustAll())
237 {
238 if (LOG.isDebugEnabled())
239 LOG.debug("No keystore or trust store configured. ACCEPTING UNTRUSTED CERTIFICATES!!!!!");
240
241 trust_managers = TRUST_ALL_CERTS;
242 }
243
244 String algorithm = getSecureRandomAlgorithm();
245 SecureRandom secureRandom = algorithm == null ? null : SecureRandom.getInstance(algorithm);
246 context = _sslProvider == null ? SSLContext.getInstance(_sslProtocol) : SSLContext.getInstance(_sslProtocol, _sslProvider);
247 context.init(null, trust_managers, secureRandom);
248 }
249 else
250 {
251 if (keyStore == null)
252 keyStore = loadKeyStore(_keyStoreResource);
253 if (trustStore == null)
254 trustStore = loadTrustStore(_trustStoreResource);
255
256 Collection<? extends CRL> crls = loadCRL(getCrlPath());
257
258
259 if (keyStore != null)
260 {
261 for (String alias : Collections.list(keyStore.aliases()))
262 {
263 Certificate certificate = keyStore.getCertificate(alias);
264 if (certificate != null && "X.509".equals(certificate.getType()))
265 {
266 X509Certificate x509C = (X509Certificate)certificate;
267
268
269 if (X509.isCertSign(x509C))
270 {
271 if (LOG.isDebugEnabled())
272 LOG.debug("Skipping " + x509C);
273 continue;
274 }
275 X509 x509 = new X509(alias, x509C);
276 _aliasX509.put(alias, x509);
277
278 if (isValidateCerts())
279 {
280 CertificateValidator validator = new CertificateValidator(trustStore, crls);
281 validator.setMaxCertPathLength(getMaxCertPathLength());
282 validator.setEnableCRLDP(isEnableCRLDP());
283 validator.setEnableOCSP(isEnableOCSP());
284 validator.setOcspResponderURL(getOcspResponderURL());
285 validator.validate(keyStore, x509C);
286 }
287
288 LOG.info("x509={} for {}", x509, this);
289
290 for (String h : x509.getHosts())
291 _certHosts.put(h, x509);
292 for (String w : x509.getWilds())
293 _certWilds.put(w, x509);
294 }
295 }
296 }
297
298
299 KeyManager[] keyManagers = getKeyManagers(keyStore);
300 TrustManager[] trustManagers = getTrustManagers(trustStore, crls);
301
302
303 SecureRandom secureRandom = (_secureRandomAlgorithm == null) ? null : SecureRandom.getInstance(_secureRandomAlgorithm);
304 context = _sslProvider == null ? SSLContext.getInstance(_sslProtocol) : SSLContext.getInstance(_sslProtocol, _sslProvider);
305 context.init(keyManagers, trustManagers, secureRandom);
306 }
307 }
308
309
310 SSLSessionContext serverContext = context.getServerSessionContext();
311 if (serverContext != null)
312 {
313 if (getSslSessionCacheSize() > -1)
314 serverContext.setSessionCacheSize(getSslSessionCacheSize());
315 if (getSslSessionTimeout() > -1)
316 serverContext.setSessionTimeout(getSslSessionTimeout());
317 }
318
319
320 SSLParameters enabled = context.getDefaultSSLParameters();
321 SSLParameters supported = context.getSupportedSSLParameters();
322 selectCipherSuites(enabled.getCipherSuites(), supported.getCipherSuites());
323 selectProtocols(enabled.getProtocols(), supported.getProtocols());
324
325 _factory = new Factory(keyStore, trustStore, context);
326 if (LOG.isDebugEnabled())
327 {
328 LOG.debug("Selected Protocols {} of {}", Arrays.asList(_selectedProtocols), Arrays.asList(supported.getProtocols()));
329 LOG.debug("Selected Ciphers {} of {}", Arrays.asList(_selectedCipherSuites), Arrays.asList(supported.getCipherSuites()));
330 }
331 }
332
333 @Override
334 public String dump()
335 {
336 return ContainerLifeCycle.dump(this);
337 }
338
339 @Override
340 public void dump(Appendable out, String indent) throws IOException
341 {
342 out.append(String.valueOf(this)).append(" trustAll=").append(Boolean.toString(_trustAll)).append(System.lineSeparator());
343
344 try
345 {
346
347
348
349
350 SSLEngine sslEngine = SSLContext.getDefault().createSSLEngine();
351
352 List<Object> selections = new ArrayList<>();
353
354
355 selections.add(new SslSelectionDump("Protocol",
356 sslEngine.getSupportedProtocols(),
357 sslEngine.getEnabledProtocols(),
358 getExcludeProtocols(),
359 getIncludeProtocols()));
360
361
362 selections.add(new SslSelectionDump("Cipher Suite",
363 sslEngine.getSupportedCipherSuites(),
364 sslEngine.getEnabledCipherSuites(),
365 getExcludeCipherSuites(),
366 getIncludeCipherSuites()));
367
368 ContainerLifeCycle.dump(out, indent, selections);
369 }
370 catch (NoSuchAlgorithmException ignore)
371 {
372 LOG.ignore(ignore);
373 }
374 }
375
376 @Override
377 protected void doStop() throws Exception
378 {
379 synchronized (this)
380 {
381 unload();
382 }
383 super.doStop();
384 }
385
386 private void unload()
387 {
388 _factory = null;
389 _selectedProtocols = null;
390 _selectedCipherSuites = null;
391 _aliasX509.clear();
392 _certHosts.clear();
393 _certWilds.clear();
394 }
395
396 public String[] getSelectedProtocols()
397 {
398 return Arrays.copyOf(_selectedProtocols, _selectedProtocols.length);
399 }
400
401 public String[] getSelectedCipherSuites()
402 {
403 return Arrays.copyOf(_selectedCipherSuites, _selectedCipherSuites.length);
404 }
405
406 public Comparator<String> getCipherComparator()
407 {
408 return _cipherComparator;
409 }
410
411 public void setCipherComparator(Comparator<String> cipherComparator)
412 {
413 if (cipherComparator != null)
414 setUseCipherSuitesOrder(true);
415 _cipherComparator = cipherComparator;
416 }
417
418 public Set<String> getAliases()
419 {
420 return Collections.unmodifiableSet(_aliasX509.keySet());
421 }
422
423 public X509 getX509(String alias)
424 {
425 return _aliasX509.get(alias);
426 }
427
428
429
430
431
432 public String[] getExcludeProtocols()
433 {
434 return _excludeProtocols.toArray(new String[0]);
435 }
436
437
438
439
440
441 public void setExcludeProtocols(String... protocols)
442 {
443 _excludeProtocols.clear();
444 _excludeProtocols.addAll(Arrays.asList(protocols));
445 }
446
447
448
449
450 public void addExcludeProtocols(String... protocol)
451 {
452 _excludeProtocols.addAll(Arrays.asList(protocol));
453 }
454
455
456
457
458
459 public String[] getIncludeProtocols()
460 {
461 return _includeProtocols.toArray(new String[0]);
462 }
463
464
465
466
467
468 public void setIncludeProtocols(String... protocols)
469 {
470 _includeProtocols.clear();
471 _includeProtocols.addAll(Arrays.asList(protocols));
472 }
473
474
475
476
477
478 public String[] getExcludeCipherSuites()
479 {
480 return _excludeCipherSuites.toArray(new String[0]);
481 }
482
483
484
485
486
487
488
489 public void setExcludeCipherSuites(String... cipherSuites)
490 {
491 _excludeCipherSuites.clear();
492 _excludeCipherSuites.addAll(Arrays.asList(cipherSuites));
493 }
494
495
496
497
498 public void addExcludeCipherSuites(String... cipher)
499 {
500 _excludeCipherSuites.addAll(Arrays.asList(cipher));
501 }
502
503
504
505
506
507 public String[] getIncludeCipherSuites()
508 {
509 return _includeCipherSuites.toArray(new String[0]);
510 }
511
512
513
514
515
516
517
518 public void setIncludeCipherSuites(String... cipherSuites)
519 {
520 _includeCipherSuites.clear();
521 _includeCipherSuites.addAll(Arrays.asList(cipherSuites));
522 }
523
524 public boolean isUseCipherSuitesOrder()
525 {
526 return _useCipherSuitesOrder;
527 }
528
529 public void setUseCipherSuitesOrder(boolean useCipherSuitesOrder)
530 {
531 _useCipherSuitesOrder = useCipherSuitesOrder;
532 }
533
534
535
536
537 public String getKeyStorePath()
538 {
539 return _keyStoreResource.toString();
540 }
541
542
543
544
545 public void setKeyStorePath(String keyStorePath)
546 {
547 try
548 {
549 _keyStoreResource = Resource.newResource(keyStorePath);
550 }
551 catch (Exception e)
552 {
553 throw new IllegalArgumentException(e);
554 }
555 }
556
557
558
559
560 public String getKeyStoreProvider()
561 {
562 return _keyStoreProvider;
563 }
564
565
566
567
568 public void setKeyStoreProvider(String keyStoreProvider)
569 {
570 _keyStoreProvider = keyStoreProvider;
571 }
572
573
574
575
576 public String getKeyStoreType()
577 {
578 return (_keyStoreType);
579 }
580
581
582
583
584 public void setKeyStoreType(String keyStoreType)
585 {
586 _keyStoreType = keyStoreType;
587 }
588
589
590
591
592 public String getCertAlias()
593 {
594 return _certAlias;
595 }
596
597
598
599
600
601
602
603
604
605
606 public void setCertAlias(String certAlias)
607 {
608 _certAlias = certAlias;
609 }
610
611
612
613
614 public void setTrustStorePath(String trustStorePath)
615 {
616 try
617 {
618 _trustStoreResource = Resource.newResource(trustStorePath);
619 }
620 catch (Exception e)
621 {
622 throw new IllegalArgumentException(e);
623 }
624 }
625
626
627
628
629 public String getTrustStoreProvider()
630 {
631 return _trustStoreProvider;
632 }
633
634
635
636
637 public void setTrustStoreProvider(String trustStoreProvider)
638 {
639 _trustStoreProvider = trustStoreProvider;
640 }
641
642
643
644
645 public String getTrustStoreType()
646 {
647 return _trustStoreType;
648 }
649
650
651
652
653 public void setTrustStoreType(String trustStoreType)
654 {
655 _trustStoreType = trustStoreType;
656 }
657
658
659
660
661
662 public boolean getNeedClientAuth()
663 {
664 return _needClientAuth;
665 }
666
667
668
669
670
671 public void setNeedClientAuth(boolean needClientAuth)
672 {
673 _needClientAuth = needClientAuth;
674 }
675
676
677
678
679
680 public boolean getWantClientAuth()
681 {
682 return _wantClientAuth;
683 }
684
685
686
687
688
689 public void setWantClientAuth(boolean wantClientAuth)
690 {
691 _wantClientAuth = wantClientAuth;
692 }
693
694
695
696
697 public boolean isValidateCerts()
698 {
699 return _validateCerts;
700 }
701
702
703
704
705 public void setValidateCerts(boolean validateCerts)
706 {
707 _validateCerts = validateCerts;
708 }
709
710
711
712
713 public boolean isValidatePeerCerts()
714 {
715 return _validatePeerCerts;
716 }
717
718
719
720
721 public void setValidatePeerCerts(boolean validatePeerCerts)
722 {
723 _validatePeerCerts = validatePeerCerts;
724 }
725
726
727
728
729
730
731
732
733 public void setKeyStorePassword(String password)
734 {
735 if (password == null)
736 {
737 if (_keyStoreResource != null)
738 _keyStorePassword = getPassword(PASSWORD_PROPERTY);
739 else
740 _keyStorePassword = null;
741 }
742 else
743 {
744 _keyStorePassword = newPassword(password);
745 }
746 }
747
748
749
750
751
752
753
754 public void setKeyManagerPassword(String password)
755 {
756 if (password == null)
757 {
758 if (System.getProperty(KEYPASSWORD_PROPERTY) != null)
759 _keyManagerPassword = getPassword(KEYPASSWORD_PROPERTY);
760 else
761 _keyManagerPassword = null;
762 }
763 else
764 {
765 _keyManagerPassword = newPassword(password);
766 }
767 }
768
769
770
771
772
773
774
775
776 public void setTrustStorePassword(String password)
777 {
778 if (password == null)
779 {
780 if (_trustStoreResource != null && !_trustStoreResource.equals(_keyStoreResource))
781 _trustStorePassword = getPassword(PASSWORD_PROPERTY);
782 else
783 _trustStorePassword = null;
784 }
785 else
786 {
787 _trustStorePassword = newPassword(password);
788 }
789 }
790
791
792
793
794
795 public String getProvider()
796 {
797 return _sslProvider;
798 }
799
800
801
802
803
804 public void setProvider(String provider)
805 {
806 _sslProvider = provider;
807 }
808
809
810
811
812
813 public String getProtocol()
814 {
815 return _sslProtocol;
816 }
817
818
819
820
821
822 public void setProtocol(String protocol)
823 {
824 _sslProtocol = protocol;
825 }
826
827
828
829
830
831
832 public String getSecureRandomAlgorithm()
833 {
834 return _secureRandomAlgorithm;
835 }
836
837
838
839
840
841
842 public void setSecureRandomAlgorithm(String algorithm)
843 {
844 _secureRandomAlgorithm = algorithm;
845 }
846
847
848
849
850 public String getKeyManagerFactoryAlgorithm()
851 {
852 return _keyManagerFactoryAlgorithm;
853 }
854
855
856
857
858 public void setKeyManagerFactoryAlgorithm(String algorithm)
859 {
860 _keyManagerFactoryAlgorithm = algorithm;
861 }
862
863
864
865
866 public String getTrustManagerFactoryAlgorithm()
867 {
868 return _trustManagerFactoryAlgorithm;
869 }
870
871
872
873
874 public boolean isTrustAll()
875 {
876 return _trustAll;
877 }
878
879
880
881
882 public void setTrustAll(boolean trustAll)
883 {
884 _trustAll = trustAll;
885 if (trustAll)
886 setEndpointIdentificationAlgorithm(null);
887 }
888
889
890
891
892
893 public void setTrustManagerFactoryAlgorithm(String algorithm)
894 {
895 _trustManagerFactoryAlgorithm = algorithm;
896 }
897
898
899
900
901 public boolean isRenegotiationAllowed()
902 {
903 return _renegotiationAllowed;
904 }
905
906
907
908
909 public void setRenegotiationAllowed(boolean renegotiationAllowed)
910 {
911 _renegotiationAllowed = renegotiationAllowed;
912 }
913
914
915
916
917 public String getCrlPath()
918 {
919 return _crlPath;
920 }
921
922
923
924
925 public void setCrlPath(String crlPath)
926 {
927 _crlPath = crlPath;
928 }
929
930
931
932
933
934 public int getMaxCertPathLength()
935 {
936 return _maxCertPathLength;
937 }
938
939
940
941
942
943 public void setMaxCertPathLength(int maxCertPathLength)
944 {
945 _maxCertPathLength = maxCertPathLength;
946 }
947
948
949
950
951 public SSLContext getSslContext()
952 {
953 if (!isStarted())
954 return _setContext;
955
956 synchronized (this)
957 {
958 return _factory._context;
959 }
960 }
961
962
963
964
965 public void setSslContext(SSLContext sslContext)
966 {
967 _setContext = sslContext;
968 }
969
970
971
972
973 public String getEndpointIdentificationAlgorithm()
974 {
975 return _endpointIdentificationAlgorithm;
976 }
977
978
979
980
981
982
983 public void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgorithm)
984 {
985 _endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
986 }
987
988
989
990
991
992
993
994
995 protected KeyStore loadKeyStore(Resource resource) throws Exception
996 {
997 String storePassword = _keyStorePassword == null ? null : _keyStorePassword.toString();
998 return CertificateUtils.getKeyStore(resource, getKeyStoreType(), getKeyStoreProvider(), storePassword);
999 }
1000
1001
1002
1003
1004
1005
1006
1007
1008 protected KeyStore loadTrustStore(Resource resource) throws Exception
1009 {
1010 String type = getTrustStoreType();
1011 String provider = getTrustStoreProvider();
1012 String passwd = _trustStorePassword == null ? null : _trustStorePassword.toString();
1013 if (resource == null || resource.equals(_keyStoreResource))
1014 {
1015 resource = _keyStoreResource;
1016 if (type == null)
1017 type = _keyStoreType;
1018 if (provider == null)
1019 provider = _keyStoreProvider;
1020 if (passwd == null)
1021 passwd = _keyStorePassword == null ? null : _keyStorePassword.toString();
1022 }
1023 return CertificateUtils.getKeyStore(resource, type, provider, passwd);
1024 }
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036 protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
1037 {
1038 return CertificateUtils.loadCRL(crlPath);
1039 }
1040
1041 protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception
1042 {
1043 KeyManager[] managers = null;
1044
1045 if (keyStore != null)
1046 {
1047 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(getKeyManagerFactoryAlgorithm());
1048 keyManagerFactory.init(keyStore, _keyManagerPassword == null ? (_keyStorePassword == null ? null : _keyStorePassword.toString().toCharArray()) : _keyManagerPassword.toString().toCharArray());
1049 managers = keyManagerFactory.getKeyManagers();
1050
1051 if (managers != null)
1052 {
1053 String alias = getCertAlias();
1054 if (alias != null)
1055 {
1056 for (int idx = 0; idx < managers.length; idx++)
1057 {
1058 if (managers[idx] instanceof X509ExtendedKeyManager)
1059 managers[idx] = new AliasedX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx], alias);
1060 }
1061 }
1062
1063 if (!_certHosts.isEmpty() || !_certWilds.isEmpty())
1064 {
1065 for (int idx = 0; idx < managers.length; idx++)
1066 {
1067 if (managers[idx] instanceof X509ExtendedKeyManager)
1068 managers[idx] = new SniX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx]);
1069 }
1070 }
1071 }
1072 }
1073
1074 if (LOG.isDebugEnabled())
1075 LOG.debug("managers={} for {}", managers, this);
1076
1077 return managers;
1078 }
1079
1080 protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
1081 {
1082 TrustManager[] managers = null;
1083 if (trustStore != null)
1084 {
1085
1086 if (isValidatePeerCerts() && "PKIX".equalsIgnoreCase(getTrustManagerFactoryAlgorithm()))
1087 {
1088 PKIXBuilderParameters pbParams = new PKIXBuilderParameters(trustStore, new X509CertSelector());
1089
1090
1091 pbParams.setMaxPathLength(_maxCertPathLength);
1092
1093
1094 pbParams.setRevocationEnabled(true);
1095
1096 if (crls != null && !crls.isEmpty())
1097 {
1098 pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(crls)));
1099 }
1100
1101 if (_enableCRLDP)
1102 {
1103
1104 System.setProperty("com.sun.security.enableCRLDP", "true");
1105 }
1106
1107 if (_enableOCSP)
1108 {
1109
1110 Security.setProperty("ocsp.enable", "true");
1111
1112 if (_ocspResponderURL != null)
1113 {
1114
1115 Security.setProperty("ocsp.responderURL", _ocspResponderURL);
1116 }
1117 }
1118
1119 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
1120 trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams));
1121
1122 managers = trustManagerFactory.getTrustManagers();
1123 }
1124 else
1125 {
1126 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
1127 trustManagerFactory.init(trustStore);
1128
1129 managers = trustManagerFactory.getTrustManagers();
1130 }
1131 }
1132
1133 return managers;
1134 }
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144 public void selectProtocols(String[] enabledProtocols, String[] supportedProtocols)
1145 {
1146 Set<String> selected_protocols = new LinkedHashSet<>();
1147
1148
1149 if (!_includeProtocols.isEmpty())
1150 {
1151
1152 for (String protocol : _includeProtocols)
1153 {
1154 if (Arrays.asList(supportedProtocols).contains(protocol))
1155 selected_protocols.add(protocol);
1156 else
1157 LOG.info("Protocol {} not supported in {}", protocol, Arrays.asList(supportedProtocols));
1158 }
1159 }
1160 else
1161 selected_protocols.addAll(Arrays.asList(enabledProtocols));
1162
1163
1164 selected_protocols.removeAll(_excludeProtocols);
1165
1166 if (selected_protocols.isEmpty())
1167 LOG.warn("No selected protocols from {}", Arrays.asList(supportedProtocols));
1168
1169 _selectedProtocols = selected_protocols.toArray(new String[0]);
1170 }
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180 protected void selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
1181 {
1182 List<String> selected_ciphers = new ArrayList<>();
1183
1184
1185 if (_includeCipherSuites.isEmpty())
1186 selected_ciphers.addAll(Arrays.asList(enabledCipherSuites));
1187 else
1188 processIncludeCipherSuites(supportedCipherSuites, selected_ciphers);
1189
1190 removeExcludedCipherSuites(selected_ciphers);
1191
1192 if (selected_ciphers.isEmpty())
1193 LOG.warn("No supported ciphers from {}", Arrays.asList(supportedCipherSuites));
1194
1195 Comparator<String> comparator = getCipherComparator();
1196 if (comparator != null)
1197 {
1198 if (LOG.isDebugEnabled())
1199 LOG.debug("Sorting selected ciphers with {}", comparator);
1200 Collections.sort(selected_ciphers, comparator);
1201 }
1202
1203 _selectedCipherSuites = selected_ciphers.toArray(new String[0]);
1204 }
1205
1206 protected void processIncludeCipherSuites(String[] supportedCipherSuites, List<String> selected_ciphers)
1207 {
1208 for (String cipherSuite : _includeCipherSuites)
1209 {
1210 Pattern p = Pattern.compile(cipherSuite);
1211 boolean added = false;
1212 for (String supportedCipherSuite : supportedCipherSuites)
1213 {
1214 Matcher m = p.matcher(supportedCipherSuite);
1215 if (m.matches())
1216 {
1217 added = true;
1218 selected_ciphers.add(supportedCipherSuite);
1219 }
1220
1221 }
1222 if (!added)
1223 LOG.info("No Cipher matching '{}' is supported", cipherSuite);
1224 }
1225 }
1226
1227 protected void removeExcludedCipherSuites(List<String> selected_ciphers)
1228 {
1229 for (String excludeCipherSuite : _excludeCipherSuites)
1230 {
1231 Pattern excludeCipherPattern = Pattern.compile(excludeCipherSuite);
1232 for (Iterator<String> i = selected_ciphers.iterator(); i.hasNext(); )
1233 {
1234 String selectedCipherSuite = i.next();
1235 Matcher m = excludeCipherPattern.matcher(selectedCipherSuite);
1236 if (m.matches())
1237 i.remove();
1238 }
1239 }
1240 }
1241
1242
1243
1244
1245 private void checkIsStarted()
1246 {
1247 if (!isStarted())
1248 throw new IllegalStateException("!STARTED: " + this);
1249 }
1250
1251
1252
1253
1254 public boolean isEnableCRLDP()
1255 {
1256 return _enableCRLDP;
1257 }
1258
1259
1260
1261
1262
1263
1264 public void setEnableCRLDP(boolean enableCRLDP)
1265 {
1266 _enableCRLDP = enableCRLDP;
1267 }
1268
1269
1270
1271
1272 public boolean isEnableOCSP()
1273 {
1274 return _enableOCSP;
1275 }
1276
1277
1278
1279
1280
1281
1282 public void setEnableOCSP(boolean enableOCSP)
1283 {
1284 _enableOCSP = enableOCSP;
1285 }
1286
1287
1288
1289
1290 public String getOcspResponderURL()
1291 {
1292 return _ocspResponderURL;
1293 }
1294
1295
1296
1297
1298
1299
1300 public void setOcspResponderURL(String ocspResponderURL)
1301 {
1302 _ocspResponderURL = ocspResponderURL;
1303 }
1304
1305
1306
1307
1308
1309
1310 public void setKeyStore(KeyStore keyStore)
1311 {
1312 _setKeyStore = keyStore;
1313 }
1314
1315 public KeyStore getKeyStore()
1316 {
1317 if (!isStarted())
1318 return _setKeyStore;
1319
1320 synchronized (this)
1321 {
1322 return _factory._keyStore;
1323 }
1324 }
1325
1326
1327
1328
1329
1330
1331 public void setTrustStore(KeyStore trustStore)
1332 {
1333 _setTrustStore = trustStore;
1334 }
1335
1336 public KeyStore getTrustStore()
1337 {
1338 if (!isStarted())
1339 return _setTrustStore;
1340
1341 synchronized (this)
1342 {
1343 return _factory._trustStore;
1344 }
1345 }
1346
1347
1348
1349
1350
1351
1352 public void setKeyStoreResource(Resource resource)
1353 {
1354 _keyStoreResource = resource;
1355 }
1356
1357 public Resource getKeyStoreResource()
1358 {
1359 return _keyStoreResource;
1360 }
1361
1362
1363
1364
1365
1366
1367 public void setTrustStoreResource(Resource resource)
1368 {
1369 _trustStoreResource = resource;
1370 }
1371
1372 public Resource getTrustStoreResource()
1373 {
1374 return _trustStoreResource;
1375 }
1376
1377
1378
1379
1380 public boolean isSessionCachingEnabled()
1381 {
1382 return _sessionCachingEnabled;
1383 }
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395 public void setSessionCachingEnabled(boolean enableSessionCaching)
1396 {
1397 _sessionCachingEnabled = enableSessionCaching;
1398 }
1399
1400
1401
1402
1403
1404
1405
1406 public int getSslSessionCacheSize()
1407 {
1408 return _sslSessionCacheSize;
1409 }
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419 public void setSslSessionCacheSize(int sslSessionCacheSize)
1420 {
1421 _sslSessionCacheSize = sslSessionCacheSize;
1422 }
1423
1424
1425
1426
1427
1428
1429 public int getSslSessionTimeout()
1430 {
1431 return _sslSessionTimeout;
1432 }
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442 public void setSslSessionTimeout(int sslSessionTimeout)
1443 {
1444 _sslSessionTimeout = sslSessionTimeout;
1445 }
1446
1447
1448
1449
1450
1451
1452
1453 protected Password getPassword(String realm)
1454 {
1455 return Password.getPassword(realm, null, null);
1456 }
1457
1458
1459
1460
1461
1462
1463
1464 public Password newPassword(String password)
1465 {
1466 return new Password(password);
1467 }
1468
1469 public SSLServerSocket newSslServerSocket(String host, int port, int backlog) throws IOException
1470 {
1471 checkIsStarted();
1472
1473 SSLContext context = getSslContext();
1474 SSLServerSocketFactory factory = context.getServerSocketFactory();
1475 SSLServerSocket socket =
1476 (SSLServerSocket)(host == null ?
1477 factory.createServerSocket(port, backlog) :
1478 factory.createServerSocket(port, backlog, InetAddress.getByName(host)));
1479 socket.setSSLParameters(customize(socket.getSSLParameters()));
1480
1481 return socket;
1482 }
1483
1484 public SSLSocket newSslSocket() throws IOException
1485 {
1486 checkIsStarted();
1487
1488 SSLContext context = getSslContext();
1489 SSLSocketFactory factory = context.getSocketFactory();
1490 SSLSocket socket = (SSLSocket)factory.createSocket();
1491 socket.setSSLParameters(customize(socket.getSSLParameters()));
1492
1493 return socket;
1494 }
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505 public SSLEngine newSSLEngine()
1506 {
1507 checkIsStarted();
1508
1509 SSLContext context = getSslContext();
1510 SSLEngine sslEngine = context.createSSLEngine();
1511 customize(sslEngine);
1512
1513 return sslEngine;
1514 }
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524 public SSLEngine newSSLEngine(String host, int port)
1525 {
1526 checkIsStarted();
1527
1528 SSLContext context = getSslContext();
1529 SSLEngine sslEngine = isSessionCachingEnabled() ?
1530 context.createSSLEngine(host, port) :
1531 context.createSSLEngine();
1532 customize(sslEngine);
1533
1534 return sslEngine;
1535 }
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555 public SSLEngine newSSLEngine(InetSocketAddress address)
1556 {
1557 if (address == null)
1558 return newSSLEngine();
1559
1560 boolean useHostName = getNeedClientAuth();
1561 String hostName = useHostName ? address.getHostName() : address.getAddress().getHostAddress();
1562 return newSSLEngine(hostName, address.getPort());
1563 }
1564
1565
1566
1567
1568
1569
1570
1571 public void customize(SSLEngine sslEngine)
1572 {
1573 if (LOG.isDebugEnabled())
1574 LOG.debug("Customize {}", sslEngine);
1575
1576 sslEngine.setSSLParameters(customize(sslEngine.getSSLParameters()));
1577 }
1578
1579
1580
1581
1582
1583
1584
1585 public SSLParameters customize(SSLParameters sslParams)
1586 {
1587 sslParams.setEndpointIdentificationAlgorithm(getEndpointIdentificationAlgorithm());
1588 sslParams.setUseCipherSuitesOrder(isUseCipherSuitesOrder());
1589 if (!_certHosts.isEmpty() || !_certWilds.isEmpty())
1590 sslParams.setSNIMatchers(Collections.singletonList(new AliasSNIMatcher()));
1591 if (_selectedCipherSuites != null)
1592 sslParams.setCipherSuites(_selectedCipherSuites);
1593 if (_selectedProtocols != null)
1594 sslParams.setProtocols(_selectedProtocols);
1595 if (getWantClientAuth())
1596 sslParams.setWantClientAuth(true);
1597 if (getNeedClientAuth())
1598 sslParams.setNeedClientAuth(true);
1599 return sslParams;
1600 }
1601
1602 public void reload(Consumer<SslContextFactory> consumer) throws Exception
1603 {
1604 synchronized (this)
1605 {
1606 consumer.accept(this);
1607 unload();
1608 load();
1609 }
1610 }
1611
1612 public static X509Certificate[] getCertChain(SSLSession sslSession)
1613 {
1614 try
1615 {
1616 Certificate[] javaxCerts = sslSession.getPeerCertificates();
1617 if (javaxCerts == null || javaxCerts.length == 0)
1618 return null;
1619
1620 int length = javaxCerts.length;
1621 X509Certificate[] javaCerts = new X509Certificate[length];
1622
1623 java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509");
1624 for (int i = 0; i < length; i++)
1625 {
1626 byte bytes[] = javaxCerts[i].getEncoded();
1627 ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
1628 javaCerts[i] = (X509Certificate)cf.generateCertificate(stream);
1629 }
1630
1631 return javaCerts;
1632 }
1633 catch (SSLPeerUnverifiedException pue)
1634 {
1635 return null;
1636 }
1637 catch (Exception e)
1638 {
1639 LOG.warn(Log.EXCEPTION, e);
1640 return null;
1641 }
1642 }
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668 public static int deduceKeyLength(String cipherSuite)
1669 {
1670
1671 if (cipherSuite == null)
1672 return 0;
1673 else if (cipherSuite.contains("WITH_AES_256_"))
1674 return 256;
1675 else if (cipherSuite.contains("WITH_RC4_128_"))
1676 return 128;
1677 else if (cipherSuite.contains("WITH_AES_128_"))
1678 return 128;
1679 else if (cipherSuite.contains("WITH_RC4_40_"))
1680 return 40;
1681 else if (cipherSuite.contains("WITH_3DES_EDE_CBC_"))
1682 return 168;
1683 else if (cipherSuite.contains("WITH_IDEA_CBC_"))
1684 return 128;
1685 else if (cipherSuite.contains("WITH_RC2_CBC_40_"))
1686 return 40;
1687 else if (cipherSuite.contains("WITH_DES40_CBC_"))
1688 return 40;
1689 else if (cipherSuite.contains("WITH_DES_CBC_"))
1690 return 56;
1691 else
1692 return 0;
1693 }
1694
1695 @Override
1696 public String toString()
1697 {
1698 return String.format("%s@%x(%s,%s)",
1699 getClass().getSimpleName(),
1700 hashCode(),
1701 _keyStoreResource,
1702 _trustStoreResource);
1703 }
1704
1705 class Factory
1706 {
1707 private final KeyStore _keyStore;
1708 private final KeyStore _trustStore;
1709 private final SSLContext _context;
1710
1711 Factory(KeyStore keyStore, KeyStore trustStore, SSLContext context)
1712 {
1713 super();
1714 _keyStore = keyStore;
1715 _trustStore = trustStore;
1716 _context = context;
1717 }
1718 }
1719
1720 class AliasSNIMatcher extends SNIMatcher
1721 {
1722 private String _host;
1723 private X509 _x509;
1724
1725 AliasSNIMatcher()
1726 {
1727 super(StandardConstants.SNI_HOST_NAME);
1728 }
1729
1730 @Override
1731 public boolean matches(SNIServerName serverName)
1732 {
1733 if (LOG.isDebugEnabled())
1734 LOG.debug("SNI matching for {}", serverName);
1735
1736 if (serverName instanceof SNIHostName)
1737 {
1738 String host = _host = ((SNIHostName)serverName).getAsciiName();
1739 host = StringUtil.asciiToLowerCase(host);
1740
1741
1742 _x509 = _certHosts.get(host);
1743
1744
1745 if (_x509 == null)
1746 {
1747 _x509 = _certWilds.get(host);
1748
1749
1750 if (_x509 == null)
1751 {
1752 int dot = host.indexOf('.');
1753 if (dot >= 0)
1754 {
1755 String domain = host.substring(dot + 1);
1756 _x509 = _certWilds.get(domain);
1757 }
1758 }
1759 }
1760
1761 if (LOG.isDebugEnabled())
1762 LOG.debug("SNI matched {}->{}", host, _x509);
1763 }
1764 else
1765 {
1766 if (LOG.isDebugEnabled())
1767 LOG.debug("SNI no match for {}", serverName);
1768 }
1769
1770
1771
1772
1773 return true;
1774 }
1775
1776 public String getHost()
1777 {
1778 return _host;
1779 }
1780
1781 public X509 getX509()
1782 {
1783 return _x509;
1784 }
1785 }
1786 }