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