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