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