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