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