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.UnpooledByteBufAllocator;
22 import io.netty.internal.tcnative.Buffer;
23 import io.netty.internal.tcnative.Library;
24 import io.netty.internal.tcnative.SSL;
25 import io.netty.internal.tcnative.SSLContext;
26 import io.netty.util.CharsetUtil;
27 import io.netty.util.ReferenceCountUtil;
28 import io.netty.util.ReferenceCounted;
29 import io.netty.util.internal.EmptyArrays;
30 import io.netty.util.internal.NativeLibraryLoader;
31 import io.netty.util.internal.PlatformDependent;
32 import io.netty.util.internal.StringUtil;
33 import io.netty.util.internal.SystemPropertyUtil;
34 import io.netty.util.internal.logging.InternalLogger;
35 import io.netty.util.internal.logging.InternalLoggerFactory;
36
37 import java.io.ByteArrayInputStream;
38 import java.security.cert.CertificateException;
39 import java.security.cert.X509Certificate;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.Collections;
44 import java.util.HashSet;
45 import java.util.LinkedHashSet;
46 import java.util.List;
47 import java.util.Set;
48
49 import static io.netty.handler.ssl.SslUtils.*;
50
51
52
53
54
55 public final class OpenSsl {
56
57 private static final InternalLogger logger = InternalLoggerFactory.getInstance(OpenSsl.class);
58 private static final Throwable UNAVAILABILITY_CAUSE;
59 static final List<String> DEFAULT_CIPHERS;
60 static final Set<String> AVAILABLE_CIPHER_SUITES;
61 private static final Set<String> AVAILABLE_OPENSSL_CIPHER_SUITES;
62 private static final Set<String> AVAILABLE_JAVA_CIPHER_SUITES;
63 private static final boolean SUPPORTS_KEYMANAGER_FACTORY;
64 private static final boolean USE_KEYMANAGER_FACTORY;
65 private static final boolean SUPPORTS_OCSP;
66 private static final boolean TLSV13_SUPPORTED;
67 private static final boolean IS_BORINGSSL;
68 private static final Set<String> CLIENT_DEFAULT_PROTOCOLS;
69 private static final Set<String> SERVER_DEFAULT_PROTOCOLS;
70 static final Set<String> SUPPORTED_PROTOCOLS_SET;
71 static final String[] EXTRA_SUPPORTED_TLS_1_3_CIPHERS;
72 static final String EXTRA_SUPPORTED_TLS_1_3_CIPHERS_STRING;
73 static final String[] NAMED_GROUPS;
74
75 static final boolean JAVAX_CERTIFICATE_CREATION_SUPPORTED;
76
77
78
79
80 private static final String[] DEFAULT_NAMED_GROUPS = { "x25519", "secp256r1", "secp384r1", "secp521r1" };
81
82 static {
83 Throwable cause = null;
84
85 if (SystemPropertyUtil.getBoolean("io.netty.handler.ssl.noOpenSsl", false)) {
86 cause = new UnsupportedOperationException(
87 "OpenSSL was explicit disabled with -Dio.netty.handler.ssl.noOpenSsl=true");
88
89 logger.debug(
90 "netty-tcnative explicit disabled; " +
91 OpenSslEngine.class.getSimpleName() + " will be unavailable.", cause);
92 } else {
93
94 try {
95 Class.forName("io.netty.internal.tcnative.SSLContext", false,
96 PlatformDependent.getClassLoader(OpenSsl.class));
97 } catch (ClassNotFoundException t) {
98 cause = t;
99 logger.debug(
100 "netty-tcnative not in the classpath; " +
101 OpenSslEngine.class.getSimpleName() + " will be unavailable.");
102 }
103
104
105 if (cause == null) {
106 try {
107
108 loadTcNative();
109 } catch (Throwable t) {
110 cause = t;
111 logger.debug(
112 "Failed to load netty-tcnative; " +
113 OpenSslEngine.class.getSimpleName() + " will be unavailable, unless the " +
114 "application has already loaded the symbols by some other means. " +
115 "See https://netty.io/wiki/forked-tomcat-native.html for more information.", t);
116 }
117
118 try {
119 String engine = SystemPropertyUtil.get("io.netty.handler.ssl.openssl.engine", null);
120 if (engine == null) {
121 logger.debug("Initialize netty-tcnative using engine: 'default'");
122 } else {
123 logger.debug("Initialize netty-tcnative using engine: '{}'", engine);
124 }
125 initializeTcNative(engine);
126
127
128
129
130 cause = null;
131 } catch (Throwable t) {
132 if (cause == null) {
133 cause = t;
134 }
135 logger.debug(
136 "Failed to initialize netty-tcnative; " +
137 OpenSslEngine.class.getSimpleName() + " will be unavailable. " +
138 "See https://netty.io/wiki/forked-tomcat-native.html for more information.", t);
139 }
140 }
141 }
142
143 UNAVAILABILITY_CAUSE = cause;
144 CLIENT_DEFAULT_PROTOCOLS = defaultProtocols("jdk.tls.client.protocols");
145 SERVER_DEFAULT_PROTOCOLS = defaultProtocols("jdk.tls.server.protocols");
146
147 if (cause == null) {
148 logger.debug("netty-tcnative using native library: {}", SSL.versionString());
149
150 final List<String> defaultCiphers = new ArrayList<String>();
151 final Set<String> availableOpenSslCipherSuites = new LinkedHashSet<String>(128);
152 boolean supportsKeyManagerFactory = false;
153 boolean useKeyManagerFactory = false;
154 boolean tlsv13Supported = false;
155 String[] namedGroups = DEFAULT_NAMED_GROUPS;
156 String[] defaultConvertedNamedGroups = new String[namedGroups.length];
157 for (int i = 0; i < namedGroups.length; i++) {
158 defaultConvertedNamedGroups[i] = GroupsConverter.toOpenSsl(namedGroups[i]);
159 }
160
161 IS_BORINGSSL = "BoringSSL".equals(versionString());
162 if (IS_BORINGSSL) {
163 EXTRA_SUPPORTED_TLS_1_3_CIPHERS = new String [] { "TLS_AES_128_GCM_SHA256",
164 "TLS_AES_256_GCM_SHA384" ,
165 "TLS_CHACHA20_POLY1305_SHA256" };
166
167 StringBuilder ciphersBuilder = new StringBuilder(128);
168 for (String cipher: EXTRA_SUPPORTED_TLS_1_3_CIPHERS) {
169 ciphersBuilder.append(cipher).append(":");
170 }
171 ciphersBuilder.setLength(ciphersBuilder.length() - 1);
172 EXTRA_SUPPORTED_TLS_1_3_CIPHERS_STRING = ciphersBuilder.toString();
173 } else {
174 EXTRA_SUPPORTED_TLS_1_3_CIPHERS = EmptyArrays.EMPTY_STRINGS;
175 EXTRA_SUPPORTED_TLS_1_3_CIPHERS_STRING = StringUtil.EMPTY_STRING;
176 }
177
178 try {
179 final long sslCtx = SSLContext.make(SSL.SSL_PROTOCOL_ALL, SSL.SSL_MODE_SERVER);
180 long certBio = 0;
181 long keyBio = 0;
182 long cert = 0;
183 long key = 0;
184 try {
185
186
187 if (SslProvider.isTlsv13Supported(SslProvider.JDK)) {
188 try {
189 StringBuilder tlsv13Ciphers = new StringBuilder();
190
191 for (String cipher : TLSV13_CIPHERS) {
192 String converted = CipherSuiteConverter.toOpenSsl(cipher, IS_BORINGSSL);
193 if (converted != null) {
194 tlsv13Ciphers.append(converted).append(':');
195 }
196 }
197 if (tlsv13Ciphers.length() == 0) {
198 tlsv13Supported = false;
199 } else {
200 tlsv13Ciphers.setLength(tlsv13Ciphers.length() - 1);
201 SSLContext.setCipherSuite(sslCtx, tlsv13Ciphers.toString(), true);
202 tlsv13Supported = true;
203 }
204
205 } catch (Exception ignore) {
206 tlsv13Supported = false;
207 }
208 }
209
210 SSLContext.setCipherSuite(sslCtx, "ALL", false);
211
212 final long ssl = SSL.newSSL(sslCtx, true);
213 try {
214 for (String c: SSL.getCiphers(ssl)) {
215
216 if (c == null || c.isEmpty() || availableOpenSslCipherSuites.contains(c) ||
217
218 !tlsv13Supported && isTLSv13Cipher(c)) {
219 continue;
220 }
221 availableOpenSslCipherSuites.add(c);
222 }
223 if (IS_BORINGSSL) {
224
225
226 Collections.addAll(availableOpenSslCipherSuites, EXTRA_SUPPORTED_TLS_1_3_CIPHERS);
227 Collections.addAll(availableOpenSslCipherSuites,
228 "AEAD-AES128-GCM-SHA256",
229 "AEAD-AES256-GCM-SHA384",
230 "AEAD-CHACHA20-POLY1305-SHA256");
231 }
232
233 PemEncoded privateKey = PemPrivateKey.valueOf(PROBING_KEY.getBytes(CharsetUtil.US_ASCII));
234 try {
235
236
237 SSLContext.setCertificateCallback(sslCtx, null);
238
239 X509Certificate certificate = selfSignedCertificate();
240 certBio = ReferenceCountedOpenSslContext.toBIO(ByteBufAllocator.DEFAULT, certificate);
241 cert = SSL.parseX509Chain(certBio);
242
243 keyBio = ReferenceCountedOpenSslContext.toBIO(
244 UnpooledByteBufAllocator.DEFAULT, privateKey.retain());
245 key = SSL.parsePrivateKey(keyBio, null);
246
247 SSL.setKeyMaterial(ssl, cert, key);
248 supportsKeyManagerFactory = true;
249 try {
250 boolean propertySet = SystemPropertyUtil.contains(
251 "io.netty.handler.ssl.openssl.useKeyManagerFactory");
252 if (!IS_BORINGSSL) {
253 useKeyManagerFactory = SystemPropertyUtil.getBoolean(
254 "io.netty.handler.ssl.openssl.useKeyManagerFactory", true);
255
256 if (propertySet) {
257 logger.info("System property " +
258 "'io.netty.handler.ssl.openssl.useKeyManagerFactory'" +
259 " is deprecated and so will be ignored in the future");
260 }
261 } else {
262 useKeyManagerFactory = true;
263 if (propertySet) {
264 logger.info("System property " +
265 "'io.netty.handler.ssl.openssl.useKeyManagerFactory'" +
266 " is deprecated and will be ignored when using BoringSSL");
267 }
268 }
269 } catch (Throwable ignore) {
270 logger.debug("Failed to get useKeyManagerFactory system property.");
271 }
272 } catch (Error ignore) {
273 logger.debug("KeyManagerFactory not supported.");
274 } finally {
275 privateKey.release();
276 }
277 } finally {
278 SSL.freeSSL(ssl);
279 if (certBio != 0) {
280 SSL.freeBIO(certBio);
281 }
282 if (keyBio != 0) {
283 SSL.freeBIO(keyBio);
284 }
285 if (cert != 0) {
286 SSL.freeX509Chain(cert);
287 }
288 if (key != 0) {
289 SSL.freePrivateKey(key);
290 }
291 }
292
293 String groups = SystemPropertyUtil.get("jdk.tls.namedGroups", null);
294 if (groups != null) {
295 String[] nGroups = groups.split(",");
296 Set<String> supportedNamedGroups = new LinkedHashSet<String>(nGroups.length);
297 Set<String> supportedConvertedNamedGroups = new LinkedHashSet<String>(nGroups.length);
298
299 Set<String> unsupportedNamedGroups = new LinkedHashSet<String>();
300 for (String namedGroup : nGroups) {
301 String converted = GroupsConverter.toOpenSsl(namedGroup);
302 if (SSLContext.setCurvesList(sslCtx, converted)) {
303 supportedConvertedNamedGroups.add(converted);
304 supportedNamedGroups.add(namedGroup);
305 } else {
306 unsupportedNamedGroups.add(namedGroup);
307 }
308 }
309
310 if (supportedNamedGroups.isEmpty()) {
311 namedGroups = defaultConvertedNamedGroups;
312 logger.info("All configured namedGroups are not supported: {}. Use default: {}.",
313 Arrays.toString(unsupportedNamedGroups.toArray(EmptyArrays.EMPTY_STRINGS)),
314 Arrays.toString(DEFAULT_NAMED_GROUPS));
315 } else {
316 String[] groupArray = supportedNamedGroups.toArray(EmptyArrays.EMPTY_STRINGS);
317 if (unsupportedNamedGroups.isEmpty()) {
318 logger.info("Using configured namedGroups -D 'jdk.tls.namedGroup': {} ",
319 Arrays.toString(groupArray));
320 } else {
321 logger.info("Using supported configured namedGroups: {}. Unsupported namedGroups: {}. ",
322 Arrays.toString(groupArray),
323 Arrays.toString(unsupportedNamedGroups.toArray(EmptyArrays.EMPTY_STRINGS)));
324 }
325 namedGroups = supportedConvertedNamedGroups.toArray(EmptyArrays.EMPTY_STRINGS);
326 }
327 } else {
328 namedGroups = defaultConvertedNamedGroups;
329 }
330 } finally {
331 SSLContext.free(sslCtx);
332 }
333 } catch (Exception e) {
334 logger.warn("Failed to get the list of available OpenSSL cipher suites.", e);
335 }
336 NAMED_GROUPS = namedGroups;
337 AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.unmodifiableSet(availableOpenSslCipherSuites);
338 final Set<String> availableJavaCipherSuites = new LinkedHashSet<String>(
339 AVAILABLE_OPENSSL_CIPHER_SUITES.size() * 2);
340 for (String cipher: AVAILABLE_OPENSSL_CIPHER_SUITES) {
341
342 if (!isTLSv13Cipher(cipher)) {
343 availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "TLS"));
344 availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "SSL"));
345 } else {
346
347 availableJavaCipherSuites.add(cipher);
348 }
349 }
350
351 addIfSupported(availableJavaCipherSuites, defaultCiphers, DEFAULT_CIPHER_SUITES);
352 addIfSupported(availableJavaCipherSuites, defaultCiphers, TLSV13_CIPHER_SUITES);
353
354 addIfSupported(availableJavaCipherSuites, defaultCiphers, EXTRA_SUPPORTED_TLS_1_3_CIPHERS);
355
356 useFallbackCiphersIfDefaultIsEmpty(defaultCiphers, availableJavaCipherSuites);
357 DEFAULT_CIPHERS = Collections.unmodifiableList(defaultCiphers);
358
359 AVAILABLE_JAVA_CIPHER_SUITES = Collections.unmodifiableSet(availableJavaCipherSuites);
360
361 final Set<String> availableCipherSuites = new LinkedHashSet<String>(
362 AVAILABLE_OPENSSL_CIPHER_SUITES.size() + AVAILABLE_JAVA_CIPHER_SUITES.size());
363 availableCipherSuites.addAll(AVAILABLE_OPENSSL_CIPHER_SUITES);
364 availableCipherSuites.addAll(AVAILABLE_JAVA_CIPHER_SUITES);
365
366 AVAILABLE_CIPHER_SUITES = availableCipherSuites;
367 SUPPORTS_KEYMANAGER_FACTORY = supportsKeyManagerFactory;
368 USE_KEYMANAGER_FACTORY = useKeyManagerFactory;
369
370 Set<String> protocols = new LinkedHashSet<String>(6);
371
372 protocols.add(SslProtocols.SSL_v2_HELLO);
373 if (doesSupportProtocol(SSL.SSL_PROTOCOL_SSLV2, SSL.SSL_OP_NO_SSLv2)) {
374 protocols.add(SslProtocols.SSL_v2);
375 }
376 if (doesSupportProtocol(SSL.SSL_PROTOCOL_SSLV3, SSL.SSL_OP_NO_SSLv3)) {
377 protocols.add(SslProtocols.SSL_v3);
378 }
379 if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1, SSL.SSL_OP_NO_TLSv1)) {
380 protocols.add(SslProtocols.TLS_v1);
381 }
382 if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_1, SSL.SSL_OP_NO_TLSv1_1)) {
383 protocols.add(SslProtocols.TLS_v1_1);
384 }
385 if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_2, SSL.SSL_OP_NO_TLSv1_2)) {
386 protocols.add(SslProtocols.TLS_v1_2);
387 }
388
389
390 if (tlsv13Supported && doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_3, SSL.SSL_OP_NO_TLSv1_3)) {
391 protocols.add(SslProtocols.TLS_v1_3);
392 TLSV13_SUPPORTED = true;
393 } else {
394 TLSV13_SUPPORTED = false;
395 }
396
397 SUPPORTED_PROTOCOLS_SET = Collections.unmodifiableSet(protocols);
398 SUPPORTS_OCSP = doesSupportOcsp();
399
400 if (logger.isDebugEnabled()) {
401 logger.debug("Supported protocols (OpenSSL): {} ", SUPPORTED_PROTOCOLS_SET);
402 logger.debug("Default cipher suites (OpenSSL): {}", DEFAULT_CIPHERS);
403 }
404
405
406
407
408 boolean javaxCertificateCreationSupported;
409 try {
410 javax.security.cert.X509Certificate.getInstance(PROBING_CERT.getBytes(CharsetUtil.US_ASCII));
411 javaxCertificateCreationSupported = true;
412 } catch (javax.security.cert.CertificateException ex) {
413 javaxCertificateCreationSupported = false;
414 }
415 JAVAX_CERTIFICATE_CREATION_SUPPORTED = javaxCertificateCreationSupported;
416 } else {
417 DEFAULT_CIPHERS = Collections.emptyList();
418 AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.emptySet();
419 AVAILABLE_JAVA_CIPHER_SUITES = Collections.emptySet();
420 AVAILABLE_CIPHER_SUITES = Collections.emptySet();
421 SUPPORTS_KEYMANAGER_FACTORY = false;
422 USE_KEYMANAGER_FACTORY = false;
423 SUPPORTED_PROTOCOLS_SET = Collections.emptySet();
424 SUPPORTS_OCSP = false;
425 TLSV13_SUPPORTED = false;
426 IS_BORINGSSL = false;
427 EXTRA_SUPPORTED_TLS_1_3_CIPHERS = EmptyArrays.EMPTY_STRINGS;
428 EXTRA_SUPPORTED_TLS_1_3_CIPHERS_STRING = StringUtil.EMPTY_STRING;
429 NAMED_GROUPS = DEFAULT_NAMED_GROUPS;
430 JAVAX_CERTIFICATE_CREATION_SUPPORTED = false;
431 }
432 }
433
434 static String checkTls13Ciphers(InternalLogger logger, String ciphers) {
435 if (IS_BORINGSSL && !ciphers.isEmpty()) {
436 assert EXTRA_SUPPORTED_TLS_1_3_CIPHERS.length > 0;
437 Set<String> boringsslTlsv13Ciphers = new HashSet<String>(EXTRA_SUPPORTED_TLS_1_3_CIPHERS.length);
438 Collections.addAll(boringsslTlsv13Ciphers, EXTRA_SUPPORTED_TLS_1_3_CIPHERS);
439 boolean ciphersNotMatch = false;
440 for (String cipher: ciphers.split(":")) {
441 if (boringsslTlsv13Ciphers.isEmpty()) {
442 ciphersNotMatch = true;
443 break;
444 }
445 if (!boringsslTlsv13Ciphers.remove(cipher) &&
446 !boringsslTlsv13Ciphers.remove(CipherSuiteConverter.toJava(cipher, "TLS"))) {
447 ciphersNotMatch = true;
448 break;
449 }
450 }
451
452
453 ciphersNotMatch |= !boringsslTlsv13Ciphers.isEmpty();
454
455 if (ciphersNotMatch) {
456 if (logger.isInfoEnabled()) {
457 StringBuilder javaCiphers = new StringBuilder(128);
458 for (String cipher : ciphers.split(":")) {
459 javaCiphers.append(CipherSuiteConverter.toJava(cipher, "TLS")).append(":");
460 }
461 javaCiphers.setLength(javaCiphers.length() - 1);
462 logger.info(
463 "BoringSSL doesn't allow to enable or disable TLSv1.3 ciphers explicitly." +
464 " Provided TLSv1.3 ciphers: '{}', default TLSv1.3 ciphers that will be used: '{}'.",
465 javaCiphers, EXTRA_SUPPORTED_TLS_1_3_CIPHERS_STRING);
466 }
467 return EXTRA_SUPPORTED_TLS_1_3_CIPHERS_STRING;
468 }
469 }
470 return ciphers;
471 }
472
473 static boolean isSessionCacheSupported() {
474 return version() >= 0x10100000L;
475 }
476
477
478
479
480 static X509Certificate selfSignedCertificate() throws CertificateException {
481 return (X509Certificate) SslContext.X509_CERT_FACTORY.generateCertificate(
482 new ByteArrayInputStream(PROBING_CERT.getBytes(CharsetUtil.US_ASCII))
483 );
484 }
485
486 private static boolean doesSupportOcsp() {
487 boolean supportsOcsp = false;
488 if (version() >= 0x10002000L) {
489 long sslCtx = -1;
490 try {
491 sslCtx = SSLContext.make(SSL.SSL_PROTOCOL_TLSV1_2, SSL.SSL_MODE_SERVER);
492 SSLContext.enableOcsp(sslCtx, false);
493 supportsOcsp = true;
494 } catch (Exception ignore) {
495
496 } finally {
497 if (sslCtx != -1) {
498 SSLContext.free(sslCtx);
499 }
500 }
501 }
502 return supportsOcsp;
503 }
504 private static boolean doesSupportProtocol(int protocol, int opt) {
505 if (opt == 0) {
506
507 return false;
508 }
509 long sslCtx = -1;
510 try {
511 sslCtx = SSLContext.make(protocol, SSL.SSL_MODE_COMBINED);
512 return true;
513 } catch (Exception ignore) {
514 return false;
515 } finally {
516 if (sslCtx != -1) {
517 SSLContext.free(sslCtx);
518 }
519 }
520 }
521
522
523
524
525
526
527 public static boolean isAvailable() {
528 return UNAVAILABILITY_CAUSE == null;
529 }
530
531
532
533
534
535
536
537 @Deprecated
538 public static boolean isAlpnSupported() {
539 return version() >= 0x10002000L;
540 }
541
542
543
544
545 public static boolean isOcspSupported() {
546 return SUPPORTS_OCSP;
547 }
548
549
550
551
552
553 public static int version() {
554 return isAvailable() ? SSL.version() : -1;
555 }
556
557
558
559
560
561 public static String versionString() {
562 return isAvailable() ? SSL.versionString() : null;
563 }
564
565
566
567
568
569
570
571 public static void ensureAvailability() {
572 if (UNAVAILABILITY_CAUSE != null) {
573 throw (Error) new UnsatisfiedLinkError(
574 "failed to load the required native library").initCause(UNAVAILABILITY_CAUSE);
575 }
576 }
577
578
579
580
581
582
583
584 public static Throwable unavailabilityCause() {
585 return UNAVAILABILITY_CAUSE;
586 }
587
588
589
590
591 @Deprecated
592 public static Set<String> availableCipherSuites() {
593 return availableOpenSslCipherSuites();
594 }
595
596
597
598
599
600 public static Set<String> availableOpenSslCipherSuites() {
601 return AVAILABLE_OPENSSL_CIPHER_SUITES;
602 }
603
604
605
606
607
608 public static Set<String> availableJavaCipherSuites() {
609 return AVAILABLE_JAVA_CIPHER_SUITES;
610 }
611
612
613
614
615
616 public static boolean isCipherSuiteAvailable(String cipherSuite) {
617 String converted = CipherSuiteConverter.toOpenSsl(cipherSuite, IS_BORINGSSL);
618 if (converted != null) {
619 cipherSuite = converted;
620 }
621 return AVAILABLE_OPENSSL_CIPHER_SUITES.contains(cipherSuite);
622 }
623
624
625
626
627 public static boolean supportsKeyManagerFactory() {
628 return SUPPORTS_KEYMANAGER_FACTORY;
629 }
630
631
632
633
634
635
636
637 @Deprecated
638 public static boolean supportsHostnameValidation() {
639 return isAvailable();
640 }
641
642 static boolean useKeyManagerFactory() {
643 return USE_KEYMANAGER_FACTORY;
644 }
645
646 static long memoryAddress(ByteBuf buf) {
647 assert buf.isDirect();
648 return buf.hasMemoryAddress() ? buf.memoryAddress() :
649
650 Buffer.address(buf.internalNioBuffer(0, buf.readableBytes()));
651 }
652
653 private OpenSsl() { }
654
655 private static void loadTcNative() throws Exception {
656 String os = PlatformDependent.normalizedOs();
657 String arch = PlatformDependent.normalizedArch();
658
659 Set<String> libNames = new LinkedHashSet<String>(5);
660 String staticLibName = "netty_tcnative";
661
662
663
664 if ("linux".equals(os)) {
665 Set<String> classifiers = PlatformDependent.normalizedLinuxClassifiers();
666 for (String classifier : classifiers) {
667 libNames.add(staticLibName + "_" + os + '_' + arch + "_" + classifier);
668 }
669
670 libNames.add(staticLibName + "_" + os + '_' + arch);
671
672
673
674
675 libNames.add(staticLibName + "_" + os + '_' + arch + "_fedora");
676 } else {
677 libNames.add(staticLibName + "_" + os + '_' + arch);
678 }
679 libNames.add(staticLibName + "_" + arch);
680 libNames.add(staticLibName);
681
682 NativeLibraryLoader.loadFirstAvailable(PlatformDependent.getClassLoader(SSLContext.class),
683 libNames.toArray(EmptyArrays.EMPTY_STRINGS));
684 }
685
686 private static boolean initializeTcNative(String engine) throws Exception {
687 return Library.initialize("provided", engine);
688 }
689
690 static void releaseIfNeeded(ReferenceCounted counted) {
691 if (counted.refCnt() > 0) {
692 ReferenceCountUtil.safeRelease(counted);
693 }
694 }
695
696 static boolean isTlsv13Supported() {
697 return TLSV13_SUPPORTED;
698 }
699
700 static boolean isOptionSupported(SslContextOption<?> option) {
701 if (isAvailable()) {
702 if (option == OpenSslContextOption.USE_TASKS) {
703 return true;
704 }
705
706 if (isBoringSSL()) {
707 return option == OpenSslContextOption.ASYNC_PRIVATE_KEY_METHOD ||
708 option == OpenSslContextOption.PRIVATE_KEY_METHOD ||
709 option == OpenSslContextOption.CERTIFICATE_COMPRESSION_ALGORITHMS ||
710 option == OpenSslContextOption.TLS_FALSE_START ||
711 option == OpenSslContextOption.MAX_CERTIFICATE_LIST_BYTES;
712 }
713 }
714 return false;
715 }
716
717 private static Set<String> defaultProtocols(String property) {
718 String protocolsString = SystemPropertyUtil.get(property, null);
719 Set<String> protocols = new HashSet<String>();
720 if (protocolsString != null) {
721 for (String proto : protocolsString.split(",")) {
722 String p = proto.trim();
723 protocols.add(p);
724 }
725 } else {
726 protocols.add(SslProtocols.TLS_v1_2);
727 protocols.add(SslProtocols.TLS_v1_3);
728 }
729 return protocols;
730 }
731
732 static String[] defaultProtocols(boolean isClient) {
733 final Collection<String> defaultProtocols = isClient ? CLIENT_DEFAULT_PROTOCOLS : SERVER_DEFAULT_PROTOCOLS;
734 assert defaultProtocols != null;
735 List<String> protocols = new ArrayList<String>(defaultProtocols.size());
736 for (String proto : defaultProtocols) {
737 if (SUPPORTED_PROTOCOLS_SET.contains(proto)) {
738 protocols.add(proto);
739 }
740 }
741 return protocols.toArray(EmptyArrays.EMPTY_STRINGS);
742 }
743
744 static boolean isBoringSSL() {
745 return IS_BORINGSSL;
746 }
747 }