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