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 import io.netty.util.internal.PlatformDependent;
33
34 import java.io.BufferedInputStream;
35 import java.security.Provider;
36 import javax.net.ssl.KeyManager;
37 import javax.net.ssl.KeyManagerFactory;
38 import javax.crypto.Cipher;
39 import javax.crypto.EncryptedPrivateKeyInfo;
40 import javax.crypto.NoSuchPaddingException;
41 import javax.crypto.SecretKey;
42 import javax.crypto.SecretKeyFactory;
43 import javax.crypto.spec.PBEKeySpec;
44 import javax.net.ssl.SSLContext;
45 import javax.net.ssl.SSLEngine;
46 import javax.net.ssl.SSLException;
47 import javax.net.ssl.SSLSessionContext;
48 import javax.net.ssl.TrustManager;
49 import javax.net.ssl.TrustManagerFactory;
50
51 import java.io.File;
52 import java.io.IOException;
53 import java.io.InputStream;
54 import java.security.AlgorithmParameters;
55 import java.security.InvalidAlgorithmParameterException;
56 import java.security.InvalidKeyException;
57 import java.security.KeyException;
58 import java.security.KeyFactory;
59 import java.security.KeyStore;
60 import java.security.KeyStoreException;
61 import java.security.NoSuchAlgorithmException;
62 import java.security.PrivateKey;
63 import java.security.SecureRandom;
64 import java.security.UnrecoverableKeyException;
65 import java.security.cert.CertificateException;
66 import java.security.cert.CertificateFactory;
67 import java.security.cert.X509Certificate;
68 import java.security.spec.InvalidKeySpecException;
69 import java.security.spec.PKCS8EncodedKeySpec;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.concurrent.Executor;
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(provider.toString());
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(), null);
812 } catch (Exception e) {
813 if (e instanceof SSLException) {
814 throw (SSLException) e;
815 }
816 throw new SSLException("failed to initialize the client-side SSL context", e);
817 }
818 }
819
820 static SslContext newClientContextInternal(
821 SslProvider provider,
822 Provider sslContextProvider,
823 X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory,
824 X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
825 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols,
826 long sessionCacheSize, long sessionTimeout, boolean enableOcsp,
827 SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm,
828 Map.Entry<SslContextOption<?>, Object>... options) throws SSLException {
829 if (provider == null) {
830 provider = defaultClientProvider();
831 }
832
833 ResumptionController resumptionController = new ResumptionController();
834
835 switch (provider) {
836 case JDK:
837 if (enableOcsp) {
838 throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
839 }
840 return new JdkSslClientContext(sslContextProvider,
841 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
842 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize,
843 sessionTimeout, secureRandom, keyStoreType, endpointIdentificationAlgorithm,
844 resumptionController);
845 case OPENSSL:
846 verifyNullSslContextProvider(provider, sslContextProvider);
847 OpenSsl.ensureAvailability();
848 return new OpenSslClientContext(
849 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
850 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
851 enableOcsp, keyStoreType, endpointIdentificationAlgorithm, resumptionController, options);
852 case OPENSSL_REFCNT:
853 verifyNullSslContextProvider(provider, sslContextProvider);
854 OpenSsl.ensureAvailability();
855 return new ReferenceCountedOpenSslClientContext(
856 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
857 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
858 enableOcsp, keyStoreType, endpointIdentificationAlgorithm, resumptionController, options);
859 default:
860 throw new Error(provider.toString());
861 }
862 }
863
864 static ApplicationProtocolConfig toApplicationProtocolConfig(Iterable<String> nextProtocols) {
865 ApplicationProtocolConfig apn;
866 if (nextProtocols == null) {
867 apn = ApplicationProtocolConfig.DISABLED;
868 } else {
869 apn = new ApplicationProtocolConfig(
870 Protocol.NPN_AND_ALPN, SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL,
871 SelectedListenerFailureBehavior.ACCEPT, nextProtocols);
872 }
873 return apn;
874 }
875
876
877
878
879 protected SslContext() {
880 this(false);
881 }
882
883
884
885
886 protected SslContext(boolean startTls) {
887 this(startTls, null);
888 }
889
890 SslContext(boolean startTls, ResumptionController resumptionController) {
891 this.startTls = startTls;
892 this.resumptionController = resumptionController;
893 }
894
895
896
897
898 public final AttributeMap attributes() {
899 return attributes;
900 }
901
902
903
904
905 public final boolean isServer() {
906 return !isClient();
907 }
908
909
910
911
912 public abstract boolean isClient();
913
914
915
916
917 public abstract List<String> cipherSuites();
918
919
920
921
922 public long sessionCacheSize() {
923 return sessionContext().getSessionCacheSize();
924 }
925
926
927
928
929 public long sessionTimeout() {
930 return sessionContext().getSessionTimeout();
931 }
932
933
934
935
936 @Deprecated
937 public final List<String> nextProtocols() {
938 return applicationProtocolNegotiator().protocols();
939 }
940
941
942
943
944 public abstract ApplicationProtocolNegotiator applicationProtocolNegotiator();
945
946
947
948
949
950
951
952 public abstract SSLEngine newEngine(ByteBufAllocator alloc);
953
954
955
956
957
958
959
960
961
962
963
964 public abstract SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort);
965
966
967
968
969 public abstract SSLSessionContext sessionContext();
970
971
972
973
974
975 public final SslHandler newHandler(ByteBufAllocator alloc) {
976 return newHandler(alloc, startTls);
977 }
978
979
980
981
982
983 protected SslHandler newHandler(ByteBufAllocator alloc, boolean startTls) {
984 return new SslHandler(newEngine(alloc), startTls, ImmediateExecutor.INSTANCE, resumptionController);
985 }
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012 public SslHandler newHandler(ByteBufAllocator alloc, Executor delegatedTaskExecutor) {
1013 return newHandler(alloc, startTls, delegatedTaskExecutor);
1014 }
1015
1016
1017
1018
1019
1020 protected SslHandler newHandler(ByteBufAllocator alloc, boolean startTls, Executor executor) {
1021 return new SslHandler(newEngine(alloc), startTls, executor, resumptionController);
1022 }
1023
1024
1025
1026
1027
1028
1029 public final SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort) {
1030 return newHandler(alloc, peerHost, peerPort, startTls);
1031 }
1032
1033
1034
1035
1036
1037 protected SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, boolean startTls) {
1038 return new SslHandler(newEngine(alloc, peerHost, peerPort), startTls, ImmediateExecutor.INSTANCE,
1039 resumptionController);
1040 }
1041
1042
1043
1044
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 public SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort,
1071 Executor delegatedTaskExecutor) {
1072 return newHandler(alloc, peerHost, peerPort, startTls, delegatedTaskExecutor);
1073 }
1074
1075 protected SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, boolean startTls,
1076 Executor delegatedTaskExecutor) {
1077 return new SslHandler(newEngine(alloc, peerHost, peerPort), startTls, delegatedTaskExecutor,
1078 resumptionController);
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097 @Deprecated
1098 protected static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key)
1099 throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
1100 InvalidKeyException, InvalidAlgorithmParameterException {
1101
1102 if (password == null) {
1103 return new PKCS8EncodedKeySpec(key);
1104 }
1105
1106 EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(key);
1107 String pbeAlgorithm = getPBEAlgorithm(encryptedPrivateKeyInfo);
1108 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(pbeAlgorithm);
1109 PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
1110 SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
1111
1112 Cipher cipher = Cipher.getInstance(pbeAlgorithm);
1113 cipher.init(Cipher.DECRYPT_MODE, pbeKey, encryptedPrivateKeyInfo.getAlgParameters());
1114
1115 return encryptedPrivateKeyInfo.getKeySpec(cipher);
1116 }
1117
1118 private static String getPBEAlgorithm(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) {
1119 AlgorithmParameters parameters = encryptedPrivateKeyInfo.getAlgParameters();
1120 String algName = encryptedPrivateKeyInfo.getAlgName();
1121
1122
1123 if (PlatformDependent.javaVersion() >= 8 && parameters != null &&
1124 (OID_PKCS5_PBES2.equals(algName) || PBES2.equals(algName))) {
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135 return parameters.toString();
1136 }
1137 return encryptedPrivateKeyInfo.getAlgName();
1138 }
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150 protected static KeyStore buildKeyStore(X509Certificate[] certChain, PrivateKey key,
1151 char[] keyPasswordChars, String keyStoreType)
1152 throws KeyStoreException, NoSuchAlgorithmException,
1153 CertificateException, IOException {
1154 if (keyStoreType == null) {
1155 keyStoreType = KeyStore.getDefaultType();
1156 }
1157 KeyStore ks = KeyStore.getInstance(keyStoreType);
1158 ks.load(null, null);
1159 ks.setKeyEntry(ALIAS, key, keyPasswordChars, certChain);
1160 return ks;
1161 }
1162
1163 protected static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException,
1164 NoSuchPaddingException, InvalidKeySpecException,
1165 InvalidAlgorithmParameterException,
1166 KeyException, IOException {
1167 return toPrivateKey(keyFile, keyPassword, true);
1168 }
1169
1170 static PrivateKey toPrivateKey(File keyFile, String keyPassword, boolean tryBouncyCastle)
1171 throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
1172 InvalidAlgorithmParameterException,
1173 KeyException, IOException {
1174 if (keyFile == null) {
1175 return null;
1176 }
1177
1178
1179 if (tryBouncyCastle && BouncyCastleUtil.isBcPkixAvailable()) {
1180 PrivateKey pk = BouncyCastlePemReader.getPrivateKey(keyFile, keyPassword);
1181 if (pk != null) {
1182 return pk;
1183 }
1184 }
1185
1186 return getPrivateKeyFromByteBuffer(PemReader.readPrivateKey(keyFile), keyPassword);
1187 }
1188
1189 protected static PrivateKey toPrivateKey(InputStream keyInputStream, String keyPassword)
1190 throws NoSuchAlgorithmException,
1191 NoSuchPaddingException, InvalidKeySpecException,
1192 InvalidAlgorithmParameterException,
1193 KeyException, IOException {
1194 if (keyInputStream == null) {
1195 return null;
1196 }
1197
1198
1199 if (BouncyCastleUtil.isBcPkixAvailable()) {
1200 if (!keyInputStream.markSupported()) {
1201
1202 keyInputStream = new BufferedInputStream(keyInputStream);
1203 }
1204 keyInputStream.mark(1048576);
1205 PrivateKey pk = BouncyCastlePemReader.getPrivateKey(keyInputStream, keyPassword);
1206 if (pk != null) {
1207 return pk;
1208 }
1209
1210 keyInputStream.reset();
1211 }
1212
1213 return getPrivateKeyFromByteBuffer(PemReader.readPrivateKey(keyInputStream), keyPassword);
1214 }
1215
1216 private static PrivateKey getPrivateKeyFromByteBuffer(ByteBuf encodedKeyBuf, String keyPassword)
1217 throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
1218 InvalidAlgorithmParameterException, KeyException, IOException {
1219
1220 byte[] encodedKey = new byte[encodedKeyBuf.readableBytes()];
1221 encodedKeyBuf.readBytes(encodedKey).release();
1222
1223 PKCS8EncodedKeySpec encodedKeySpec = generateKeySpec(
1224 keyPassword == null ? null : keyPassword.toCharArray(), encodedKey);
1225 try {
1226 return KeyFactory.getInstance("RSA").generatePrivate(encodedKeySpec);
1227 } catch (InvalidKeySpecException ignore) {
1228 try {
1229 return KeyFactory.getInstance("DSA").generatePrivate(encodedKeySpec);
1230 } catch (InvalidKeySpecException ignore2) {
1231 try {
1232 return KeyFactory.getInstance("EC").generatePrivate(encodedKeySpec);
1233 } catch (InvalidKeySpecException e) {
1234 throw new InvalidKeySpecException("Neither RSA, DSA nor EC worked", e);
1235 }
1236 }
1237 }
1238 }
1239
1240
1241
1242
1243
1244
1245
1246 @Deprecated
1247 protected static TrustManagerFactory buildTrustManagerFactory(
1248 File certChainFile, TrustManagerFactory trustManagerFactory)
1249 throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
1250 return buildTrustManagerFactory(certChainFile, trustManagerFactory, null);
1251 }
1252
1253
1254
1255
1256
1257
1258
1259
1260 protected static TrustManagerFactory buildTrustManagerFactory(
1261 File certChainFile, TrustManagerFactory trustManagerFactory, String keyType)
1262 throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
1263 X509Certificate[] x509Certs = toX509Certificates(certChainFile);
1264
1265 return buildTrustManagerFactory(x509Certs, trustManagerFactory, keyType);
1266 }
1267
1268 protected static X509Certificate[] toX509Certificates(File file) throws CertificateException {
1269 if (file == null) {
1270 return null;
1271 }
1272 return getCertificatesFromBuffers(PemReader.readCertificates(file));
1273 }
1274
1275 protected static X509Certificate[] toX509Certificates(InputStream in) throws CertificateException {
1276 if (in == null) {
1277 return null;
1278 }
1279 return getCertificatesFromBuffers(PemReader.readCertificates(in));
1280 }
1281
1282 private static X509Certificate[] getCertificatesFromBuffers(ByteBuf[] certs) throws CertificateException {
1283 CertificateFactory cf = CertificateFactory.getInstance("X.509");
1284 X509Certificate[] x509Certs = new X509Certificate[certs.length];
1285
1286 try {
1287 for (int i = 0; i < certs.length; i++) {
1288 InputStream is = new ByteBufInputStream(certs[i], false);
1289 try {
1290 x509Certs[i] = (X509Certificate) cf.generateCertificate(is);
1291 } finally {
1292 try {
1293 is.close();
1294 } catch (IOException e) {
1295
1296 throw new RuntimeException(e);
1297 }
1298 }
1299 }
1300 } finally {
1301 for (ByteBuf buf: certs) {
1302 buf.release();
1303 }
1304 }
1305 return x509Certs;
1306 }
1307
1308 protected static TrustManagerFactory buildTrustManagerFactory(
1309 X509Certificate[] certCollection, TrustManagerFactory trustManagerFactory, String keyStoreType)
1310 throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
1311 if (keyStoreType == null) {
1312 keyStoreType = KeyStore.getDefaultType();
1313 }
1314 final KeyStore ks = KeyStore.getInstance(keyStoreType);
1315 ks.load(null, null);
1316
1317 int i = 1;
1318 for (X509Certificate cert: certCollection) {
1319 String alias = Integer.toString(i);
1320 ks.setCertificateEntry(alias, cert);
1321 i++;
1322 }
1323
1324
1325 if (trustManagerFactory == null) {
1326 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
1327 }
1328 trustManagerFactory.init(ks);
1329
1330 return trustManagerFactory;
1331 }
1332
1333 static PrivateKey toPrivateKeyInternal(File keyFile, String keyPassword) throws SSLException {
1334 try {
1335 return toPrivateKey(keyFile, keyPassword);
1336 } catch (Exception e) {
1337 throw new SSLException(e);
1338 }
1339 }
1340
1341 static X509Certificate[] toX509CertificatesInternal(File file) throws SSLException {
1342 try {
1343 return toX509Certificates(file);
1344 } catch (CertificateException e) {
1345 throw new SSLException(e);
1346 }
1347 }
1348
1349 protected static KeyManagerFactory buildKeyManagerFactory(X509Certificate[] certChainFile,
1350 String keyAlgorithm, PrivateKey key,
1351 String keyPassword, KeyManagerFactory kmf,
1352 String keyStore)
1353 throws KeyStoreException, NoSuchAlgorithmException, IOException,
1354 CertificateException, UnrecoverableKeyException {
1355 if (keyAlgorithm == null) {
1356 keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
1357 }
1358 char[] keyPasswordChars = keyStorePassword(keyPassword);
1359 KeyStore ks = buildKeyStore(certChainFile, key, keyPasswordChars, keyStore);
1360 return buildKeyManagerFactory(ks, keyAlgorithm, keyPasswordChars, kmf);
1361 }
1362
1363 static KeyManagerFactory buildKeyManagerFactory(KeyStore ks,
1364 String keyAlgorithm,
1365 char[] keyPasswordChars, KeyManagerFactory kmf)
1366 throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
1367
1368 if (kmf == null) {
1369 if (keyAlgorithm == null) {
1370 keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
1371 }
1372 kmf = KeyManagerFactory.getInstance(keyAlgorithm);
1373 }
1374 kmf.init(ks, keyPasswordChars);
1375
1376 return kmf;
1377 }
1378
1379 static char[] keyStorePassword(String keyPassword) {
1380 return keyPassword == null ? EmptyArrays.EMPTY_CHARS : keyPassword.toCharArray();
1381 }
1382 }