From 1d128c7a6594e1ffd986fee9723c4305082e23cf Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Wed, 10 Aug 2016 08:55:30 +0200 Subject: [PATCH] Switch to netty-tcnative 2.0.0 which uses different package names Motivation: Previous versions of netty-tcnative used the org.apache.tomcat namespace which could lead to problems when a user tried to use tomcat and netty in the same app. Modifications: Use netty-tcnative which now uses a different namespace and adjust code to some API changes. Result: Its now possible to use netty-tcnative even when running together with tomcat. --- .../java/io/netty/handler/ssl/OpenSsl.java | 98 +++++-------------- .../ssl/OpenSslCertificateException.java | 2 +- .../handler/ssl/OpenSslClientContext.java | 2 +- .../ssl/OpenSslKeyMaterialManager.java | 4 +- .../handler/ssl/OpenSslServerContext.java | 2 +- .../ssl/OpenSslServerSessionContext.java | 4 +- .../handler/ssl/OpenSslSessionContext.java | 23 ++++- .../handler/ssl/OpenSslSessionStats.java | 2 +- .../handler/ssl/OpenSslSessionTicketKey.java | 2 +- .../ReferenceCountedOpenSslClientContext.java | 6 +- .../ssl/ReferenceCountedOpenSslContext.java | 19 +--- .../ssl/ReferenceCountedOpenSslEngine.java | 4 +- .../ReferenceCountedOpenSslServerContext.java | 4 +- pom.xml | 2 +- 14 files changed, 64 insertions(+), 110 deletions(-) diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java index 3b8c8237ea..bda9548123 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java @@ -24,23 +24,16 @@ import io.netty.util.internal.NativeLibraryLoader; import io.netty.util.internal.SystemPropertyUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; -import org.apache.tomcat.Apr; -import org.apache.tomcat.jni.Buffer; -import org.apache.tomcat.jni.Library; -import org.apache.tomcat.jni.Pool; -import org.apache.tomcat.jni.SSL; -import org.apache.tomcat.jni.SSLContext; +import io.netty.tcnative.jni.Buffer; +import io.netty.tcnative.jni.Library; +import io.netty.tcnative.jni.SSL; +import io.netty.tcnative.jni.SSLContext; -import java.io.IOException; -import java.io.InputStream; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Locale; -import java.util.Properties; import java.util.Set; /** @@ -75,7 +68,7 @@ public final class OpenSsl { // Test if netty-tcnative is in the classpath first. try { - Class.forName("org.apache.tomcat.jni.SSL", false, OpenSsl.class.getClassLoader()); + Class.forName("io.netty.tcnative.jni.SSL", false, OpenSsl.class.getClassLoader()); } catch (ClassNotFoundException t) { cause = t; logger.debug( @@ -115,21 +108,14 @@ public final class OpenSsl { } } - if (cause == null && !isNettyTcnative()) { - logger.debug("incompatible tcnative in the classpath; " - + OpenSslEngine.class.getSimpleName() + " will be unavailable."); - cause = new ClassNotFoundException("incompatible tcnative in the classpath"); - } - UNAVAILABILITY_CAUSE = cause; if (cause == null) { final Set availableOpenSslCipherSuites = new LinkedHashSet(128); boolean supportsKeyManagerFactory = false; boolean useKeyManagerFactory = false; - final long aprPool = Pool.create(0); try { - final long sslCtx = SSLContext.make(aprPool, SSL.SSL_PROTOCOL_ALL, SSL.SSL_MODE_SERVER); + final long sslCtx = SSLContext.make(SSL.SSL_PROTOCOL_ALL, SSL.SSL_MODE_SERVER); long privateKeyBio = 0; long certBio = 0; try { @@ -173,8 +159,6 @@ public final class OpenSsl { } } catch (Exception e) { logger.warn("Failed to get the list of available OpenSSL cipher suites.", e); - } finally { - Pool.destroy(aprPool); } AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.unmodifiableSet(availableOpenSslCipherSuites); @@ -199,30 +183,25 @@ public final class OpenSsl { SUPPORTS_KEYMANAGER_FACTORY = supportsKeyManagerFactory; USE_KEYMANAGER_FACTORY = useKeyManagerFactory; - final long pool = Pool.create(0); - Set protocols = new LinkedHashSet(6); // Seems like there is no way to explicitly disable SSLv2Hello in openssl so it is always enabled protocols.add(PROTOCOL_SSL_V2_HELLO); - try { - if (doesSupportProtocol(pool, SSL.SSL_PROTOCOL_SSLV2)) { - protocols.add(PROTOCOL_SSL_V2); - } - if (doesSupportProtocol(pool, SSL.SSL_PROTOCOL_SSLV3)) { - protocols.add(PROTOCOL_SSL_V3); - } - if (doesSupportProtocol(pool, SSL.SSL_PROTOCOL_TLSV1)) { - protocols.add(PROTOCOL_TLS_V1); - } - if (doesSupportProtocol(pool, SSL.SSL_PROTOCOL_TLSV1_1)) { - protocols.add(PROTOCOL_TLS_V1_1); - } - if (doesSupportProtocol(pool, SSL.SSL_PROTOCOL_TLSV1_2)) { - protocols.add(PROTOCOL_TLS_V1_2); - } - } finally { - Pool.destroy(aprPool); + if (doesSupportProtocol(SSL.SSL_PROTOCOL_SSLV2)) { + protocols.add(PROTOCOL_SSL_V2); } + if (doesSupportProtocol(SSL.SSL_PROTOCOL_SSLV3)) { + protocols.add(PROTOCOL_SSL_V3); + } + if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1)) { + protocols.add(PROTOCOL_TLS_V1); + } + if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_1)) { + protocols.add(PROTOCOL_TLS_V1_1); + } + if (doesSupportProtocol(SSL.SSL_PROTOCOL_TLSV1_2)) { + protocols.add(PROTOCOL_TLS_V1_2); + } + SUPPORTED_PROTOCOLS_SET = Collections.unmodifiableSet(protocols); } else { AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.emptySet(); @@ -234,10 +213,10 @@ public final class OpenSsl { } } - private static boolean doesSupportProtocol(long aprPool, int protocol) { + private static boolean doesSupportProtocol(int protocol) { long sslCtx = -1; try { - sslCtx = SSLContext.make(aprPool, protocol, SSL.SSL_MODE_COMBINED); + sslCtx = SSLContext.make(protocol, SSL.SSL_MODE_COMBINED); return true; } catch (Exception ignore) { return false; @@ -248,32 +227,6 @@ public final class OpenSsl { } } - private static boolean isNettyTcnative() { - return AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - InputStream is = null; - try { - is = Apr.class.getResourceAsStream("/org/apache/tomcat/apr.properties"); - Properties props = new Properties(); - props.load(is); - String info = props.getProperty("tcn.info"); - return info != null && info.startsWith("netty-tcnative"); - } catch (Throwable ignore) { - return false; - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException ignore) { - // ignore - } - } - } - } - }); - } - /** * Returns {@code true} if and only if * {@code netty-tcnative} and its OpenSSL support @@ -413,9 +366,8 @@ public final class OpenSsl { libNames.toArray(new String[libNames.size()])); } - private static void initializeTcNative() throws Exception { - Library.initialize("provided"); - SSL.initialize(null); + private static boolean initializeTcNative() throws Exception { + return Library.initialize(); } private static String normalizeOs(String value) { diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java index 5d9bce0f0d..b0e945b422 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java @@ -15,7 +15,7 @@ */ package io.netty.handler.ssl; -import org.apache.tomcat.jni.CertificateVerifier; +import io.netty.tcnative.jni.CertificateVerifier; import java.security.cert.CertificateException; diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java index bbbbbee512..972de2a117 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java @@ -15,7 +15,7 @@ */ package io.netty.handler.ssl; -import org.apache.tomcat.jni.SSL; +import io.netty.tcnative.jni.SSL; import java.io.File; import java.security.PrivateKey; diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java index 95a38fd14b..7ed4913a43 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java @@ -16,8 +16,8 @@ package io.netty.handler.ssl; import io.netty.buffer.ByteBufAllocator; -import org.apache.tomcat.jni.CertificateRequestedCallback; -import org.apache.tomcat.jni.SSL; +import io.netty.tcnative.jni.CertificateRequestedCallback; +import io.netty.tcnative.jni.SSL; import javax.net.ssl.SSLException; import javax.net.ssl.X509KeyManager; diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java index a65e07dc2a..1dd614c290 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java @@ -16,7 +16,7 @@ package io.netty.handler.ssl; import io.netty.handler.ssl.ReferenceCountedOpenSslServerContext.ServerContext; -import org.apache.tomcat.jni.SSL; +import io.netty.tcnative.jni.SSL; import java.io.File; import java.security.PrivateKey; diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java index c6687f6668..12d7f6aef4 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java @@ -15,8 +15,8 @@ */ package io.netty.handler.ssl; -import org.apache.tomcat.jni.SSL; -import org.apache.tomcat.jni.SSLContext; +import io.netty.tcnative.jni.SSL; +import io.netty.tcnative.jni.SSLContext; /** diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java index df13d6ab4c..3b67b77386 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java @@ -16,12 +16,13 @@ package io.netty.handler.ssl; import io.netty.util.internal.ObjectUtil; -import org.apache.tomcat.jni.SSL; -import org.apache.tomcat.jni.SSLContext; -import org.apache.tomcat.jni.SessionTicketKey; +import io.netty.tcnative.jni.SSL; +import io.netty.tcnative.jni.SSLContext; +import io.netty.tcnative.jni.SessionTicketKey; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; +import java.util.Arrays; import java.util.Enumeration; import java.util.NoSuchElementException; @@ -62,9 +63,21 @@ public abstract class OpenSslSessionContext implements SSLSessionContext { */ @Deprecated public void setTicketKeys(byte[] keys) { - ObjectUtil.checkNotNull(keys, "keys"); + if (keys.length % SessionTicketKey.TICKET_KEY_SIZE != 0) { + throw new IllegalArgumentException("keys.length % " + SessionTicketKey.TICKET_KEY_SIZE + " != 0"); + } + SessionTicketKey[] tickets = new SessionTicketKey[keys.length / SessionTicketKey.TICKET_KEY_SIZE]; + for (int i = 0, a = 0; i < tickets.length; i++) { + byte[] name = Arrays.copyOfRange(keys, a, SessionTicketKey.NAME_SIZE); + a += SessionTicketKey.NAME_SIZE; + byte[] hmacKey = Arrays.copyOfRange(keys, a, SessionTicketKey.HMAC_KEY_SIZE); + i += SessionTicketKey.HMAC_KEY_SIZE; + byte[] aesKey = Arrays.copyOfRange(keys, a, SessionTicketKey.AES_KEY_SIZE); + a += SessionTicketKey.AES_KEY_SIZE; + tickets[i] = new SessionTicketKey(name, hmacKey, aesKey); + } SSLContext.clearOptions(context.ctx, SSL.SSL_OP_NO_TICKET); - SSLContext.setSessionTicketKeys(context.ctx, keys); + SSLContext.setSessionTicketKeys(context.ctx, tickets); } /** diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java index ff93a04b81..29fa07daa6 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java @@ -16,7 +16,7 @@ package io.netty.handler.ssl; -import org.apache.tomcat.jni.SSLContext; +import io.netty.tcnative.jni.SSLContext; /** * Stats exposed by an OpenSSL session context. diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java index f3af8204be..f05faaff55 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java @@ -15,7 +15,7 @@ */ package io.netty.handler.ssl; -import org.apache.tomcat.jni.SessionTicketKey; +import io.netty.tcnative.jni.SessionTicketKey; /** * Session Ticket Key diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java index 97cd3e3956..06c80eabb4 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java @@ -17,9 +17,9 @@ package io.netty.handler.ssl; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; -import org.apache.tomcat.jni.CertificateRequestedCallback; -import org.apache.tomcat.jni.SSL; -import org.apache.tomcat.jni.SSLContext; +import io.netty.tcnative.jni.CertificateRequestedCallback; +import io.netty.tcnative.jni.SSL; +import io.netty.tcnative.jni.SSLContext; import java.security.KeyStore; import java.security.PrivateKey; diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java index 9a3d1855e9..3b7bca0cb9 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java @@ -27,10 +27,9 @@ import io.netty.util.internal.StringUtil; import io.netty.util.internal.SystemPropertyUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; -import org.apache.tomcat.jni.CertificateVerifier; -import org.apache.tomcat.jni.Pool; -import org.apache.tomcat.jni.SSL; -import org.apache.tomcat.jni.SSLContext; +import io.netty.tcnative.jni.CertificateVerifier; +import io.netty.tcnative.jni.SSL; +import io.netty.tcnative.jni.SSLContext; import java.security.AccessController; import java.security.PrivateKey; @@ -98,7 +97,6 @@ public abstract class ReferenceCountedOpenSslContext extends SslContext implemen * The OpenSSL SSL_CTX object */ protected volatile long ctx; - long aprPool; @SuppressWarnings({ "unused", "FieldMayBeFinal" }) private volatile int aprPoolDestroyed; private final List unmodifiableCiphers; @@ -250,15 +248,12 @@ public abstract class ReferenceCountedOpenSslContext extends SslContext implemen this.apn = checkNotNull(apn, "apn"); - // Allocate a new APR pool. - aprPool = Pool.create(0); - // Create a new SSL_CTX and configure it. boolean success = false; try { synchronized (ReferenceCountedOpenSslContext.class) { try { - ctx = SSLContext.make(aprPool, SSL.SSL_PROTOCOL_ALL, mode); + ctx = SSLContext.make(SSL.SSL_PROTOCOL_ALL, mode); } catch (Exception e) { throw new SSLException("failed to create an SSL_CTX", e); } @@ -466,12 +461,6 @@ public abstract class ReferenceCountedOpenSslContext extends SslContext implemen SSLContext.free(ctx); ctx = 0; } - - // Guard against multiple destroyPools() calls triggered by construction exception and finalize() later - if (aprPool != 0) { - Pool.destroy(aprPool); - aprPool = 0; - } } } diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java index 1178a55083..8125770b5f 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java @@ -29,8 +29,8 @@ import io.netty.util.internal.StringUtil; import io.netty.util.internal.ThrowableUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; -import org.apache.tomcat.jni.Buffer; -import org.apache.tomcat.jni.SSL; +import io.netty.tcnative.jni.Buffer; +import io.netty.tcnative.jni.SSL; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java index beb85cfdf9..08454ecc7b 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java @@ -15,8 +15,8 @@ */ package io.netty.handler.ssl; -import org.apache.tomcat.jni.SSL; -import org.apache.tomcat.jni.SSLContext; +import io.netty.tcnative.jni.SSL; +import io.netty.tcnative.jni.SSLContext; import java.security.KeyStore; import java.security.PrivateKey; diff --git a/pom.xml b/pom.xml index f4a46592be..e77a574f8c 100644 --- a/pom.xml +++ b/pom.xml @@ -244,7 +244,7 @@ fedora netty-tcnative - 1.1.33.Fork26 + 2.0.0.Beta1 ${os.detected.classifier} ${os.detected.name}-${os.detected.arch} ${project.basedir}/../common/src/test/resources/logback-test.xml