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