1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.handler.ssl;
18
19 import io.netty.buffer.ByteBuf;
20 import io.netty.buffer.ByteBufAllocator;
21 import io.netty.buffer.ByteBufInputStream;
22 import io.netty.channel.ChannelInitializer;
23 import io.netty.channel.ChannelPipeline;
24 import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
25 import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
26 import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
27 import io.netty.handler.ssl.util.BouncyCastleUtil;
28 import io.netty.util.AttributeMap;
29 import io.netty.util.DefaultAttributeMap;
30 import io.netty.util.concurrent.ImmediateExecutor;
31 import io.netty.util.internal.EmptyArrays;
32
33 import java.io.BufferedInputStream;
34 import java.io.File;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.security.AlgorithmParameters;
38 import java.security.InvalidAlgorithmParameterException;
39 import java.security.InvalidKeyException;
40 import java.security.KeyException;
41 import java.security.KeyFactory;
42 import java.security.KeyStore;
43 import java.security.KeyStoreException;
44 import java.security.NoSuchAlgorithmException;
45 import java.security.PrivateKey;
46 import java.security.Provider;
47 import java.security.SecureRandom;
48 import java.security.UnrecoverableKeyException;
49 import java.security.cert.CertificateException;
50 import java.security.cert.CertificateFactory;
51 import java.security.cert.X509Certificate;
52 import java.security.spec.InvalidKeySpecException;
53 import java.security.spec.PKCS8EncodedKeySpec;
54 import java.util.Collections;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.concurrent.Executor;
58 import javax.crypto.Cipher;
59 import javax.crypto.EncryptedPrivateKeyInfo;
60 import javax.crypto.NoSuchPaddingException;
61 import javax.crypto.SecretKey;
62 import javax.crypto.SecretKeyFactory;
63 import javax.crypto.spec.PBEKeySpec;
64 import javax.net.ssl.KeyManager;
65 import javax.net.ssl.KeyManagerFactory;
66 import javax.net.ssl.SNIServerName;
67 import javax.net.ssl.SSLContext;
68 import javax.net.ssl.SSLEngine;
69 import javax.net.ssl.SSLException;
70 import javax.net.ssl.SSLSessionContext;
71 import javax.net.ssl.TrustManager;
72 import javax.net.ssl.TrustManagerFactory;
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public abstract class SslContext {
97 static final String ALIAS = "key";
98
99 static final CertificateFactory X509_CERT_FACTORY;
100 static {
101 try {
102 X509_CERT_FACTORY = CertificateFactory.getInstance("X.509");
103 } catch (CertificateException e) {
104 throw new IllegalStateException("unable to instance X.509 CertificateFactory", e);
105 }
106 }
107
108 private final boolean startTls;
109 private final AttributeMap attributes = new DefaultAttributeMap();
110 final ResumptionController resumptionController;
111 private static final String OID_PKCS5_PBES2 = "1.2.840.113549.1.5.13";
112 private static final String PBES2 = "PBES2";
113
114
115
116
117
118
119 public static SslProvider defaultServerProvider() {
120 return defaultProvider();
121 }
122
123
124
125
126
127
128 public static SslProvider defaultClientProvider() {
129 return defaultProvider();
130 }
131
132 private static SslProvider defaultProvider() {
133 if (OpenSsl.isAvailable()) {
134 return SslProvider.OPENSSL;
135 } else {
136 return SslProvider.JDK;
137 }
138 }
139
140
141
142
143
144
145
146
147
148 @Deprecated
149 public static SslContext newServerContext(File certChainFile, File keyFile) throws SSLException {
150 return newServerContext(certChainFile, keyFile, null);
151 }
152
153
154
155
156
157
158
159
160
161
162
163 @Deprecated
164 public static SslContext newServerContext(
165 File certChainFile, File keyFile, String keyPassword) throws SSLException {
166 return newServerContext(null, certChainFile, keyFile, keyPassword);
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 @Deprecated
188 public static SslContext newServerContext(
189 File certChainFile, File keyFile, String keyPassword,
190 Iterable<String> ciphers, Iterable<String> nextProtocols,
191 long sessionCacheSize, long sessionTimeout) throws SSLException {
192
193 return newServerContext(
194 null, certChainFile, keyFile, keyPassword,
195 ciphers, nextProtocols, sessionCacheSize, sessionTimeout);
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 @Deprecated
217 public static SslContext newServerContext(
218 File certChainFile, File keyFile, String keyPassword,
219 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
220 long sessionCacheSize, long sessionTimeout) throws SSLException {
221 return newServerContext(
222 null, certChainFile, keyFile, keyPassword,
223 ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
224 }
225
226
227
228
229
230
231
232
233
234
235
236 @Deprecated
237 public static SslContext newServerContext(
238 SslProvider provider, File certChainFile, File keyFile) throws SSLException {
239 return newServerContext(provider, certChainFile, keyFile, null);
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253
254 @Deprecated
255 public static SslContext newServerContext(
256 SslProvider provider, File certChainFile, File keyFile, String keyPassword) throws SSLException {
257 return newServerContext(provider, certChainFile, keyFile, keyPassword, null, IdentityCipherSuiteFilter.INSTANCE,
258 null, 0, 0);
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 @Deprecated
282 public static SslContext newServerContext(
283 SslProvider provider,
284 File certChainFile, File keyFile, String keyPassword,
285 Iterable<String> ciphers, Iterable<String> nextProtocols,
286 long sessionCacheSize, long sessionTimeout) throws SSLException {
287 return newServerContext(provider, certChainFile, keyFile, keyPassword,
288 ciphers, IdentityCipherSuiteFilter.INSTANCE,
289 toApplicationProtocolConfig(nextProtocols), sessionCacheSize, sessionTimeout);
290 }
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315 @Deprecated
316 public static SslContext newServerContext(
317 SslProvider provider,
318 File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory,
319 Iterable<String> ciphers, Iterable<String> nextProtocols,
320 long sessionCacheSize, long sessionTimeout) throws SSLException {
321
322 return newServerContext(
323 provider, null, trustManagerFactory, certChainFile, keyFile, keyPassword,
324 null, ciphers, IdentityCipherSuiteFilter.INSTANCE,
325 toApplicationProtocolConfig(nextProtocols), sessionCacheSize, sessionTimeout);
326 }
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 @Deprecated
350 public static SslContext newServerContext(SslProvider provider,
351 File certChainFile, File keyFile, String keyPassword,
352 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
353 long sessionCacheSize, long sessionTimeout) throws SSLException {
354 return newServerContext(provider, null, null, certChainFile, keyFile, keyPassword, null,
355 ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391 @Deprecated
392 public static SslContext newServerContext(
393 SslProvider provider,
394 File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
395 File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
396 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
397 long sessionCacheSize, long sessionTimeout) throws SSLException {
398 return newServerContext(provider, trustCertCollectionFile, trustManagerFactory, keyCertChainFile,
399 keyFile, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn,
400 sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
401 }
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 static SslContext newServerContext(
437 SslProvider provider,
438 File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
439 File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
440 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
441 long sessionCacheSize, long sessionTimeout, String keyStore) throws SSLException {
442 try {
443 return newServerContextInternal(provider, null, toX509Certificates(trustCertCollectionFile),
444 trustManagerFactory, toX509Certificates(keyCertChainFile),
445 toPrivateKey(keyFile, keyPassword),
446 keyPassword, keyManagerFactory, ciphers, cipherFilter, apn,
447 sessionCacheSize, sessionTimeout, ClientAuth.NONE, null,
448 false, false, null, keyStore);
449 } catch (Exception e) {
450 if (e instanceof SSLException) {
451 throw (SSLException) e;
452 }
453 throw new SSLException("failed to initialize the server-side SSL context", e);
454 }
455 }
456
457 static SslContext newServerContextInternal(
458 SslProvider provider,
459 Provider sslContextProvider,
460 X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
461 X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
462 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
463 long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
464 boolean enableOcsp, SecureRandom secureRandom, String keyStoreType,
465 Map.Entry<SslContextOption<?>, Object>... ctxOptions)
466 throws SSLException {
467
468 if (provider == null) {
469 provider = defaultServerProvider();
470 }
471
472 ResumptionController resumptionController = new ResumptionController();
473
474 switch (provider) {
475 case JDK:
476 if (enableOcsp) {
477 throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
478 }
479 return new JdkSslServerContext(sslContextProvider,
480 trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
481 keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
482 clientAuth, protocols, startTls, secureRandom, keyStoreType, resumptionController);
483 case OPENSSL:
484 verifyNullSslContextProvider(provider, sslContextProvider);
485 return new OpenSslServerContext(
486 trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
487 keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
488 clientAuth, protocols, startTls, enableOcsp, keyStoreType, resumptionController, ctxOptions);
489 case OPENSSL_REFCNT:
490 verifyNullSslContextProvider(provider, sslContextProvider);
491 return new ReferenceCountedOpenSslServerContext(
492 trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
493 keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
494 clientAuth, protocols, startTls, enableOcsp, keyStoreType, resumptionController, ctxOptions);
495 default:
496 throw new Error("Unexpected provider: " + provider);
497 }
498 }
499
500 private static void verifyNullSslContextProvider(SslProvider provider, Provider sslContextProvider) {
501 if (sslContextProvider != null) {
502 throw new IllegalArgumentException("Java Security Provider unsupported for SslProvider: " + provider);
503 }
504 }
505
506
507
508
509
510
511
512 @Deprecated
513 public static SslContext newClientContext() throws SSLException {
514 return newClientContext(null, null, null);
515 }
516
517
518
519
520
521
522
523
524
525 @Deprecated
526 public static SslContext newClientContext(File certChainFile) throws SSLException {
527 return newClientContext(null, certChainFile);
528 }
529
530
531
532
533
534
535
536
537
538
539
540 @Deprecated
541 public static SslContext newClientContext(TrustManagerFactory trustManagerFactory) throws SSLException {
542 return newClientContext(null, null, trustManagerFactory);
543 }
544
545
546
547
548
549
550
551
552
553
554
555
556
557 @Deprecated
558 public static SslContext newClientContext(
559 File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException {
560 return newClientContext(null, certChainFile, trustManagerFactory);
561 }
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583 @Deprecated
584 public static SslContext newClientContext(
585 File certChainFile, TrustManagerFactory trustManagerFactory,
586 Iterable<String> ciphers, Iterable<String> nextProtocols,
587 long sessionCacheSize, long sessionTimeout) throws SSLException {
588 return newClientContext(
589 null, certChainFile, trustManagerFactory,
590 ciphers, nextProtocols, sessionCacheSize, sessionTimeout);
591 }
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613 @Deprecated
614 public static SslContext newClientContext(
615 File certChainFile, TrustManagerFactory trustManagerFactory,
616 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
617 long sessionCacheSize, long sessionTimeout) throws SSLException {
618 return newClientContext(
619 null, certChainFile, trustManagerFactory,
620 ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
621 }
622
623
624
625
626
627
628
629
630
631
632 @Deprecated
633 public static SslContext newClientContext(SslProvider provider) throws SSLException {
634 return newClientContext(provider, null, null);
635 }
636
637
638
639
640
641
642
643
644
645
646
647
648 @Deprecated
649 public static SslContext newClientContext(SslProvider provider, File certChainFile) throws SSLException {
650 return newClientContext(provider, certChainFile, null);
651 }
652
653
654
655
656
657
658
659
660
661
662
663
664
665 @Deprecated
666 public static SslContext newClientContext(
667 SslProvider provider, TrustManagerFactory trustManagerFactory) throws SSLException {
668 return newClientContext(provider, null, trustManagerFactory);
669 }
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685 @Deprecated
686 public static SslContext newClientContext(
687 SslProvider provider, File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException {
688 return newClientContext(provider, certChainFile, trustManagerFactory, null, IdentityCipherSuiteFilter.INSTANCE,
689 null, 0, 0);
690 }
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714 @Deprecated
715 public static SslContext newClientContext(
716 SslProvider provider,
717 File certChainFile, TrustManagerFactory trustManagerFactory,
718 Iterable<String> ciphers, Iterable<String> nextProtocols,
719 long sessionCacheSize, long sessionTimeout) throws SSLException {
720 return newClientContext(
721 provider, certChainFile, trustManagerFactory, null, null, null, null,
722 ciphers, IdentityCipherSuiteFilter.INSTANCE,
723 toApplicationProtocolConfig(nextProtocols), sessionCacheSize, sessionTimeout);
724 }
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748 @Deprecated
749 public static SslContext newClientContext(
750 SslProvider provider,
751 File certChainFile, TrustManagerFactory trustManagerFactory,
752 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
753 long sessionCacheSize, long sessionTimeout) throws SSLException {
754
755 return newClientContext(
756 provider, certChainFile, trustManagerFactory, null, null, null, null,
757 ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
758 }
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797 @Deprecated
798 public static SslContext newClientContext(
799 SslProvider provider,
800 File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
801 File keyCertChainFile, File keyFile, String keyPassword,
802 KeyManagerFactory keyManagerFactory,
803 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
804 long sessionCacheSize, long sessionTimeout) throws SSLException {
805 try {
806 return newClientContextInternal(provider, null,
807 toX509Certificates(trustCertCollectionFile), trustManagerFactory,
808 toX509Certificates(keyCertChainFile), toPrivateKey(keyFile, keyPassword),
809 keyPassword, keyManagerFactory, ciphers, cipherFilter,
810 apn, null, sessionCacheSize, sessionTimeout, false,
811 null, KeyStore.getDefaultType(),
812 SslUtils.defaultEndpointVerificationAlgorithm,
813 Collections.emptyList());
814 } catch (Exception e) {
815 if (e instanceof SSLException) {
816 throw (SSLException) e;
817 }
818 throw new SSLException("failed to initialize the client-side SSL context", e);
819 }
820 }
821
822 static SslContext newClientContextInternal(
823 SslProvider provider,
824 Provider sslContextProvider,
825 X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory,
826 X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
827 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols,
828 long sessionCacheSize, long sessionTimeout, boolean enableOcsp,
829 SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm,
830 List<SNIServerName> serverNames,
831 Map.Entry<SslContextOption<?>, Object>... options) throws SSLException {
832 if (provider == null) {
833 provider = defaultClientProvider();
834 }
835
836 ResumptionController resumptionController = new ResumptionController();
837
838 switch (provider) {
839 case JDK:
840 if (enableOcsp) {
841 throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
842 }
843 return new JdkSslClientContext(sslContextProvider,
844 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
845 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize,
846 sessionTimeout, secureRandom, keyStoreType, endpointIdentificationAlgorithm,
847 serverNames, resumptionController);
848 case OPENSSL:
849 verifyNullSslContextProvider(provider, sslContextProvider);
850 OpenSsl.ensureAvailability();
851 return new OpenSslClientContext(
852 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
853 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
854 enableOcsp, keyStoreType, endpointIdentificationAlgorithm, serverNames, resumptionController,
855 options);
856 case OPENSSL_REFCNT:
857 verifyNullSslContextProvider(provider, sslContextProvider);
858 OpenSsl.ensureAvailability();
859 return new ReferenceCountedOpenSslClientContext(
860 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
861 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
862 enableOcsp, keyStoreType, endpointIdentificationAlgorithm, serverNames, resumptionController,
863 options);
864 default:
865 throw new Error("Unexpected provider: " + provider);
866 }
867 }
868
869 static ApplicationProtocolConfig toApplicationProtocolConfig(Iterable<String> nextProtocols) {
870 ApplicationProtocolConfig apn;
871 if (nextProtocols == null) {
872 apn = ApplicationProtocolConfig.DISABLED;
873 } else {
874 apn = new ApplicationProtocolConfig(
875 Protocol.NPN_AND_ALPN, SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL,
876 SelectedListenerFailureBehavior.ACCEPT, nextProtocols);
877 }
878 return apn;
879 }
880
881
882
883
884 protected SslContext() {
885 this(false);
886 }
887
888
889
890
891 protected SslContext(boolean startTls) {
892 this(startTls, null);
893 }
894
895 SslContext(boolean startTls, ResumptionController resumptionController) {
896 this.startTls = startTls;
897 this.resumptionController = resumptionController;
898 }
899
900
901
902
903 public final AttributeMap attributes() {
904 return attributes;
905 }
906
907
908
909
910 public final boolean isServer() {
911 return !isClient();
912 }
913
914
915
916
917 public abstract boolean isClient();
918
919
920
921
922 public abstract List<String> cipherSuites();
923
924
925
926
927 public long sessionCacheSize() {
928 return sessionContext().getSessionCacheSize();
929 }
930
931
932
933
934 public long sessionTimeout() {
935 return sessionContext().getSessionTimeout();
936 }
937
938
939
940
941 @Deprecated
942 public final List<String> nextProtocols() {
943 return applicationProtocolNegotiator().protocols();
944 }
945
946
947
948
949 public abstract ApplicationProtocolNegotiator applicationProtocolNegotiator();
950
951
952
953
954
955
956
957 public abstract SSLEngine newEngine(ByteBufAllocator alloc);
958
959
960
961
962
963
964
965
966
967
968
969 public abstract SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort);
970
971
972
973
974 public abstract SSLSessionContext sessionContext();
975
976
977
978
979
980 public final SslHandler newHandler(ByteBufAllocator alloc) {
981 return newHandler(alloc, startTls);
982 }
983
984
985
986
987
988 protected SslHandler newHandler(ByteBufAllocator alloc, boolean startTls) {
989 return new SslHandler(newEngine(alloc), startTls, ImmediateExecutor.INSTANCE, resumptionController);
990 }
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 public SslHandler newHandler(ByteBufAllocator alloc, Executor delegatedTaskExecutor) {
1018 return newHandler(alloc, startTls, delegatedTaskExecutor);
1019 }
1020
1021
1022
1023
1024
1025 protected SslHandler newHandler(ByteBufAllocator alloc, boolean startTls, Executor executor) {
1026 return new SslHandler(newEngine(alloc), startTls, executor, resumptionController);
1027 }
1028
1029
1030
1031
1032
1033
1034 public final SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort) {
1035 return newHandler(alloc, peerHost, peerPort, startTls);
1036 }
1037
1038
1039
1040
1041
1042 protected SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, boolean startTls) {
1043 return new SslHandler(newEngine(alloc, peerHost, peerPort), startTls, ImmediateExecutor.INSTANCE,
1044 resumptionController);
1045 }
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 public SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort,
1076 Executor delegatedTaskExecutor) {
1077 return newHandler(alloc, peerHost, peerPort, startTls, delegatedTaskExecutor);
1078 }
1079
1080 protected SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, boolean startTls,
1081 Executor delegatedTaskExecutor) {
1082 return new SslHandler(newEngine(alloc, peerHost, peerPort), startTls, delegatedTaskExecutor,
1083 resumptionController);
1084 }
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102 @Deprecated
1103 protected static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key)
1104 throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
1105 InvalidKeyException, InvalidAlgorithmParameterException {
1106
1107 if (password == null) {
1108 return new PKCS8EncodedKeySpec(key);
1109 }
1110
1111 EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(key);
1112 String pbeAlgorithm = getPBEAlgorithm(encryptedPrivateKeyInfo);
1113 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(pbeAlgorithm);
1114 PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
1115 SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
1116
1117 Cipher cipher = Cipher.getInstance(pbeAlgorithm);
1118 cipher.init(Cipher.DECRYPT_MODE, pbeKey, encryptedPrivateKeyInfo.getAlgParameters());
1119
1120 return encryptedPrivateKeyInfo.getKeySpec(cipher);
1121 }
1122
1123 private static String getPBEAlgorithm(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) {
1124 AlgorithmParameters parameters = encryptedPrivateKeyInfo.getAlgParameters();
1125 String algName = encryptedPrivateKeyInfo.getAlgName();
1126
1127
1128 if (parameters != null && (OID_PKCS5_PBES2.equals(algName) || PBES2.equals(algName))) {
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139 return parameters.toString();
1140 }
1141 return encryptedPrivateKeyInfo.getAlgName();
1142 }
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 protected static KeyStore buildKeyStore(X509Certificate[] certChain, PrivateKey key,
1155 char[] keyPasswordChars, String keyStoreType)
1156 throws KeyStoreException, NoSuchAlgorithmException,
1157 CertificateException, IOException {
1158 if (keyStoreType == null) {
1159 keyStoreType = KeyStore.getDefaultType();
1160 }
1161 KeyStore ks = KeyStore.getInstance(keyStoreType);
1162 ks.load(null, null);
1163 ks.setKeyEntry(ALIAS, key, keyPasswordChars, certChain);
1164 return ks;
1165 }
1166
1167 protected static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException,
1168 NoSuchPaddingException, InvalidKeySpecException,
1169 InvalidAlgorithmParameterException,
1170 KeyException, IOException {
1171 return toPrivateKey(keyFile, keyPassword, true);
1172 }
1173
1174 static PrivateKey toPrivateKey(File keyFile, String keyPassword, boolean tryBouncyCastle)
1175 throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
1176 InvalidAlgorithmParameterException,
1177 KeyException, IOException {
1178 if (keyFile == null) {
1179 return null;
1180 }
1181
1182
1183 if (tryBouncyCastle && BouncyCastleUtil.isBcPkixAvailable()) {
1184 PrivateKey pk = BouncyCastlePemReader.getPrivateKey(keyFile, keyPassword);
1185 if (pk != null) {
1186 return pk;
1187 }
1188 }
1189
1190 return getPrivateKeyFromByteBuffer(PemReader.readPrivateKey(keyFile), keyPassword);
1191 }
1192
1193 protected static PrivateKey toPrivateKey(InputStream keyInputStream, String keyPassword)
1194 throws NoSuchAlgorithmException,
1195 NoSuchPaddingException, InvalidKeySpecException,
1196 InvalidAlgorithmParameterException,
1197 KeyException, IOException {
1198 if (keyInputStream == null) {
1199 return null;
1200 }
1201
1202
1203 if (BouncyCastleUtil.isBcPkixAvailable()) {
1204 if (!keyInputStream.markSupported()) {
1205
1206 keyInputStream = new BufferedInputStream(keyInputStream);
1207 }
1208 keyInputStream.mark(1048576);
1209 PrivateKey pk = BouncyCastlePemReader.getPrivateKey(keyInputStream, keyPassword);
1210 if (pk != null) {
1211 return pk;
1212 }
1213
1214 keyInputStream.reset();
1215 }
1216
1217 return getPrivateKeyFromByteBuffer(PemReader.readPrivateKey(keyInputStream), keyPassword);
1218 }
1219
1220 private static PrivateKey getPrivateKeyFromByteBuffer(ByteBuf encodedKeyBuf, String keyPassword)
1221 throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
1222 InvalidAlgorithmParameterException, KeyException, IOException {
1223
1224 byte[] encodedKey = new byte[encodedKeyBuf.readableBytes()];
1225 encodedKeyBuf.readBytes(encodedKey).release();
1226
1227 PKCS8EncodedKeySpec encodedKeySpec = generateKeySpec(
1228 keyPassword == null ? null : keyPassword.toCharArray(), encodedKey);
1229 try {
1230 return KeyFactory.getInstance("RSA").generatePrivate(encodedKeySpec);
1231 } catch (InvalidKeySpecException ignore) {
1232 try {
1233 return KeyFactory.getInstance("DSA").generatePrivate(encodedKeySpec);
1234 } catch (InvalidKeySpecException ignore2) {
1235 try {
1236 return KeyFactory.getInstance("EC").generatePrivate(encodedKeySpec);
1237 } catch (InvalidKeySpecException e) {
1238 throw new InvalidKeySpecException("Neither RSA, DSA nor EC worked", e);
1239 }
1240 }
1241 }
1242 }
1243
1244
1245
1246
1247
1248
1249
1250 @Deprecated
1251 protected static TrustManagerFactory buildTrustManagerFactory(
1252 File certChainFile, TrustManagerFactory trustManagerFactory)
1253 throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
1254 return buildTrustManagerFactory(certChainFile, trustManagerFactory, null);
1255 }
1256
1257
1258
1259
1260
1261
1262
1263
1264 protected static TrustManagerFactory buildTrustManagerFactory(
1265 File certChainFile, TrustManagerFactory trustManagerFactory, String keyType)
1266 throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
1267 X509Certificate[] x509Certs = toX509Certificates(certChainFile);
1268
1269 return buildTrustManagerFactory(x509Certs, trustManagerFactory, keyType);
1270 }
1271
1272 protected static X509Certificate[] toX509Certificates(File file) throws CertificateException {
1273 if (file == null) {
1274 return null;
1275 }
1276 return getCertificatesFromBuffers(PemReader.readCertificates(file));
1277 }
1278
1279 protected static X509Certificate[] toX509Certificates(InputStream in) throws CertificateException {
1280 if (in == null) {
1281 return null;
1282 }
1283 return getCertificatesFromBuffers(PemReader.readCertificates(in));
1284 }
1285
1286 private static X509Certificate[] getCertificatesFromBuffers(ByteBuf[] certs) throws CertificateException {
1287 CertificateFactory cf = CertificateFactory.getInstance("X.509");
1288 X509Certificate[] x509Certs = new X509Certificate[certs.length];
1289
1290 try {
1291 for (int i = 0; i < certs.length; i++) {
1292 try (InputStream is = new ByteBufInputStream(certs[i], false)) {
1293 x509Certs[i] = (X509Certificate) cf.generateCertificate(is);
1294 } catch (IOException e) {
1295
1296 throw new RuntimeException(e);
1297 }
1298 }
1299 } finally {
1300 for (ByteBuf buf: certs) {
1301 buf.release();
1302 }
1303 }
1304 return x509Certs;
1305 }
1306
1307 protected static TrustManagerFactory buildTrustManagerFactory(
1308 X509Certificate[] certCollection, TrustManagerFactory trustManagerFactory, String keyStoreType)
1309 throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
1310 if (keyStoreType == null) {
1311 keyStoreType = KeyStore.getDefaultType();
1312 }
1313 final KeyStore ks = KeyStore.getInstance(keyStoreType);
1314 ks.load(null, null);
1315
1316 int i = 1;
1317 for (X509Certificate cert: certCollection) {
1318 String alias = Integer.toString(i);
1319 ks.setCertificateEntry(alias, cert);
1320 i++;
1321 }
1322
1323
1324 if (trustManagerFactory == null) {
1325 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
1326 }
1327 trustManagerFactory.init(ks);
1328
1329 return trustManagerFactory;
1330 }
1331
1332 static PrivateKey toPrivateKeyInternal(File keyFile, String keyPassword) throws SSLException {
1333 try {
1334 return toPrivateKey(keyFile, keyPassword);
1335 } catch (Exception e) {
1336 throw new SSLException(e);
1337 }
1338 }
1339
1340 static X509Certificate[] toX509CertificatesInternal(File file) throws SSLException {
1341 try {
1342 return toX509Certificates(file);
1343 } catch (CertificateException e) {
1344 throw new SSLException(e);
1345 }
1346 }
1347
1348 protected static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChainFile,
1349 String keyAlgorithm, PrivateKey key,
1350 String keyPassword, KeyManagerFactory kmf,
1351 String keyStore)
1352 throws KeyStoreException, NoSuchAlgorithmException, IOException,
1353 CertificateException, UnrecoverableKeyException {
1354 if (keyAlgorithm == null) {
1355 keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
1356 }
1357 char[] keyPasswordChars = keyStorePassword(keyPassword);
1358 KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars, keyStore);
1359 return buildKeyManagerFactory(ks, keyAlgorithm, keyPasswordChars, kmf);
1360 }
1361
1362 static KeyManagerFactory buildKeyManagerFactory(KeyStore ks,
1363 String keyAlgorithm,
1364 char[] keyPasswordChars, KeyManagerFactory kmf)
1365 throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
1366
1367 if (kmf == null) {
1368 if (keyAlgorithm == null) {
1369 keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
1370 }
1371 kmf = KeyManagerFactory.getInstance(keyAlgorithm);
1372 }
1373 kmf.init(ks, keyPasswordChars);
1374
1375 return kmf;
1376 }
1377
1378 static char[] keyStorePassword(String keyPassword) {
1379 return keyPassword == null ? EmptyArrays.EMPTY_CHARS : keyPassword.toCharArray();
1380 }
1381 }