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.io.File;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.security.AlgorithmParameters;
36 import java.security.InvalidAlgorithmParameterException;
37 import java.security.InvalidKeyException;
38 import java.security.KeyException;
39 import java.security.KeyFactory;
40 import java.security.KeyStore;
41 import java.security.KeyStoreException;
42 import java.security.NoSuchAlgorithmException;
43 import java.security.PrivateKey;
44 import java.security.Provider;
45 import java.security.SecureRandom;
46 import java.security.UnrecoverableKeyException;
47 import java.security.cert.CertificateException;
48 import java.security.cert.CertificateFactory;
49 import java.security.cert.X509Certificate;
50 import java.security.spec.InvalidKeySpecException;
51 import java.security.spec.PKCS8EncodedKeySpec;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.concurrent.Executor;
55 import javax.crypto.Cipher;
56 import javax.crypto.EncryptedPrivateKeyInfo;
57 import javax.crypto.NoSuchPaddingException;
58 import javax.crypto.SecretKey;
59 import javax.crypto.SecretKeyFactory;
60 import javax.crypto.spec.PBEKeySpec;
61 import javax.net.ssl.KeyManager;
62 import javax.net.ssl.KeyManagerFactory;
63 import javax.net.ssl.SSLContext;
64 import javax.net.ssl.SSLEngine;
65 import javax.net.ssl.SSLException;
66 import javax.net.ssl.SSLSessionContext;
67 import javax.net.ssl.TrustManager;
68 import javax.net.ssl.TrustManagerFactory;
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public abstract class SslContext {
93 static final String ALIAS = "key";
94
95 static final CertificateFactory X509_CERT_FACTORY;
96 static {
97 try {
98 X509_CERT_FACTORY = CertificateFactory.getInstance("X.509");
99 } catch (CertificateException e) {
100 throw new IllegalStateException("unable to instance X.509 CertificateFactory", e);
101 }
102 }
103
104 private final boolean startTls;
105 private final AttributeMap attributes = new DefaultAttributeMap();
106 private static final String OID_PKCS5_PBES2 = "1.2.840.113549.1.5.13";
107 private static final String PBES2 = "PBES2";
108
109
110
111
112
113
114 public static SslProvider defaultServerProvider() {
115 return defaultProvider();
116 }
117
118
119
120
121
122
123 public static SslProvider defaultClientProvider() {
124 return defaultProvider();
125 }
126
127 private static SslProvider defaultProvider() {
128 if (OpenSsl.isAvailable()) {
129 return SslProvider.OPENSSL;
130 } else {
131 return SslProvider.JDK;
132 }
133 }
134
135
136
137
138
139
140
141
142
143 @Deprecated
144 public static SslContext newServerContext(File certChainFile, File keyFile) throws SSLException {
145 return newServerContext(certChainFile, keyFile, null);
146 }
147
148
149
150
151
152
153
154
155
156
157
158 @Deprecated
159 public static SslContext newServerContext(
160 File certChainFile, File keyFile, String keyPassword) throws SSLException {
161 return newServerContext(null, certChainFile, keyFile, keyPassword);
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 @Deprecated
183 public static SslContext newServerContext(
184 File certChainFile, File keyFile, String keyPassword,
185 Iterable<String> ciphers, Iterable<String> nextProtocols,
186 long sessionCacheSize, long sessionTimeout) throws SSLException {
187
188 return newServerContext(
189 null, certChainFile, keyFile, keyPassword,
190 ciphers, nextProtocols, sessionCacheSize, sessionTimeout);
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 @Deprecated
212 public static SslContext newServerContext(
213 File certChainFile, File keyFile, String keyPassword,
214 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
215 long sessionCacheSize, long sessionTimeout) throws SSLException {
216 return newServerContext(
217 null, certChainFile, keyFile, keyPassword,
218 ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
219 }
220
221
222
223
224
225
226
227
228
229
230
231 @Deprecated
232 public static SslContext newServerContext(
233 SslProvider provider, File certChainFile, File keyFile) throws SSLException {
234 return newServerContext(provider, certChainFile, keyFile, null);
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248
249 @Deprecated
250 public static SslContext newServerContext(
251 SslProvider provider, File certChainFile, File keyFile, String keyPassword) throws SSLException {
252 return newServerContext(provider, certChainFile, keyFile, keyPassword, null, IdentityCipherSuiteFilter.INSTANCE,
253 null, 0, 0);
254 }
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276 @Deprecated
277 public static SslContext newServerContext(
278 SslProvider provider,
279 File certChainFile, File keyFile, String keyPassword,
280 Iterable<String> ciphers, Iterable<String> nextProtocols,
281 long sessionCacheSize, long sessionTimeout) throws SSLException {
282 return newServerContext(provider, certChainFile, keyFile, keyPassword,
283 ciphers, IdentityCipherSuiteFilter.INSTANCE,
284 toApplicationProtocolConfig(nextProtocols), sessionCacheSize, sessionTimeout);
285 }
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 @Deprecated
311 public static SslContext newServerContext(
312 SslProvider provider,
313 File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory,
314 Iterable<String> ciphers, Iterable<String> nextProtocols,
315 long sessionCacheSize, long sessionTimeout) throws SSLException {
316
317 return newServerContext(
318 provider, null, trustManagerFactory, certChainFile, keyFile, keyPassword,
319 null, ciphers, IdentityCipherSuiteFilter.INSTANCE,
320 toApplicationProtocolConfig(nextProtocols), sessionCacheSize, sessionTimeout);
321 }
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344 @Deprecated
345 public static SslContext newServerContext(SslProvider provider,
346 File certChainFile, File keyFile, String keyPassword,
347 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
348 long sessionCacheSize, long sessionTimeout) throws SSLException {
349 return newServerContext(provider, null, null, certChainFile, keyFile, keyPassword, null,
350 ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
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
384
385
386 @Deprecated
387 public static SslContext newServerContext(
388 SslProvider provider,
389 File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
390 File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
391 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
392 long sessionCacheSize, long sessionTimeout) throws SSLException {
393 return newServerContext(provider, trustCertCollectionFile, trustManagerFactory, keyCertChainFile,
394 keyFile, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn,
395 sessionCacheSize, sessionTimeout, KeyStore.getDefaultType());
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
429
430
431 static SslContext newServerContext(
432 SslProvider provider,
433 File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
434 File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
435 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
436 long sessionCacheSize, long sessionTimeout, String keyStore) throws SSLException {
437 try {
438 return newServerContextInternal(provider, null, toX509Certificates(trustCertCollectionFile),
439 trustManagerFactory, toX509Certificates(keyCertChainFile),
440 toPrivateKey(keyFile, keyPassword),
441 keyPassword, keyManagerFactory, ciphers, cipherFilter, apn,
442 sessionCacheSize, sessionTimeout, ClientAuth.NONE, null,
443 false, false, null, keyStore);
444 } catch (Exception e) {
445 if (e instanceof SSLException) {
446 throw (SSLException) e;
447 }
448 throw new SSLException("failed to initialize the server-side SSL context", e);
449 }
450 }
451
452 static SslContext newServerContextInternal(
453 SslProvider provider,
454 Provider sslContextProvider,
455 X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
456 X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
457 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
458 long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
459 boolean enableOcsp, SecureRandom secureRandom, String keyStoreType,
460 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, secureRandom, 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 null, KeyStore.getDefaultType(), "HTTPS");
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,
820 SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm,
821 Map.Entry<SslContextOption<?>, Object>... options) throws SSLException {
822 if (provider == null) {
823 provider = defaultClientProvider();
824 }
825 switch (provider) {
826 case JDK:
827 if (enableOcsp) {
828 throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
829 }
830 return new JdkSslClientContext(sslContextProvider,
831 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
832 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize,
833 sessionTimeout, secureRandom, keyStoreType, endpointIdentificationAlgorithm);
834 case OPENSSL:
835 verifyNullSslContextProvider(provider, sslContextProvider);
836 OpenSsl.ensureAvailability();
837 return new OpenSslClientContext(
838 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
839 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
840 enableOcsp, keyStoreType, endpointIdentificationAlgorithm, options);
841 case OPENSSL_REFCNT:
842 verifyNullSslContextProvider(provider, sslContextProvider);
843 OpenSsl.ensureAvailability();
844 return new ReferenceCountedOpenSslClientContext(
845 trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
846 keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, sessionTimeout,
847 enableOcsp, keyStoreType, endpointIdentificationAlgorithm, options);
848 default:
849 throw new Error(provider.toString());
850 }
851 }
852
853 static ApplicationProtocolConfig toApplicationProtocolConfig(Iterable<String> nextProtocols) {
854 ApplicationProtocolConfig apn;
855 if (nextProtocols == null) {
856 apn = ApplicationProtocolConfig.DISABLED;
857 } else {
858 apn = new ApplicationProtocolConfig(
859 Protocol.NPN_AND_ALPN, SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL,
860 SelectedListenerFailureBehavior.ACCEPT, nextProtocols);
861 }
862 return apn;
863 }
864
865
866
867
868 protected SslContext() {
869 this(false);
870 }
871
872
873
874
875 protected SslContext(boolean startTls) {
876 this.startTls = startTls;
877 }
878
879
880
881
882 public final AttributeMap attributes() {
883 return attributes;
884 }
885
886
887
888
889 public final boolean isServer() {
890 return !isClient();
891 }
892
893
894
895
896 public abstract boolean isClient();
897
898
899
900
901 public abstract List<String> cipherSuites();
902
903
904
905
906 public long sessionCacheSize() {
907 return sessionContext().getSessionCacheSize();
908 }
909
910
911
912
913 public long sessionTimeout() {
914 return sessionContext().getSessionTimeout();
915 }
916
917
918
919
920 @Deprecated
921 public final List<String> nextProtocols() {
922 return applicationProtocolNegotiator().protocols();
923 }
924
925
926
927
928 public abstract ApplicationProtocolNegotiator applicationProtocolNegotiator();
929
930
931
932
933
934
935
936 public abstract SSLEngine newEngine(ByteBufAllocator alloc);
937
938
939
940
941
942
943
944
945
946
947
948 public abstract SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort);
949
950
951
952
953 public abstract SSLSessionContext sessionContext();
954
955
956
957
958
959 public final SslHandler newHandler(ByteBufAllocator alloc) {
960 return newHandler(alloc, startTls);
961 }
962
963
964
965
966
967 protected SslHandler newHandler(ByteBufAllocator alloc, boolean startTls) {
968 return new SslHandler(newEngine(alloc), startTls);
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
996 public SslHandler newHandler(ByteBufAllocator alloc, Executor delegatedTaskExecutor) {
997 return newHandler(alloc, startTls, delegatedTaskExecutor);
998 }
999
1000
1001
1002
1003
1004 protected SslHandler newHandler(ByteBufAllocator alloc, boolean startTls, Executor executor) {
1005 return new SslHandler(newEngine(alloc), startTls, executor);
1006 }
1007
1008
1009
1010
1011
1012
1013 public final SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort) {
1014 return newHandler(alloc, peerHost, peerPort, startTls);
1015 }
1016
1017
1018
1019
1020
1021 protected SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, boolean startTls) {
1022 return new SslHandler(newEngine(alloc, peerHost, peerPort), startTls);
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
1053 public SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort,
1054 Executor delegatedTaskExecutor) {
1055 return newHandler(alloc, peerHost, peerPort, startTls, delegatedTaskExecutor);
1056 }
1057
1058 protected SslHandler newHandler(ByteBufAllocator alloc, String peerHost, int peerPort, boolean startTls,
1059 Executor delegatedTaskExecutor) {
1060 return new SslHandler(newEngine(alloc, peerHost, peerPort), startTls, delegatedTaskExecutor);
1061 }
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079 @Deprecated
1080 protected static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key)
1081 throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
1082 InvalidKeyException, InvalidAlgorithmParameterException {
1083
1084 if (password == null) {
1085 return new PKCS8EncodedKeySpec(key);
1086 }
1087
1088 EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(key);
1089 String pbeAlgorithm = getPBEAlgorithm(encryptedPrivateKeyInfo);
1090 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(pbeAlgorithm);
1091 PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
1092 SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
1093
1094 Cipher cipher = Cipher.getInstance(pbeAlgorithm);
1095 cipher.init(Cipher.DECRYPT_MODE, pbeKey, encryptedPrivateKeyInfo.getAlgParameters());
1096
1097 return encryptedPrivateKeyInfo.getKeySpec(cipher);
1098 }
1099
1100 private static String getPBEAlgorithm(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) {
1101 AlgorithmParameters parameters = encryptedPrivateKeyInfo.getAlgParameters();
1102 String algName = encryptedPrivateKeyInfo.getAlgName();
1103
1104
1105 if (parameters != null && (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 }