Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates-src > by-pkgid > a093f1508dd87e04da20c1f3045bfdba > files > 1

netty-4.0.42-1.mga6.src.rpm

From 8b7286b1c8cd740e85fc483c1be6fcc8ce478ec4 Mon Sep 17 00:00:00 2001
From: Severin Gehwolf <sgehwolf@redhat.com>
Date: Thu, 20 Oct 2016 15:54:52 +0200
Subject: [PATCH 1/2] Remove OpenSSL parts depending on tcnative.

---
 .../main/java/io/netty/handler/ssl/OpenSsl.java    |  479 -----
 .../handler/ssl/OpenSslCertificateException.java   |   80 -
 .../io/netty/handler/ssl/OpenSslClientContext.java |  210 ---
 .../java/io/netty/handler/ssl/OpenSslContext.java  |   57 -
 .../java/io/netty/handler/ssl/OpenSslEngine.java   |   42 -
 .../io/netty/handler/ssl/OpenSslEngineMap.java     |   35 -
 .../ssl/OpenSslExtendedKeyMaterialManager.java     |   40 -
 .../handler/ssl/OpenSslKeyMaterialManager.java     |  179 --
 .../io/netty/handler/ssl/OpenSslServerContext.java |  370 ----
 .../handler/ssl/OpenSslServerSessionContext.java   |   79 -
 .../netty/handler/ssl/OpenSslSessionContext.java   |  111 --
 .../io/netty/handler/ssl/OpenSslSessionStats.java  |  155 --
 .../netty/handler/ssl/OpenSslSessionTicketKey.java |   78 -
 .../ssl/ReferenceCountedOpenSslClientContext.java  |  300 ---
 .../ssl/ReferenceCountedOpenSslContext.java        |  751 --------
 .../handler/ssl/ReferenceCountedOpenSslEngine.java | 1936 --------------------
 .../ssl/ReferenceCountedOpenSslServerContext.java  |  195 --
 .../main/java/io/netty/handler/ssl/SslContext.java |   24 +-
 .../main/java/io/netty/handler/ssl/SslHandler.java |   38 +-
 .../handler/ssl/JdkOpenSslEngineInteroptTest.java  |   37 -
 .../handler/ssl/OpenSslClientContextTest.java      |   38 -
 .../io/netty/handler/ssl/OpenSslEngineTest.java    |  129 --
 .../ssl/OpenSslJdkSslEngineInteroptTest.java       |   38 -
 .../netty/handler/ssl/OpenSslRenegotiateTest.java  |   36 -
 .../handler/ssl/OpenSslServerContextTest.java      |   39 -
 .../java/io/netty/handler/ssl/PemEncodedTest.java  |   95 -
 .../ssl/ReferenceCountedOpenSslEngineTest.java     |   52 -
 .../java/io/netty/handler/ssl/SniClientTest.java   |   18 -
 .../netty/handler/ssl/SslContextBuilderTest.java   |   24 -
 .../java/io/netty/handler/ssl/SslHandlerTest.java  |   28 -
 30 files changed, 14 insertions(+), 5679 deletions(-)
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslExtendedKeyMaterialManager.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java
 delete mode 100644 handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/OpenSslClientContextTest.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/OpenSslRenegotiateTest.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/OpenSslServerContextTest.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/PemEncodedTest.java
 delete mode 100644 handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java

diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
deleted file mode 100644
index c77d6cd..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package io.netty.handler.ssl;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.handler.ssl.util.SelfSignedCertificate;
-import io.netty.util.ReferenceCountUtil;
-import io.netty.util.ReferenceCounted;
-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 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;
-
-/**
- * Tells if <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and its OpenSSL support
- * are available.
- */
-public final class OpenSsl {
-
-    private static final InternalLogger logger = InternalLoggerFactory.getInstance(OpenSsl.class);
-    private static final String LINUX = "linux";
-    private static final String UNKNOWN = "unknown";
-    private static final Throwable UNAVAILABILITY_CAUSE;
-
-    static final Set<String> AVAILABLE_CIPHER_SUITES;
-    private static final Set<String> AVAILABLE_OPENSSL_CIPHER_SUITES;
-    private static final Set<String> AVAILABLE_JAVA_CIPHER_SUITES;
-    private static final boolean SUPPORTS_KEYMANAGER_FACTORY;
-    private static final boolean USE_KEYMANAGER_FACTORY;
-
-    // Protocols
-    static final String PROTOCOL_SSL_V2_HELLO = "SSLv2Hello";
-    static final String PROTOCOL_SSL_V2 = "SSLv2";
-    static final String PROTOCOL_SSL_V3 = "SSLv3";
-    static final String PROTOCOL_TLS_V1 = "TLSv1";
-    static final String PROTOCOL_TLS_V1_1 = "TLSv1.1";
-    static final String PROTOCOL_TLS_V1_2 = "TLSv1.2";
-
-    private static final String[] SUPPORTED_PROTOCOLS = {
-            PROTOCOL_SSL_V2_HELLO,
-            PROTOCOL_SSL_V2,
-            PROTOCOL_SSL_V3,
-            PROTOCOL_TLS_V1,
-            PROTOCOL_TLS_V1_1,
-            PROTOCOL_TLS_V1_2
-    };
-    static final Set<String> SUPPORTED_PROTOCOLS_SET = Collections.unmodifiableSet(
-            new HashSet<String>(Arrays.asList(SUPPORTED_PROTOCOLS)));
-
-    static {
-        Throwable cause = null;
-
-        // Test if netty-tcnative is in the classpath first.
-        try {
-            Class.forName("org.apache.tomcat.jni.SSL", false, OpenSsl.class.getClassLoader());
-        } catch (ClassNotFoundException t) {
-            cause = t;
-            logger.debug(
-                    "netty-tcnative not in the classpath; " +
-                    OpenSslEngine.class.getSimpleName() + " will be unavailable.");
-        }
-
-        // If in the classpath, try to load the native library and initialize netty-tcnative.
-        if (cause == null) {
-            try {
-                // The JNI library was not already loaded. Load it now.
-                loadTcNative();
-            } catch (Throwable t) {
-                cause = t;
-                logger.debug(
-                    "Failed to load netty-tcnative; " +
-                        OpenSslEngine.class.getSimpleName() + " will be unavailable, unless the " +
-                        "application has already loaded the symbols by some other means. " +
-                        "See http://netty.io/wiki/forked-tomcat-native.html for more information.", t);
-            }
-
-            try {
-                initializeTcNative();
-
-                // The library was initialized successfully. If loading the library failed above,
-                // reset the cause now since it appears that the library was loaded by some other
-                // means.
-                cause = null;
-            } catch (Throwable t) {
-                if (cause == null) {
-                    cause = t;
-                }
-                logger.debug(
-                    "Failed to initialize netty-tcnative; " +
-                        OpenSslEngine.class.getSimpleName() + " will be unavailable. " +
-                        "See http://netty.io/wiki/forked-tomcat-native.html for more information.", t);
-            }
-        }
-
-        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<String> availableOpenSslCipherSuites = new LinkedHashSet<String>(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);
-                long privateKeyBio = 0;
-                long certBio = 0;
-                try {
-                    SSLContext.setOptions(sslCtx, SSL.SSL_OP_ALL);
-                    SSLContext.setCipherSuite(sslCtx, "ALL");
-                    final long ssl = SSL.newSSL(sslCtx, true);
-                    try {
-                        for (String c: SSL.getCiphers(ssl)) {
-                            // Filter out bad input.
-                            if (c == null || c.length() == 0 || availableOpenSslCipherSuites.contains(c)) {
-                                continue;
-                            }
-                            availableOpenSslCipherSuites.add(c);
-                        }
-                        try {
-                            SelfSignedCertificate cert = new SelfSignedCertificate();
-                            certBio = OpenSslContext.toBIO(cert.cert());
-                            SSL.setCertificateChainBio(ssl, certBio, false);
-                            supportsKeyManagerFactory = true;
-                            useKeyManagerFactory = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-                                @Override
-                                public Boolean run() {
-                                    return SystemPropertyUtil.getBoolean(
-                                            "io.netty.handler.ssl.openssl.useKeyManagerFactory", true);
-                                }
-                            });
-                        } catch (Throwable ignore) {
-                            logger.debug("KeyManagerFactory not supported.");
-                        }
-                    } finally {
-                        SSL.freeSSL(ssl);
-                        if (privateKeyBio != 0) {
-                            SSL.freeBIO(privateKeyBio);
-                        }
-                        if (certBio != 0) {
-                            SSL.freeBIO(certBio);
-                        }
-                    }
-                } finally {
-                    SSLContext.free(sslCtx);
-                }
-            } 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);
-
-            final Set<String> availableJavaCipherSuites = new LinkedHashSet<String>(
-                    AVAILABLE_OPENSSL_CIPHER_SUITES.size() * 2);
-            for (String cipher: AVAILABLE_OPENSSL_CIPHER_SUITES) {
-                // Included converted but also openssl cipher name
-                availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "TLS"));
-                availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "SSL"));
-            }
-            AVAILABLE_JAVA_CIPHER_SUITES = Collections.unmodifiableSet(availableJavaCipherSuites);
-
-            final Set<String> availableCipherSuites = new LinkedHashSet<String>(
-                    AVAILABLE_OPENSSL_CIPHER_SUITES.size() + AVAILABLE_JAVA_CIPHER_SUITES.size());
-            for (String cipher: AVAILABLE_OPENSSL_CIPHER_SUITES) {
-                availableCipherSuites.add(cipher);
-            }
-            for (String cipher: AVAILABLE_JAVA_CIPHER_SUITES) {
-                availableCipherSuites.add(cipher);
-            }
-            AVAILABLE_CIPHER_SUITES = availableCipherSuites;
-            SUPPORTS_KEYMANAGER_FACTORY = supportsKeyManagerFactory;
-            USE_KEYMANAGER_FACTORY = useKeyManagerFactory;
-        } else {
-            AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.emptySet();
-            AVAILABLE_JAVA_CIPHER_SUITES = Collections.emptySet();
-            AVAILABLE_CIPHER_SUITES = Collections.emptySet();
-            SUPPORTS_KEYMANAGER_FACTORY = false;
-            USE_KEYMANAGER_FACTORY = false;
-        }
-    }
-
-    private static boolean isNettyTcnative() {
-        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-            @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
-     * <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and its OpenSSL support
-     * are available.
-     */
-    public static boolean isAvailable() {
-        return UNAVAILABILITY_CAUSE == null;
-    }
-
-    /**
-     * Returns {@code true} if the used version of openssl supports
-     * <a href="https://tools.ietf.org/html/rfc7301">ALPN</a>.
-     */
-    public static boolean isAlpnSupported() {
-        return version() >= 0x10002000L;
-    }
-
-    /**
-     * Returns the version of the used available OpenSSL library or {@code -1} if {@link #isAvailable()}
-     * returns {@code false}.
-     */
-    public static int version() {
-        if (isAvailable()) {
-            return SSL.version();
-        }
-        return -1;
-    }
-
-    /**
-     * Returns the version string of the used available OpenSSL library or {@code null} if {@link #isAvailable()}
-     * returns {@code false}.
-     */
-    public static String versionString() {
-        if (isAvailable()) {
-            return SSL.versionString();
-        }
-        return null;
-    }
-
-    /**
-     * Ensure that <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and
-     * its OpenSSL support are available.
-     *
-     * @throws UnsatisfiedLinkError if unavailable
-     */
-    public static void ensureAvailability() {
-        if (UNAVAILABILITY_CAUSE != null) {
-            throw (Error) new UnsatisfiedLinkError(
-                    "failed to load the required native library").initCause(UNAVAILABILITY_CAUSE);
-        }
-    }
-
-    /**
-     * Returns the cause of unavailability of
-     * <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and its OpenSSL support.
-     *
-     * @return the cause if unavailable. {@code null} if available.
-     */
-    public static Throwable unavailabilityCause() {
-        return UNAVAILABILITY_CAUSE;
-    }
-
-    /**
-     * @deprecated use {@link #availableOpenSslCipherSuites()}
-     */
-    @Deprecated
-    public static Set<String> availableCipherSuites() {
-        return availableOpenSslCipherSuites();
-    }
-
-    /**
-     * Returns all the available OpenSSL cipher suites.
-     * Please note that the returned array may include the cipher suites that are insecure or non-functional.
-     */
-    public static Set<String> availableOpenSslCipherSuites() {
-        return AVAILABLE_OPENSSL_CIPHER_SUITES;
-    }
-
-    /**
-     * Returns all the available cipher suites (Java-style).
-     * Please note that the returned array may include the cipher suites that are insecure or non-functional.
-     */
-    public static Set<String> availableJavaCipherSuites() {
-        return AVAILABLE_JAVA_CIPHER_SUITES;
-    }
-
-    /**
-     * Returns {@code true} if and only if the specified cipher suite is available in OpenSSL.
-     * Both Java-style cipher suite and OpenSSL-style cipher suite are accepted.
-     */
-    public static boolean isCipherSuiteAvailable(String cipherSuite) {
-        String converted = CipherSuiteConverter.toOpenSsl(cipherSuite);
-        if (converted != null) {
-            cipherSuite = converted;
-        }
-        return AVAILABLE_OPENSSL_CIPHER_SUITES.contains(cipherSuite);
-    }
-
-    /**
-     * Returns {@code true} if {@link javax.net.ssl.KeyManagerFactory} is supported when using OpenSSL.
-     */
-    public static boolean supportsKeyManagerFactory() {
-        return SUPPORTS_KEYMANAGER_FACTORY;
-    }
-
-    static boolean useKeyManagerFactory() {
-        return USE_KEYMANAGER_FACTORY;
-    }
-
-    static boolean isError(long errorCode) {
-        return errorCode != SSL.SSL_ERROR_NONE;
-    }
-
-    static long memoryAddress(ByteBuf buf) {
-        assert buf.isDirect();
-        return buf.hasMemoryAddress() ? buf.memoryAddress() : Buffer.address(buf.nioBuffer());
-    }
-
-    private OpenSsl() { }
-
-    private static void loadTcNative() throws Exception {
-        String os = normalizeOs(SystemPropertyUtil.get("os.name", ""));
-        String arch = normalizeArch(SystemPropertyUtil.get("os.arch", ""));
-
-        Set<String> libNames = new LinkedHashSet<String>(3);
-        // First, try loading the platform-specific library. Platform-specific
-        // libraries will be available if using a tcnative uber jar.
-        libNames.add("netty-tcnative-" + os + '-' + arch);
-        if (LINUX.equalsIgnoreCase(os)) {
-            // Fedora SSL lib so naming (libssl.so.10 vs libssl.so.1.0.0)..
-            libNames.add("netty-tcnative-" + os + '-' + arch + "-fedora");
-        }
-        // finally the default library.
-        libNames.add("netty-tcnative");
-
-        NativeLibraryLoader.loadFirstAvailable(SSL.class.getClassLoader(),
-            libNames.toArray(new String[libNames.size()]));
-    }
-
-    private static void initializeTcNative() throws Exception {
-        Library.initialize("provided");
-        SSL.initialize(null);
-    }
-
-    private static String normalizeOs(String value) {
-        value = normalize(value);
-        if (value.startsWith("aix")) {
-            return "aix";
-        }
-        if (value.startsWith("hpux")) {
-            return "hpux";
-        }
-        if (value.startsWith("os400")) {
-            // Avoid the names such as os4000
-            if (value.length() <= 5 || !Character.isDigit(value.charAt(5))) {
-                return "os400";
-            }
-        }
-        if (value.startsWith(LINUX)) {
-            return LINUX;
-        }
-        if (value.startsWith("macosx") || value.startsWith("osx")) {
-            return "osx";
-        }
-        if (value.startsWith("freebsd")) {
-            return "freebsd";
-        }
-        if (value.startsWith("openbsd")) {
-            return "openbsd";
-        }
-        if (value.startsWith("netbsd")) {
-            return "netbsd";
-        }
-        if (value.startsWith("solaris") || value.startsWith("sunos")) {
-            return "sunos";
-        }
-        if (value.startsWith("windows")) {
-            return "windows";
-        }
-
-        return UNKNOWN;
-    }
-
-    private static String normalizeArch(String value) {
-        value = normalize(value);
-        if (value.matches("^(x8664|amd64|ia32e|em64t|x64)$")) {
-            return "x86_64";
-        }
-        if (value.matches("^(x8632|x86|i[3-6]86|ia32|x32)$")) {
-            return "x86_32";
-        }
-        if (value.matches("^(ia64|itanium64)$")) {
-            return "itanium_64";
-        }
-        if (value.matches("^(sparc|sparc32)$")) {
-            return "sparc_32";
-        }
-        if (value.matches("^(sparcv9|sparc64)$")) {
-            return "sparc_64";
-        }
-        if (value.matches("^(arm|arm32)$")) {
-            return "arm_32";
-        }
-        if ("aarch64".equals(value)) {
-            return "aarch_64";
-        }
-        if (value.matches("^(ppc|ppc32)$")) {
-            return "ppc_32";
-        }
-        if ("ppc64".equals(value)) {
-            return "ppc_64";
-        }
-        if ("ppc64le".equals(value)) {
-            return "ppcle_64";
-        }
-        if ("s390".equals(value)) {
-            return "s390_32";
-        }
-        if ("s390x".equals(value)) {
-            return "s390_64";
-        }
-
-        return UNKNOWN;
-    }
-
-    private static String normalize(String value) {
-        return value.toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", "");
-    }
-
-    static void releaseIfNeeded(ReferenceCounted counted) {
-        if (counted.refCnt() > 0) {
-            ReferenceCountUtil.safeRelease(counted);
-        }
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java
deleted file mode 100644
index 5d9bce0..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslCertificateException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.apache.tomcat.jni.CertificateVerifier;
-
-import java.security.cert.CertificateException;
-
-/**
- * A special {@link CertificateException} which allows to specify which error code is included in the
- * SSL Record. This only work when {@link SslProvider#OPENSSL} is used.
- */
-public final class OpenSslCertificateException extends CertificateException {
-    private static final long serialVersionUID = 5542675253797129798L;
-
-    private final int errorCode;
-
-    /**
-     * Construct a new exception with the
-     * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a>.
-     */
-    public OpenSslCertificateException(int errorCode) {
-        this((String) null, errorCode);
-    }
-
-    /**
-     * Construct a new exception with the msg and
-     * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a> .
-     */
-    public OpenSslCertificateException(String msg, int errorCode) {
-        super(msg);
-        this.errorCode = checkErrorCode(errorCode);
-    }
-
-    /**
-     * Construct a new exception with the msg, cause and
-     * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a> .
-     */
-    public OpenSslCertificateException(String message, Throwable cause, int errorCode) {
-        super(message, cause);
-        this.errorCode = checkErrorCode(errorCode);
-    }
-
-    /**
-     * Construct a new exception with the cause and
-     * <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a> .
-     */
-    public OpenSslCertificateException(Throwable cause, int errorCode) {
-        this(null, cause, errorCode);
-    }
-
-    /**
-     * Return the <a href="https://www.openssl.org/docs/manmaster/apps/verify.html">error code</a> to use.
-     */
-    public int errorCode() {
-        return errorCode;
-    }
-
-    private static int checkErrorCode(int errorCode) {
-        if (errorCode < CertificateVerifier.X509_V_OK || errorCode > CertificateVerifier.X509_V_ERR_DANE_NO_MATCH) {
-            throw new IllegalArgumentException("errorCode must be " + CertificateVerifier.X509_V_OK + " => "
-                    + CertificateVerifier.X509_V_ERR_DANE_NO_MATCH +
-                    ". See https://www.openssl.org/docs/manmaster/apps/verify.html .");
-        }
-        return errorCode;
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java
deleted file mode 100644
index bbbbbee..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslClientContext.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.apache.tomcat.jni.SSL;
-
-import java.io.File;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-import static io.netty.handler.ssl.ReferenceCountedOpenSslClientContext.newSessionContext;
-
-/**
- * A client-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation.
- * <p>This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers
- * and manually release the native memory see {@link ReferenceCountedOpenSslClientContext}.
- */
-public final class OpenSslClientContext extends OpenSslContext {
-    private final OpenSslSessionContext sessionContext;
-
-    /**
-     * Creates a new instance.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslClientContext() throws SSLException {
-        this((File) null, null, null, null, null, null, null, IdentityCipherSuiteFilter.INSTANCE, null, 0, 0);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format.
-     *                      {@code null} to use the system default
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslClientContext(File certChainFile) throws SSLException {
-        this(certChainFile, null);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
-     *                            that verifies the certificates sent from servers.
-     *                            {@code null} to use the default.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslClientContext(TrustManagerFactory trustManagerFactory) throws SSLException {
-        this(null, trustManagerFactory);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format.
-     *                      {@code null} to use the system default
-     * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
-     *                            that verifies the certificates sent from servers.
-     *                            {@code null} to use the default.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException {
-        this(certChainFile, trustManagerFactory, null, null, null, null, null,
-             IdentityCipherSuiteFilter.INSTANCE, null, 0, 0);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
-     *                            that verifies the certificates sent from servers.
-     *                            {@code null} to use the default..
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param apn Provides a means to configure parameters related to application protocol negotiation.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory, Iterable<String> ciphers,
-                                ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout)
-            throws SSLException {
-        this(certChainFile, trustManagerFactory, null, null, null, null, ciphers, IdentityCipherSuiteFilter.INSTANCE,
-                apn, sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
-     *                            that verifies the certificates sent from servers.
-     *                            {@code null} to use the default..
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param cipherFilter a filter to apply over the supplied list of ciphers
-     * @param apn Provides a means to configure parameters related to application protocol negotiation.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory, Iterable<String> ciphers,
-                                CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-                                long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(certChainFile, trustManagerFactory, null, null, null, null,
-             ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     * @param trustCertCollectionFile an X.509 certificate collection file in PEM format.
-     *                      {@code null} to use the system default
-     * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
-     *                            that verifies the certificates sent from servers.
-     *                            {@code null} to use the default or the results of parsing
-     *                            {@code trustCertCollectionFile}
-     * @param keyCertChainFile an X.509 certificate chain file in PEM format.
-     *                      This provides the public key for mutual authentication.
-     *                      {@code null} to use the system default
-     * @param keyFile a PKCS#8 private key file in PEM format.
-     *                      This provides the private key for mutual authentication.
-     *                      {@code null} for no mutual authentication.
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     *                    Ignored if {@code keyFile} is {@code null}.
-     * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link javax.net.ssl.KeyManager}s
-     *                          that is used to encrypt data being sent to servers.
-     *                          {@code null} to use the default or the results of parsing
-     *                          {@code keyCertChainFile} and {@code keyFile}.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param cipherFilter a filter to apply over the supplied list of ciphers
-     * @param apn Application Protocol Negotiator object.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslClientContext(File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
-                                File keyCertChainFile, File keyFile, String keyPassword,
-                                KeyManagerFactory keyManagerFactory, Iterable<String> ciphers,
-                                CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-                                long sessionCacheSize, long sessionTimeout)
-            throws SSLException {
-        this(toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory,
-                toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
-                keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
-    }
-
-    OpenSslClientContext(X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-                         X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
-                                KeyManagerFactory keyManagerFactory, Iterable<String> ciphers,
-                                CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-                                long sessionCacheSize, long sessionTimeout)
-            throws SSLException {
-        super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, keyCertChain,
-                ClientAuth.NONE, false);
-        boolean success = false;
-        try {
-            sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
-                                               keyCertChain, key, keyPassword, keyManagerFactory);
-            success = true;
-        } finally {
-            if (!success) {
-                release();
-            }
-        }
-    }
-
-    @Override
-    public OpenSslSessionContext sessionContext() {
-        return sessionContext;
-    }
-
-    @Override
-    OpenSslKeyMaterialManager keyMaterialManager() {
-        return null;
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java
deleted file mode 100644
index 4cafbfb..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.buffer.ByteBufAllocator;
-
-import java.security.cert.Certificate;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLException;
-
-/**
- * This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers
- * and manually release the native memory see {@link ReferenceCountedOpenSslContext}.
- */
-public abstract class OpenSslContext extends ReferenceCountedOpenSslContext {
-    OpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apnCfg,
-                   long sessionCacheSize, long sessionTimeout, int mode, Certificate[] keyCertChain,
-                   ClientAuth clientAuth, boolean startTls)
-            throws SSLException {
-        super(ciphers, cipherFilter, apnCfg, sessionCacheSize, sessionTimeout, mode, keyCertChain,
-                clientAuth, startTls, false);
-    }
-
-    OpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
-                   OpenSslApplicationProtocolNegotiator apn, long sessionCacheSize,
-                   long sessionTimeout, int mode, Certificate[] keyCertChain,
-                   ClientAuth clientAuth, boolean startTls) throws SSLException {
-        super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, mode, keyCertChain, clientAuth, startTls,
-              false);
-    }
-
-    @Override
-    final SSLEngine newEngine0(ByteBufAllocator alloc, String peerHost, int peerPort) {
-        return new OpenSslEngine(this, alloc, peerHost, peerPort);
-    }
-
-    @Override
-    @SuppressWarnings("FinalizeDeclaration")
-    protected final void finalize() throws Throwable {
-        super.finalize();
-        OpenSsl.releaseIfNeeded(this);
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java
deleted file mode 100644
index 2ab7c5c..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngine.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.buffer.ByteBufAllocator;
-
-import javax.net.ssl.SSLEngine;
-
-import static io.netty.util.ReferenceCountUtil.safeRelease;
-
-/**
- * Implements a {@link SSLEngine} using
- * <a href="https://www.openssl.org/docs/crypto/BIO_s_bio.html#EXAMPLE">OpenSSL BIO abstractions</a>.
- * <p>
- * This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers
- * and manually release the native memory see {@link ReferenceCountedOpenSslEngine}.
- */
-public final class OpenSslEngine extends ReferenceCountedOpenSslEngine {
-    OpenSslEngine(OpenSslContext context, ByteBufAllocator alloc, String peerHost, int peerPort) {
-        super(context, alloc, peerHost, peerPort, false);
-    }
-
-    @Override
-    @SuppressWarnings("FinalizeDeclaration")
-    protected void finalize() throws Throwable {
-        super.finalize();
-        OpenSsl.releaseIfNeeded(this);
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java
deleted file mode 100644
index 02131b4..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslEngineMap.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-interface OpenSslEngineMap {
-
-    /**
-     * Remove the {@link OpenSslEngine} with the given {@code ssl} address and
-     * return it.
-     */
-    ReferenceCountedOpenSslEngine remove(long ssl);
-
-    /**
-     * Add a {@link OpenSslEngine} to this {@link OpenSslEngineMap}.
-     */
-    void add(ReferenceCountedOpenSslEngine engine);
-
-    /**
-     * Get the {@link OpenSslEngine} for the given {@code ssl} address.
-     */
-    ReferenceCountedOpenSslEngine get(long ssl);
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslExtendedKeyMaterialManager.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslExtendedKeyMaterialManager.java
deleted file mode 100644
index 38f6a7f..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslExtendedKeyMaterialManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.security.auth.x500.X500Principal;
-
-final class OpenSslExtendedKeyMaterialManager extends OpenSslKeyMaterialManager {
-
-    private final X509ExtendedKeyManager keyManager;
-
-    OpenSslExtendedKeyMaterialManager(X509ExtendedKeyManager keyManager, String password) {
-        super(keyManager, password);
-        this.keyManager = keyManager;
-    }
-
-    @Override
-    protected String chooseClientAlias(ReferenceCountedOpenSslEngine engine, String[] keyTypes,
-                                       X500Principal[] issuer) {
-        return keyManager.chooseEngineClientAlias(keyTypes, issuer, engine);
-    }
-
-    @Override
-    protected String chooseServerAlias(ReferenceCountedOpenSslEngine engine, String type) {
-        return keyManager.chooseEngineServerAlias(type, null, engine);
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java
deleted file mode 100644
index 95a38fd..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslKeyMaterialManager.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.buffer.ByteBufAllocator;
-import org.apache.tomcat.jni.CertificateRequestedCallback;
-import org.apache.tomcat.jni.SSL;
-
-import javax.net.ssl.SSLException;
-import javax.net.ssl.X509KeyManager;
-import javax.security.auth.x500.X500Principal;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static io.netty.handler.ssl.ReferenceCountedOpenSslContext.freeBio;
-import static io.netty.handler.ssl.ReferenceCountedOpenSslContext.toBIO;
-
-/**
- * Manages key material for {@link OpenSslEngine}s and so set the right {@link PrivateKey}s and
- * {@link X509Certificate}s.
- */
-class OpenSslKeyMaterialManager {
-
-    // Code in this class is inspired by code of conscrypts:
-    // - https://android.googlesource.com/platform/external/
-    //   conscrypt/+/master/src/main/java/org/conscrypt/OpenSSLEngineImpl.java
-    // - https://android.googlesource.com/platform/external/
-    //   conscrypt/+/master/src/main/java/org/conscrypt/SSLParametersImpl.java
-    //
-    static final String KEY_TYPE_RSA = "RSA";
-    static final String KEY_TYPE_DH_RSA = "DH_RSA";
-    static final String KEY_TYPE_EC = "EC";
-    static final String KEY_TYPE_EC_EC = "EC_EC";
-    static final String KEY_TYPE_EC_RSA = "EC_RSA";
-
-    // key type mappings for types.
-    private static final Map<String, String> KEY_TYPES = new HashMap<String, String>();
-    static {
-        KEY_TYPES.put("RSA", KEY_TYPE_RSA);
-        KEY_TYPES.put("DHE_RSA", KEY_TYPE_RSA);
-        KEY_TYPES.put("ECDHE_RSA", KEY_TYPE_RSA);
-        KEY_TYPES.put("ECDHE_ECDSA", KEY_TYPE_EC);
-        KEY_TYPES.put("ECDH_RSA", KEY_TYPE_EC_RSA);
-        KEY_TYPES.put("ECDH_ECDSA", KEY_TYPE_EC_EC);
-        KEY_TYPES.put("DH_RSA", KEY_TYPE_DH_RSA);
-    }
-
-    private final X509KeyManager keyManager;
-    private final String password;
-
-    OpenSslKeyMaterialManager(X509KeyManager keyManager, String password) {
-        this.keyManager = keyManager;
-        this.password = password;
-    }
-
-    void setKeyMaterial(ReferenceCountedOpenSslEngine engine) throws SSLException {
-        long ssl = engine.sslPointer();
-        String[] authMethods = SSL.authenticationMethods(ssl);
-        Set<String> aliases = new HashSet<String>(authMethods.length);
-        for (String authMethod : authMethods) {
-            String type = KEY_TYPES.get(authMethod);
-            if (type != null) {
-                String alias = chooseServerAlias(engine, type);
-                if (alias != null && aliases.add(alias)) {
-                    setKeyMaterial(ssl, alias);
-                }
-            }
-        }
-    }
-
-    CertificateRequestedCallback.KeyMaterial keyMaterial(ReferenceCountedOpenSslEngine engine, String[] keyTypes,
-                                                         X500Principal[] issuer) throws SSLException {
-        String alias = chooseClientAlias(engine, keyTypes, issuer);
-        long keyBio = 0;
-        long keyCertChainBio = 0;
-        long pkey = 0;
-        long certChain = 0;
-
-        try {
-            // TODO: Should we cache these and so not need to do a memory copy all the time ?
-            X509Certificate[] certificates = keyManager.getCertificateChain(alias);
-            if (certificates == null || certificates.length == 0) {
-                return null;
-            }
-
-            PrivateKey key = keyManager.getPrivateKey(alias);
-            keyCertChainBio = toBIO(certificates);
-            certChain = SSL.parseX509Chain(keyCertChainBio);
-            if (key != null) {
-                keyBio = toBIO(key);
-                pkey = SSL.parsePrivateKey(keyBio, password);
-            }
-            CertificateRequestedCallback.KeyMaterial material = new CertificateRequestedCallback.KeyMaterial(
-                    certChain, pkey);
-
-            // Reset to 0 so we do not free these. This is needed as the client certificate callback takes ownership
-            // of both the key and the certificate if they are returned from this method, and thus must not
-            // be freed here.
-            certChain = pkey = 0;
-            return material;
-        } catch (SSLException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new SSLException(e);
-        } finally {
-            freeBio(keyBio);
-            freeBio(keyCertChainBio);
-            SSL.freePrivateKey(pkey);
-            SSL.freeX509Chain(certChain);
-        }
-    }
-
-    private void setKeyMaterial(long ssl, String alias) throws SSLException {
-        long keyBio = 0;
-        long keyCertChainBio = 0;
-        long keyCertChainBio2 = 0;
-
-        try {
-            // TODO: Should we cache these and so not need to do a memory copy all the time ?
-            X509Certificate[] certificates = keyManager.getCertificateChain(alias);
-            if (certificates == null || certificates.length == 0) {
-                return;
-            }
-
-            PrivateKey key = keyManager.getPrivateKey(alias);
-
-            // Only encode one time
-            PemEncoded encoded = PemX509Certificate.toPEM(ByteBufAllocator.DEFAULT, true, certificates);
-            try {
-                keyCertChainBio = toBIO(ByteBufAllocator.DEFAULT, encoded.retain());
-                keyCertChainBio2 = toBIO(ByteBufAllocator.DEFAULT, encoded.retain());
-
-                if (key != null) {
-                    keyBio = toBIO(key);
-                }
-                SSL.setCertificateBio(ssl, keyCertChainBio, keyBio, password);
-
-                // We may have more then one cert in the chain so add all of them now.
-                SSL.setCertificateChainBio(ssl, keyCertChainBio2, true);
-            } finally {
-                encoded.release();
-            }
-        } catch (SSLException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new SSLException(e);
-        } finally {
-            freeBio(keyBio);
-            freeBio(keyCertChainBio);
-            freeBio(keyCertChainBio2);
-        }
-    }
-
-    protected String chooseClientAlias(@SuppressWarnings("unused") ReferenceCountedOpenSslEngine engine,
-                                       String[] keyTypes, X500Principal[] issuer) {
-        return keyManager.chooseClientAlias(keyTypes, issuer, null);
-    }
-
-    protected String chooseServerAlias(@SuppressWarnings("unused") ReferenceCountedOpenSslEngine engine, String type) {
-        return keyManager.chooseServerAlias(type, null, null);
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java
deleted file mode 100644
index a65e07d..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerContext.java
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.handler.ssl.ReferenceCountedOpenSslServerContext.ServerContext;
-import org.apache.tomcat.jni.SSL;
-
-import java.io.File;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-import static io.netty.handler.ssl.ReferenceCountedOpenSslServerContext.newSessionContext;
-
-/**
- * A server-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation.
- * <p>This class will use a finalizer to ensure native resources are automatically cleaned up. To avoid finalizers
- * and manually release the native memory see {@link ReferenceCountedOpenSslServerContext}.
- */
-public final class OpenSslServerContext extends OpenSslContext {
-    private final OpenSslServerSessionContext sessionContext;
-    private final OpenSslKeyMaterialManager keyMaterialManager;
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(File certChainFile, File keyFile) throws SSLException {
-        this(certChainFile, keyFile, null);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(File certChainFile, File keyFile, String keyPassword) throws SSLException {
-        this(certChainFile, keyFile, keyPassword, null, IdentityCipherSuiteFilter.INSTANCE,
-             ApplicationProtocolConfig.DISABLED, 0, 0);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param apn Provides a means to configure parameters related to application protocol negotiation.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File certChainFile, File keyFile, String keyPassword,
-            Iterable<String> ciphers, ApplicationProtocolConfig apn,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(certChainFile, keyFile, keyPassword, ciphers, IdentityCipherSuiteFilter.INSTANCE,
-             apn, sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param nextProtocols the application layer protocols to accept, in the order of preference.
-     *                      {@code null} to disable TLS NPN/ALPN extension.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File certChainFile, File keyFile, String keyPassword,
-            Iterable<String> ciphers, Iterable<String> nextProtocols,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(certChainFile, keyFile, keyPassword, ciphers,
-            toApplicationProtocolConfig(nextProtocols), sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param config Application protocol config.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory,
-            Iterable<String> ciphers, ApplicationProtocolConfig config,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(certChainFile, keyFile, keyPassword, trustManagerFactory, ciphers,
-                toNegotiator(config), sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param apn Application protocol negotiator.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory,
-            Iterable<String> ciphers, OpenSslApplicationProtocolNegotiator apn,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(null, trustManagerFactory, certChainFile, keyFile, keyPassword, null,
-             ciphers, null, apn, sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param cipherFilter a filter to apply over the supplied list of ciphers
-     * @param apn Provides a means to configure parameters related to application protocol negotiation.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File certChainFile, File keyFile, String keyPassword,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(null, null, certChainFile, keyFile, keyPassword, null,
-             ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param trustCertCollectionFile an X.509 certificate collection file in PEM format.
-     *                      This provides the certificate collection used for mutual authentication.
-     *                      {@code null} to use the system default
-     * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
-     *                            that verifies the certificates sent from clients.
-     *                            {@code null} to use the default or the results of parsing
-     *                            {@code trustCertCollectionFile}.
-     * @param keyCertChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s
-     *                          that is used to encrypt data being sent to clients.
-     *                          {@code null} to use the default or the results of parsing
-     *                          {@code keyCertChainFile} and {@code keyFile}.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param cipherFilter a filter to apply over the supplied list of ciphers
-     *                Only required if {@code provider} is {@link SslProvider#JDK}
-     * @param config Provides a means to configure parameters related to application protocol negotiation.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
-            File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig config,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(trustCertCollectionFile, trustManagerFactory, keyCertChainFile, keyFile, keyPassword, keyManagerFactory,
-             ciphers, cipherFilter, toNegotiator(config), sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param cipherFilter a filter to apply over the supplied list of ciphers
-     * @param config Application protocol config.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(File certChainFile, File keyFile, String keyPassword,
-                                TrustManagerFactory trustManagerFactory, Iterable<String> ciphers,
-                                CipherSuiteFilter cipherFilter, ApplicationProtocolConfig config,
-                                long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(null, trustManagerFactory, certChainFile, keyFile, keyPassword, null, ciphers, cipherFilter,
-                      toNegotiator(config), sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     * @param certChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param cipherFilter a filter to apply over the supplied list of ciphers
-     * @param apn Application protocol negotiator.
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File certChainFile, File keyFile, String keyPassword, TrustManagerFactory trustManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(null, trustManagerFactory, certChainFile, keyFile, keyPassword, null, ciphers, cipherFilter,
-             apn, sessionCacheSize, sessionTimeout);
-    }
-
-    /**
-     * Creates a new instance.
-     *
-     *
-     * @param trustCertCollectionFile an X.509 certificate collection file in PEM format.
-     *                      This provides the certificate collection used for mutual authentication.
-     *                      {@code null} to use the system default
-     * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
-     *                            that verifies the certificates sent from clients.
-     *                            {@code null} to use the default or the results of parsing
-     *                            {@code trustCertCollectionFile}.
-     * @param keyCertChainFile an X.509 certificate chain file in PEM format
-     * @param keyFile a PKCS#8 private key file in PEM format
-     * @param keyPassword the password of the {@code keyFile}.
-     *                    {@code null} if it's not password-protected.
-     * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s
-     *                          that is used to encrypt data being sent to clients.
-     *                          {@code null} to use the default or the results of parsing
-     *                          {@code keyCertChainFile} and {@code keyFile}.
-     * @param ciphers the cipher suites to enable, in the order of preference.
-     *                {@code null} to use the default cipher suites.
-     * @param cipherFilter a filter to apply over the supplied list of ciphers
-     *                Only required if {@code provider} is {@link SslProvider#JDK}
-     * @param apn Application Protocol Negotiator object
-     * @param sessionCacheSize the size of the cache used for storing SSL session objects.
-     *                         {@code 0} to use the default value.
-     * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
-     *                       {@code 0} to use the default value.
-     * @deprecated use {@link SslContextBuilder}
-     */
-    @Deprecated
-    public OpenSslServerContext(
-            File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
-            File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
-            long sessionCacheSize, long sessionTimeout) throws SSLException {
-        this(toX509CertificatesInternal(trustCertCollectionFile), trustManagerFactory,
-                toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
-                keyPassword, keyManagerFactory, ciphers, cipherFilter,
-                apn, sessionCacheSize, sessionTimeout, ClientAuth.NONE, false);
-    }
-
-    OpenSslServerContext(
-            X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-            X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-            long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, boolean startTls) throws SSLException {
-        this(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers,
-                cipherFilter, toNegotiator(apn), sessionCacheSize, sessionTimeout, clientAuth, startTls);
-    }
-
-    @SuppressWarnings("deprecation")
-    private OpenSslServerContext(
-            X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-            X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
-            long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, boolean startTls) throws SSLException {
-        super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, keyCertChain,
-                clientAuth, startTls);
-        // Create a new SSL_CTX and configure it.
-        boolean success = false;
-        try {
-            ServerContext context = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
-                                                      keyCertChain, key, keyPassword, keyManagerFactory);
-            sessionContext = context.sessionContext;
-            keyMaterialManager = context.keyMaterialManager;
-            success = true;
-        } finally {
-            if (!success) {
-                release();
-            }
-        }
-    }
-
-    @Override
-    public OpenSslServerSessionContext sessionContext() {
-        return sessionContext;
-    }
-
-    @Override
-    OpenSslKeyMaterialManager keyMaterialManager() {
-        return keyMaterialManager;
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java
deleted file mode 100644
index c6687f6..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslServerSessionContext.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.apache.tomcat.jni.SSL;
-import org.apache.tomcat.jni.SSLContext;
-
-
-/**
- * {@link OpenSslSessionContext} implementation which offers extra methods which are only useful for the server-side.
- */
-public final class OpenSslServerSessionContext extends OpenSslSessionContext {
-    OpenSslServerSessionContext(ReferenceCountedOpenSslContext context) {
-        super(context);
-    }
-
-    @Override
-    public void setSessionTimeout(int seconds) {
-        if (seconds < 0) {
-            throw new IllegalArgumentException();
-        }
-        SSLContext.setSessionCacheTimeout(context.ctx, seconds);
-    }
-
-    @Override
-    public int getSessionTimeout() {
-        return (int) SSLContext.getSessionCacheTimeout(context.ctx);
-    }
-
-    @Override
-    public void setSessionCacheSize(int size) {
-        if (size < 0) {
-            throw new IllegalArgumentException();
-        }
-        SSLContext.setSessionCacheSize(context.ctx, size);
-    }
-
-    @Override
-    public int getSessionCacheSize() {
-        return (int) SSLContext.getSessionCacheSize(context.ctx);
-    }
-
-    @Override
-    public void setSessionCacheEnabled(boolean enabled) {
-        long mode = enabled ? SSL.SSL_SESS_CACHE_SERVER : SSL.SSL_SESS_CACHE_OFF;
-        SSLContext.setSessionCacheMode(context.ctx, mode);
-    }
-
-    @Override
-    public boolean isSessionCacheEnabled() {
-        return SSLContext.getSessionCacheMode(context.ctx) == SSL.SSL_SESS_CACHE_SERVER;
-    }
-
-    /**
-     * Set the context within which session be reused (server side only)
-     * See <a href="http://www.openssl.org/docs/ssl/SSL_CTX_set_session_id_context.html">
-     *     man SSL_CTX_set_session_id_context</a>
-     *
-     * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name
-     *               of the application and/or the hostname and/or service name
-     * @return {@code true} if success, {@code false} otherwise.
-     */
-    public boolean setSessionIdContext(byte[] sidCtx) {
-        return SSLContext.setSessionIdContext(context.ctx, sidCtx);
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java
deleted file mode 100644
index df13d6a..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionContext.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-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 javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-/**
- * OpenSSL specific {@link SSLSessionContext} implementation.
- */
-public abstract class OpenSslSessionContext implements SSLSessionContext {
-    private static final Enumeration<byte[]> EMPTY = new EmptyEnumeration();
-
-    private final OpenSslSessionStats stats;
-    final ReferenceCountedOpenSslContext context;
-
-    // IMPORTANT: We take the OpenSslContext and not just the long (which points the native instance) to prevent
-    //            the GC to collect OpenSslContext as this would also free the pointer and so could result in a
-    //            segfault when the user calls any of the methods here that try to pass the pointer down to the native
-    //            level.
-    OpenSslSessionContext(ReferenceCountedOpenSslContext context) {
-        this.context = context;
-        stats = new OpenSslSessionStats(context);
-    }
-
-    @Override
-    public SSLSession getSession(byte[] bytes) {
-        if (bytes == null) {
-            throw new NullPointerException("bytes");
-        }
-        return null;
-    }
-
-    @Override
-    public Enumeration<byte[]> getIds() {
-        return EMPTY;
-    }
-
-    /**
-     * Sets the SSL session ticket keys of this context.
-     * @deprecated use {@link #setTicketKeys(OpenSslSessionTicketKey...)}.
-     */
-    @Deprecated
-    public void setTicketKeys(byte[] keys) {
-        ObjectUtil.checkNotNull(keys, "keys");
-        SSLContext.clearOptions(context.ctx, SSL.SSL_OP_NO_TICKET);
-        SSLContext.setSessionTicketKeys(context.ctx, keys);
-    }
-
-    /**
-     * Sets the SSL session ticket keys of this context.
-     */
-    public void setTicketKeys(OpenSslSessionTicketKey... keys) {
-        ObjectUtil.checkNotNull(keys, "keys");
-        SSLContext.clearOptions(context.ctx, SSL.SSL_OP_NO_TICKET);
-        SessionTicketKey[] ticketKeys = new SessionTicketKey[keys.length];
-        for (int i = 0; i < ticketKeys.length; i++) {
-            ticketKeys[i] = keys[i].key;
-        }
-        SSLContext.setSessionTicketKeys(context.ctx, ticketKeys);
-    }
-
-    /**
-     * Enable or disable caching of SSL sessions.
-     */
-    public abstract void setSessionCacheEnabled(boolean enabled);
-
-    /**
-     * Return {@code true} if caching of SSL sessions is enabled, {@code false} otherwise.
-     */
-    public abstract boolean isSessionCacheEnabled();
-
-    /**
-     * Returns the stats of this context.
-     */
-    public OpenSslSessionStats stats() {
-        return stats;
-    }
-
-    private static final class EmptyEnumeration implements Enumeration<byte[]> {
-        @Override
-        public boolean hasMoreElements() {
-            return false;
-        }
-
-        @Override
-        public byte[] nextElement() {
-            throw new NoSuchElementException();
-        }
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java
deleted file mode 100644
index ff93a04..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionStats.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package io.netty.handler.ssl;
-
-import org.apache.tomcat.jni.SSLContext;
-
-/**
- * Stats exposed by an OpenSSL session context.
- *
- * @see <a href="https://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html"><code>SSL_CTX_sess_number</code></a>
- */
-public final class OpenSslSessionStats {
-
-    private final ReferenceCountedOpenSslContext context;
-
-    // IMPORTANT: We take the OpenSslContext and not just the long (which points the native instance) to prevent
-    //            the GC to collect OpenSslContext as this would also free the pointer and so could result in a
-    //            segfault when the user calls any of the methods here that try to pass the pointer down to the native
-    //            level.
-    OpenSslSessionStats(ReferenceCountedOpenSslContext context) {
-        this.context = context;
-    }
-
-    /**
-     * Returns the current number of sessions in the internal session cache.
-     */
-    public long number() {
-        return SSLContext.sessionNumber(context.ctx);
-    }
-
-    /**
-     * Returns the number of started SSL/TLS handshakes in client mode.
-     */
-    public long connect() {
-        return SSLContext.sessionConnect(context.ctx);
-    }
-
-    /**
-     * Returns the number of successfully established SSL/TLS sessions in client mode.
-     */
-    public long connectGood() {
-        return SSLContext.sessionConnectGood(context.ctx);
-    }
-
-    /**
-     * Returns the number of start renegotiations in client mode.
-     */
-    public long connectRenegotiate() {
-        return SSLContext.sessionConnectRenegotiate(context.ctx);
-    }
-
-    /**
-     * Returns the number of started SSL/TLS handshakes in server mode.
-     */
-    public long accept() {
-        return SSLContext.sessionAccept(context.ctx);
-    }
-
-    /**
-     * Returns the number of successfully established SSL/TLS sessions in server mode.
-     */
-    public long acceptGood() {
-        return SSLContext.sessionAcceptGood(context.ctx);
-    }
-
-    /**
-     * Returns the number of start renegotiations in server mode.
-     */
-    public long acceptRenegotiate() {
-        return SSLContext.sessionAcceptRenegotiate(context.ctx);
-    }
-
-    /**
-     * Returns the number of successfully reused sessions. In client mode, a session set with {@code SSL_set_session}
-     * successfully reused is counted as a hit. In server mode, a session successfully retrieved from internal or
-     * external cache is counted as a hit.
-     */
-    public long hits() {
-        return SSLContext.sessionHits(context.ctx);
-    }
-
-    /**
-     * Returns the number of successfully retrieved sessions from the external session cache in server mode.
-     */
-    public long cbHits() {
-        return SSLContext.sessionCbHits(context.ctx);
-    }
-
-    /**
-     * Returns the number of sessions proposed by clients that were not found in the internal session cache
-     * in server mode.
-     */
-    public long misses() {
-        return SSLContext.sessionMisses(context.ctx);
-    }
-
-    /**
-     * Returns the number of sessions proposed by clients and either found in the internal or external session cache
-     * in server mode, but that were invalid due to timeout. These sessions are not included in the {@link #hits()}
-     * count.
-     */
-    public long timeouts() {
-        return SSLContext.sessionTimeouts(context.ctx);
-    }
-
-    /**
-     * Returns the number of sessions that were removed because the maximum session cache size was exceeded.
-     */
-    public long cacheFull() {
-        return SSLContext.sessionCacheFull(context.ctx);
-    }
-
-    /**
-     * Returns the number of times a client presented a ticket that did not match any key in the list.
-     */
-    public long ticketKeyFail() {
-        return SSLContext.sessionTicketKeyFail(context.ctx);
-    }
-
-    /**
-     * Returns the number of times a client did not present a ticket and we issued a new one
-     */
-    public long ticketKeyNew() {
-        return SSLContext.sessionTicketKeyNew(context.ctx);
-    }
-
-    /**
-     * Returns the number of times a client presented a ticket derived from an older key,
-     * and we upgraded to the primary key.
-     */
-    public long ticketKeyRenew() {
-        return SSLContext.sessionTicketKeyRenew(context.ctx);
-    }
-
-    /**
-     * Returns the number of times a client presented a ticket derived from the primary key.
-     */
-    public long ticketKeyResume() {
-        return SSLContext.sessionTicketKeyResume(context.ctx);
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java b/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java
deleted file mode 100644
index f3af820..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSslSessionTicketKey.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2015 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.apache.tomcat.jni.SessionTicketKey;
-
-/**
- * Session Ticket Key
- */
-public final class OpenSslSessionTicketKey {
-
-    /**
-     * Size of session ticket key name
-     */
-    public static final int NAME_SIZE = SessionTicketKey.NAME_SIZE;
-    /**
-     * Size of session ticket key HMAC key
-     */
-    public static final int HMAC_KEY_SIZE = SessionTicketKey.HMAC_KEY_SIZE;
-    /**
-     * Size of session ticket key AES key
-     */
-    public static final int AES_KEY_SIZE = SessionTicketKey.AES_KEY_SIZE;
-    /**
-     * Size of session ticker key
-     */
-    public static final int TICKET_KEY_SIZE = SessionTicketKey.TICKET_KEY_SIZE;
-
-    final SessionTicketKey key;
-
-    /**
-     * Construct a OpenSslSessionTicketKey.
-     *
-     * @param name the name of the session ticket key
-     * @param hmacKey the HMAC key of the session ticket key
-     * @param aesKey the AES key of the session ticket key
-     */
-    public OpenSslSessionTicketKey(byte[] name, byte[] hmacKey, byte[] aesKey) {
-        key = new SessionTicketKey(name.clone(), hmacKey.clone(), aesKey.clone());
-    }
-
-    /**
-     * Get name.
-     * @return the name of the session ticket key
-     */
-    public byte[] name() {
-        return key.getName().clone();
-    }
-
-    /**
-     * Get HMAC key.
-     * @return the HMAC key of the session ticket key
-     */
-    public byte[] hmacKey() {
-        return key.getHmacKey().clone();
-    }
-
-    /**
-     * Get AES Key.
-     * @return the AES key of the session ticket key
-     */
-    public byte[] aesKey() {
-        return key.getAesKey().clone();
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java
deleted file mode 100644
index 97cd3e3..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslClientContext.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-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 java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509ExtendedTrustManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * A client-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation.
- * <p>Instances of this class must be {@link #release() released} or else native memory will leak!
- *
- * <p>Instances of this class <strong>must not</strong> be released before any {@link ReferenceCountedOpenSslEngine}
- * which depends upon the instance of this class is released. Otherwise if any method of
- * {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash.
- */
-public final class ReferenceCountedOpenSslClientContext extends ReferenceCountedOpenSslContext {
-    private static final InternalLogger logger =
-            InternalLoggerFactory.getInstance(ReferenceCountedOpenSslClientContext.class);
-    private final OpenSslSessionContext sessionContext;
-
-    ReferenceCountedOpenSslClientContext(X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-                                         X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
-                                         KeyManagerFactory keyManagerFactory, Iterable<String> ciphers,
-                                         CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-                                         long sessionCacheSize, long sessionTimeout)
-            throws SSLException {
-        super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, keyCertChain,
-              ClientAuth.NONE, false, true);
-        boolean success = false;
-        try {
-            sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
-                                               keyCertChain, key, keyPassword, keyManagerFactory);
-            success = true;
-        } finally {
-            if (!success) {
-                release();
-            }
-        }
-    }
-
-    @Override
-    OpenSslKeyMaterialManager keyMaterialManager() {
-        return null;
-    }
-
-    @Override
-    public OpenSslSessionContext sessionContext() {
-        return sessionContext;
-    }
-
-    static OpenSslSessionContext newSessionContext(ReferenceCountedOpenSslContext thiz, long ctx,
-                                                   OpenSslEngineMap engineMap,
-                                                   X509Certificate[] trustCertCollection,
-                                                   TrustManagerFactory trustManagerFactory,
-                                                   X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
-                                                   KeyManagerFactory keyManagerFactory) throws SSLException {
-        if (key == null && keyCertChain != null || key != null && keyCertChain == null) {
-            throw new IllegalArgumentException(
-                    "Either both keyCertChain and key needs to be null or none of them");
-        }
-        synchronized (ReferenceCountedOpenSslContext.class) {
-            try {
-                if (!OpenSsl.useKeyManagerFactory()) {
-                    if (keyManagerFactory != null) {
-                        throw new IllegalArgumentException(
-                                "KeyManagerFactory not supported");
-                    }
-                    if (keyCertChain != null/* && key != null*/) {
-                        setKeyMaterial(ctx, keyCertChain, key, keyPassword);
-                    }
-                } else {
-                    // javadocs state that keyManagerFactory has precedent over keyCertChain
-                    if (keyManagerFactory == null && keyCertChain != null) {
-                        keyManagerFactory = buildKeyManagerFactory(
-                                keyCertChain, key, keyPassword, keyManagerFactory);
-                    }
-
-                    if (keyManagerFactory != null) {
-                        X509KeyManager keyManager = chooseX509KeyManager(keyManagerFactory.getKeyManagers());
-                        OpenSslKeyMaterialManager materialManager = useExtendedKeyManager(keyManager) ?
-                                new OpenSslExtendedKeyMaterialManager(
-                                        (X509ExtendedKeyManager) keyManager, keyPassword) :
-                                new OpenSslKeyMaterialManager(keyManager, keyPassword);
-                        SSLContext.setCertRequestedCallback(ctx, new OpenSslCertificateRequestedCallback(
-                                engineMap, materialManager));
-                    }
-                }
-            } catch (Exception e) {
-                throw new SSLException("failed to set certificate and key", e);
-            }
-
-            SSLContext.setVerify(ctx, SSL.SSL_VERIFY_NONE, VERIFY_DEPTH);
-
-            try {
-                if (trustCertCollection != null) {
-                    trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory);
-                } else if (trustManagerFactory == null) {
-                    trustManagerFactory = TrustManagerFactory.getInstance(
-                            TrustManagerFactory.getDefaultAlgorithm());
-                    trustManagerFactory.init((KeyStore) null);
-                }
-                final X509TrustManager manager = chooseTrustManager(trustManagerFactory.getTrustManagers());
-
-                // IMPORTANT: The callbacks set for verification must be static to prevent memory leak as
-                //            otherwise the context can never be collected. This is because the JNI code holds
-                //            a global reference to the callbacks.
-                //
-                //            See https://github.com/netty/netty/issues/5372
-
-                // Use this to prevent an error when running on java < 7
-                if (useExtendedTrustManager(manager)) {
-                    SSLContext.setCertVerifyCallback(ctx,
-                            new ExtendedTrustManagerVerifyCallback(engineMap, (X509ExtendedTrustManager) manager));
-                } else {
-                    SSLContext.setCertVerifyCallback(ctx, new TrustManagerVerifyCallback(engineMap, manager));
-                }
-            } catch (Exception e) {
-                throw new SSLException("unable to setup trustmanager", e);
-            }
-        }
-        return new OpenSslClientSessionContext(thiz);
-    }
-
-    // No cache is currently supported for client side mode.
-    static final class OpenSslClientSessionContext extends OpenSslSessionContext {
-        OpenSslClientSessionContext(ReferenceCountedOpenSslContext context) {
-            super(context);
-        }
-
-        @Override
-        public void setSessionTimeout(int seconds) {
-            if (seconds < 0) {
-                throw new IllegalArgumentException();
-            }
-        }
-
-        @Override
-        public int getSessionTimeout() {
-            return 0;
-        }
-
-        @Override
-        public void setSessionCacheSize(int size)  {
-            if (size < 0) {
-                throw new IllegalArgumentException();
-            }
-        }
-
-        @Override
-        public int getSessionCacheSize() {
-            return 0;
-        }
-
-        @Override
-        public void setSessionCacheEnabled(boolean enabled) {
-            // ignored
-        }
-
-        @Override
-        public boolean isSessionCacheEnabled() {
-            return false;
-        }
-    }
-
-    private static final class TrustManagerVerifyCallback extends AbstractCertificateVerifier {
-        private final X509TrustManager manager;
-
-        TrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509TrustManager manager) {
-            super(engineMap);
-            this.manager = manager;
-        }
-
-        @Override
-        void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth)
-                throws Exception {
-            manager.checkServerTrusted(peerCerts, auth);
-        }
-    }
-
-    private static final class ExtendedTrustManagerVerifyCallback extends AbstractCertificateVerifier {
-        private final X509ExtendedTrustManager manager;
-
-        ExtendedTrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509ExtendedTrustManager manager) {
-            super(engineMap);
-            this.manager = manager;
-        }
-
-        @Override
-        void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth)
-                throws Exception {
-            manager.checkServerTrusted(peerCerts, auth, engine);
-        }
-    }
-
-    private static final class OpenSslCertificateRequestedCallback implements CertificateRequestedCallback {
-        private final OpenSslEngineMap engineMap;
-        private final OpenSslKeyMaterialManager keyManagerHolder;
-
-        OpenSslCertificateRequestedCallback(OpenSslEngineMap engineMap, OpenSslKeyMaterialManager keyManagerHolder) {
-            this.engineMap = engineMap;
-            this.keyManagerHolder = keyManagerHolder;
-        }
-
-        @Override
-        public KeyMaterial requested(long ssl, byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) {
-            final ReferenceCountedOpenSslEngine engine = engineMap.get(ssl);
-            try {
-                final Set<String> keyTypesSet = supportedClientKeyTypes(keyTypeBytes);
-                final String[] keyTypes = keyTypesSet.toArray(new String[keyTypesSet.size()]);
-                final X500Principal[] issuers;
-                if (asn1DerEncodedPrincipals == null) {
-                    issuers = null;
-                } else {
-                    issuers = new X500Principal[asn1DerEncodedPrincipals.length];
-                    for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) {
-                        issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]);
-                    }
-                }
-                return keyManagerHolder.keyMaterial(engine, keyTypes, issuers);
-            } catch (Throwable cause) {
-                logger.debug("request of key failed", cause);
-                SSLHandshakeException e = new SSLHandshakeException("General OpenSslEngine problem");
-                e.initCause(cause);
-                engine.handshakeException = e;
-                return null;
-            }
-        }
-
-        /**
-         * Gets the supported key types for client certificates.
-         *
-         * @param clientCertificateTypes {@code ClientCertificateType} values provided by the server.
-         *        See https://www.ietf.org/assignments/tls-parameters/tls-parameters.xml.
-         * @return supported key types that can be used in {@code X509KeyManager.chooseClientAlias} and
-         *         {@code X509ExtendedKeyManager.chooseEngineClientAlias}.
-         */
-        private static Set<String> supportedClientKeyTypes(byte[] clientCertificateTypes) {
-            Set<String> result = new HashSet<String>(clientCertificateTypes.length);
-            for (byte keyTypeCode : clientCertificateTypes) {
-                String keyType = clientKeyType(keyTypeCode);
-                if (keyType == null) {
-                    // Unsupported client key type -- ignore
-                    continue;
-                }
-                result.add(keyType);
-            }
-            return result;
-        }
-
-        private static String clientKeyType(byte clientCertificateType) {
-            // See also http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml
-            switch (clientCertificateType) {
-                case CertificateRequestedCallback.TLS_CT_RSA_SIGN:
-                    return OpenSslKeyMaterialManager.KEY_TYPE_RSA; // RFC rsa_sign
-                case CertificateRequestedCallback.TLS_CT_RSA_FIXED_DH:
-                    return OpenSslKeyMaterialManager.KEY_TYPE_DH_RSA; // RFC rsa_fixed_dh
-                case CertificateRequestedCallback.TLS_CT_ECDSA_SIGN:
-                    return OpenSslKeyMaterialManager.KEY_TYPE_EC; // RFC ecdsa_sign
-                case CertificateRequestedCallback.TLS_CT_RSA_FIXED_ECDH:
-                    return OpenSslKeyMaterialManager.KEY_TYPE_EC_RSA; // RFC rsa_fixed_ecdh
-                case CertificateRequestedCallback.TLS_CT_ECDSA_FIXED_ECDH:
-                    return OpenSslKeyMaterialManager.KEY_TYPE_EC_EC; // RFC ecdsa_fixed_ecdh
-                default:
-                    return null;
-            }
-        }
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java
deleted file mode 100644
index 82e90a9..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufAllocator;
-import io.netty.util.AbstractReferenceCounted;
-import io.netty.util.ReferenceCounted;
-import io.netty.util.ResourceLeak;
-import io.netty.util.ResourceLeakDetector;
-import io.netty.util.ResourceLeakDetectorFactory;
-import io.netty.util.internal.PlatformDependent;
-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 java.security.AccessController;
-import java.security.PrivateKey;
-import java.security.PrivilegedAction;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.CertificateRevokedException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509ExtendedTrustManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-
-import static io.netty.util.internal.ObjectUtil.checkNotNull;
-
-/**
- * An implementation of {@link SslContext} which works with libraries that support the
- * <a href="https://www.openssl.org/">OpenSsl</a> C library API.
- * <p>Instances of this class must be {@link #release() released} or else native memory will leak!
- *
- * <p>Instances of this class <strong>must not</strong> be released before any {@link ReferenceCountedOpenSslEngine}
- * which depends upon the instance of this class is released. Otherwise if any method of
- * {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash.
- */
-public abstract class ReferenceCountedOpenSslContext extends SslContext implements ReferenceCounted {
-    private static final InternalLogger logger =
-            InternalLoggerFactory.getInstance(ReferenceCountedOpenSslContext.class);
-    /**
-     * To make it easier for users to replace JDK implemention with OpenSsl version we also use
-     * {@code jdk.tls.rejectClientInitiatedRenegotiation} to allow disabling client initiated renegotiation.
-     * Java8+ uses this system property as well.
-     * <p>
-     * See also <a href="http://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-java-8.html">
-     * Significant SSL/TLS improvements in Java 8</a>
-     */
-    private static final boolean JDK_REJECT_CLIENT_INITIATED_RENEGOTIATION =
-            AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-                @Override
-                public Boolean run() {
-                    return SystemPropertyUtil.getBoolean("jdk.tls.rejectClientInitiatedRenegotiation", false);
-                }
-            });
-    private static final List<String> DEFAULT_CIPHERS;
-    private static final Integer DH_KEY_LENGTH;
-    private static final ResourceLeakDetector<ReferenceCountedOpenSslContext> leakDetector =
-            ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ReferenceCountedOpenSslContext.class);
-
-    // TODO: Maybe make configurable ?
-    protected static final int VERIFY_DEPTH = 10;
-
-    /**
-     * The OpenSSL SSL_CTX object
-     */
-    protected volatile long ctx;
-    long aprPool;
-    @SuppressWarnings({ "unused", "FieldMayBeFinal" })
-    private volatile int aprPoolDestroyed;
-    private final List<String> unmodifiableCiphers;
-    private final long sessionCacheSize;
-    private final long sessionTimeout;
-    private final OpenSslApplicationProtocolNegotiator apn;
-    private final int mode;
-
-    // Reference Counting
-    private final ResourceLeak leak;
-    private final AbstractReferenceCounted refCnt = new AbstractReferenceCounted() {
-        @Override
-        protected void deallocate() {
-            destroy();
-            if (leak != null) {
-                leak.close();
-            }
-        }
-    };
-
-    final Certificate[] keyCertChain;
-    final ClientAuth clientAuth;
-    final OpenSslEngineMap engineMap = new DefaultOpenSslEngineMap();
-    volatile boolean rejectRemoteInitiatedRenegotiation;
-
-    static final OpenSslApplicationProtocolNegotiator NONE_PROTOCOL_NEGOTIATOR =
-            new OpenSslApplicationProtocolNegotiator() {
-                @Override
-                public ApplicationProtocolConfig.Protocol protocol() {
-                    return ApplicationProtocolConfig.Protocol.NONE;
-                }
-
-                @Override
-                public List<String> protocols() {
-                    return Collections.emptyList();
-                }
-
-                @Override
-                public ApplicationProtocolConfig.SelectorFailureBehavior selectorFailureBehavior() {
-                    return ApplicationProtocolConfig.SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL;
-                }
-
-                @Override
-                public ApplicationProtocolConfig.SelectedListenerFailureBehavior selectedListenerFailureBehavior() {
-                    return ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT;
-                }
-            };
-
-    static {
-        List<String> ciphers = new ArrayList<String>();
-        // XXX: Make sure to sync this list with JdkSslEngineFactory.
-        Collections.addAll(
-                ciphers,
-                "ECDHE-ECDSA-AES256-GCM-SHA384",
-                "ECDHE-ECDSA-AES128-GCM-SHA256",
-                "ECDHE-RSA-AES128-GCM-SHA256",
-                "ECDHE-RSA-AES128-SHA",
-                "ECDHE-RSA-AES256-SHA",
-                "AES128-GCM-SHA256",
-                "AES128-SHA",
-                "AES256-SHA");
-        DEFAULT_CIPHERS = Collections.unmodifiableList(ciphers);
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("Default cipher suite (OpenSSL): " + ciphers);
-        }
-
-        Integer dhLen = null;
-
-        try {
-            String dhKeySize = AccessController.doPrivileged(new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return SystemPropertyUtil.get("jdk.tls.ephemeralDHKeySize");
-                }
-            });
-            if (dhKeySize != null) {
-                try {
-                    dhLen = Integer.valueOf(dhKeySize);
-                } catch (NumberFormatException e) {
-                    logger.debug("ReferenceCountedOpenSslContext supports -Djdk.tls.ephemeralDHKeySize={int}, but got: "
-                            + dhKeySize);
-                }
-            }
-        } catch (Throwable ignore) {
-            // ignore
-        }
-        DH_KEY_LENGTH = dhLen;
-    }
-
-    ReferenceCountedOpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
-                                   ApplicationProtocolConfig apnCfg, long sessionCacheSize, long sessionTimeout,
-                                   int mode, Certificate[] keyCertChain, ClientAuth clientAuth, boolean startTls,
-                                   boolean leakDetection) throws SSLException {
-        this(ciphers, cipherFilter, toNegotiator(apnCfg), sessionCacheSize, sessionTimeout, mode, keyCertChain,
-                clientAuth, startTls, leakDetection);
-    }
-
-    ReferenceCountedOpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
-                                   OpenSslApplicationProtocolNegotiator apn, long sessionCacheSize,
-                                   long sessionTimeout, int mode, Certificate[] keyCertChain,
-                                   ClientAuth clientAuth, boolean startTls, boolean leakDetection) throws SSLException {
-        super(startTls);
-
-        OpenSsl.ensureAvailability();
-
-        if (mode != SSL.SSL_MODE_SERVER && mode != SSL.SSL_MODE_CLIENT) {
-            throw new IllegalArgumentException("mode most be either SSL.SSL_MODE_SERVER or SSL.SSL_MODE_CLIENT");
-        }
-        leak = leakDetection ? leakDetector.open(this) : null;
-        this.mode = mode;
-        this.clientAuth = isServer() ? checkNotNull(clientAuth, "clientAuth") : ClientAuth.NONE;
-
-        if (mode == SSL.SSL_MODE_SERVER) {
-            rejectRemoteInitiatedRenegotiation =
-                    JDK_REJECT_CLIENT_INITIATED_RENEGOTIATION;
-        }
-        this.keyCertChain = keyCertChain == null ? null : keyCertChain.clone();
-        final List<String> convertedCiphers;
-        if (ciphers == null) {
-            convertedCiphers = null;
-        } else {
-            convertedCiphers = new ArrayList<String>();
-            for (String c : ciphers) {
-                if (c == null) {
-                    break;
-                }
-
-                String converted = CipherSuiteConverter.toOpenSsl(c);
-                if (converted != null) {
-                    c = converted;
-                }
-                convertedCiphers.add(c);
-            }
-        }
-
-        unmodifiableCiphers = Arrays.asList(checkNotNull(cipherFilter, "cipherFilter").filterCipherSuites(
-                convertedCiphers, DEFAULT_CIPHERS, OpenSsl.availableCipherSuites()));
-
-        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);
-                } catch (Exception e) {
-                    throw new SSLException("failed to create an SSL_CTX", e);
-                }
-
-                SSLContext.setOptions(ctx, SSL.SSL_OP_ALL);
-                SSLContext.setOptions(ctx, SSL.SSL_OP_NO_SSLv2);
-                SSLContext.setOptions(ctx, SSL.SSL_OP_NO_SSLv3);
-                SSLContext.setOptions(ctx, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
-                SSLContext.setOptions(ctx, SSL.SSL_OP_SINGLE_ECDH_USE);
-                SSLContext.setOptions(ctx, SSL.SSL_OP_SINGLE_DH_USE);
-                SSLContext.setOptions(ctx, SSL.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
-                // Disable ticket support by default to be more inline with SSLEngineImpl of the JDK.
-                // This also let SSLSession.getId() work the same way for the JDK implementation and the OpenSSLEngine.
-                // If tickets are supported SSLSession.getId() will only return an ID on the server-side if it could
-                // make use of tickets.
-                SSLContext.setOptions(ctx, SSL.SSL_OP_NO_TICKET);
-
-                // We need to enable SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER as the memory address may change between
-                // calling OpenSSLEngine.wrap(...).
-                // See https://github.com/netty/netty-tcnative/issues/100
-                SSLContext.setMode(ctx, SSLContext.getMode(ctx) | SSL.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
-                if (DH_KEY_LENGTH != null) {
-                    SSLContext.setTmpDHLength(ctx, DH_KEY_LENGTH);
-                }
-
-                /* List the ciphers that are permitted to negotiate. */
-                try {
-                    SSLContext.setCipherSuite(ctx, CipherSuiteConverter.toOpenSsl(unmodifiableCiphers));
-                } catch (SSLException e) {
-                    throw e;
-                } catch (Exception e) {
-                    throw new SSLException("failed to set cipher suite: " + unmodifiableCiphers, e);
-                }
-
-                List<String> nextProtoList = apn.protocols();
-                /* Set next protocols for next protocol negotiation extension, if specified */
-                if (!nextProtoList.isEmpty()) {
-                    String[] protocols = nextProtoList.toArray(new String[nextProtoList.size()]);
-                    int selectorBehavior = opensslSelectorFailureBehavior(apn.selectorFailureBehavior());
-
-                    switch (apn.protocol()) {
-                        case NPN:
-                            SSLContext.setNpnProtos(ctx, protocols, selectorBehavior);
-                            break;
-                        case ALPN:
-                            SSLContext.setAlpnProtos(ctx, protocols, selectorBehavior);
-                            break;
-                        case NPN_AND_ALPN:
-                            SSLContext.setNpnProtos(ctx, protocols, selectorBehavior);
-                            SSLContext.setAlpnProtos(ctx, protocols, selectorBehavior);
-                            break;
-                        default:
-                            throw new Error();
-                    }
-                }
-
-                /* Set session cache size, if specified */
-                if (sessionCacheSize > 0) {
-                    this.sessionCacheSize = sessionCacheSize;
-                    SSLContext.setSessionCacheSize(ctx, sessionCacheSize);
-                } else {
-                    // Get the default session cache size using SSLContext.setSessionCacheSize()
-                    this.sessionCacheSize = sessionCacheSize = SSLContext.setSessionCacheSize(ctx, 20480);
-                    // Revert the session cache size to the default value.
-                    SSLContext.setSessionCacheSize(ctx, sessionCacheSize);
-                }
-
-                /* Set session timeout, if specified */
-                if (sessionTimeout > 0) {
-                    this.sessionTimeout = sessionTimeout;
-                    SSLContext.setSessionCacheTimeout(ctx, sessionTimeout);
-                } else {
-                    // Get the default session timeout using SSLContext.setSessionCacheTimeout()
-                    this.sessionTimeout = sessionTimeout = SSLContext.setSessionCacheTimeout(ctx, 300);
-                    // Revert the session timeout to the default value.
-                    SSLContext.setSessionCacheTimeout(ctx, sessionTimeout);
-                }
-            }
-            success = true;
-        } finally {
-            if (!success) {
-                release();
-            }
-        }
-    }
-
-    private static int opensslSelectorFailureBehavior(ApplicationProtocolConfig.SelectorFailureBehavior behavior) {
-        switch (behavior) {
-            case NO_ADVERTISE:
-                return SSL.SSL_SELECTOR_FAILURE_NO_ADVERTISE;
-            case CHOOSE_MY_LAST_PROTOCOL:
-                return SSL.SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL;
-            default:
-                throw new Error();
-        }
-    }
-
-    @Override
-    public final List<String> cipherSuites() {
-        return unmodifiableCiphers;
-    }
-
-    @Override
-    public final long sessionCacheSize() {
-        return sessionCacheSize;
-    }
-
-    @Override
-    public final long sessionTimeout() {
-        return sessionTimeout;
-    }
-
-    @Override
-    public ApplicationProtocolNegotiator applicationProtocolNegotiator() {
-        return apn;
-    }
-
-    @Override
-    public final boolean isClient() {
-        return mode == SSL.SSL_MODE_CLIENT;
-    }
-
-    @Override
-    public final SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort) {
-        return newEngine0(alloc, peerHost, peerPort);
-    }
-
-    SSLEngine newEngine0(ByteBufAllocator alloc, String peerHost, int peerPort) {
-        return new ReferenceCountedOpenSslEngine(this, alloc, peerHost, peerPort, true);
-    }
-
-    abstract OpenSslKeyMaterialManager keyMaterialManager();
-
-    /**
-     * Returns a new server-side {@link SSLEngine} with the current configuration.
-     */
-    @Override
-    public final SSLEngine newEngine(ByteBufAllocator alloc) {
-        return newEngine(alloc, null, -1);
-    }
-
-    /**
-     * Returns the pointer to the {@code SSL_CTX} object for this {@link ReferenceCountedOpenSslContext}.
-     * Be aware that it is freed as soon as the {@link #finalize()}  method is called.
-     * At this point {@code 0} will be returned.
-     *
-     * @deprecated use {@link #sslCtxPointer()}
-     */
-    @Deprecated
-    public final long context() {
-        return ctx;
-    }
-
-    /**
-     * Returns the stats of this context.
-     *
-     * @deprecated use {@link #sessionContext#stats()}
-     */
-    @Deprecated
-    public final OpenSslSessionStats stats() {
-        return sessionContext().stats();
-    }
-
-    /**
-     * Specify if remote initiated renegotiation is supported or not. If not supported and the remote side tries
-     * to initiate a renegotiation a {@link SSLHandshakeException} will be thrown during decoding.
-     */
-    public void setRejectRemoteInitiatedRenegotiation(boolean rejectRemoteInitiatedRenegotiation) {
-        this.rejectRemoteInitiatedRenegotiation = rejectRemoteInitiatedRenegotiation;
-    }
-
-    /**
-     * Sets the SSL session ticket keys of this context.
-     *
-     * @deprecated use {@link OpenSslSessionContext#setTicketKeys(byte[])}
-     */
-    @Deprecated
-    public final void setTicketKeys(byte[] keys) {
-        sessionContext().setTicketKeys(keys);
-    }
-
-    @Override
-    public abstract OpenSslSessionContext sessionContext();
-
-    /**
-     * Returns the pointer to the {@code SSL_CTX} object for this {@link ReferenceCountedOpenSslContext}.
-     * Be aware that it is freed as soon as the {@link #release()}  method is called.
-     * At this point {@code 0} will be returned.
-     */
-    public final long sslCtxPointer() {
-        return ctx;
-    }
-
-    // IMPORTANT: This method must only be called from either the constructor or the finalizer as a user MUST never
-    //            get access to an OpenSslSessionContext after this method was called to prevent the user from
-    //            producing a segfault.
-    final void destroy() {
-        synchronized (ReferenceCountedOpenSslContext.class) {
-            if (ctx != 0) {
-                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;
-            }
-        }
-    }
-
-    protected static X509Certificate[] certificates(byte[][] chain) {
-        X509Certificate[] peerCerts = new X509Certificate[chain.length];
-        for (int i = 0; i < peerCerts.length; i++) {
-            peerCerts[i] = new OpenSslX509Certificate(chain[i]);
-        }
-        return peerCerts;
-    }
-
-    protected static X509TrustManager chooseTrustManager(TrustManager[] managers) {
-        for (TrustManager m : managers) {
-            if (m instanceof X509TrustManager) {
-                return (X509TrustManager) m;
-            }
-        }
-        throw new IllegalStateException("no X509TrustManager found");
-    }
-
-    protected static X509KeyManager chooseX509KeyManager(KeyManager[] kms) {
-        for (KeyManager km : kms) {
-            if (km instanceof X509KeyManager) {
-                return (X509KeyManager) km;
-            }
-        }
-        throw new IllegalStateException("no X509KeyManager found");
-    }
-
-    /**
-     * Translate a {@link ApplicationProtocolConfig} object to a
-     * {@link OpenSslApplicationProtocolNegotiator} object.
-     *
-     * @param config The configuration which defines the translation
-     * @return The results of the translation
-     */
-    static OpenSslApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig config) {
-        if (config == null) {
-            return NONE_PROTOCOL_NEGOTIATOR;
-        }
-
-        switch (config.protocol()) {
-            case NONE:
-                return NONE_PROTOCOL_NEGOTIATOR;
-            case ALPN:
-            case NPN:
-            case NPN_AND_ALPN:
-                switch (config.selectedListenerFailureBehavior()) {
-                    case CHOOSE_MY_LAST_PROTOCOL:
-                    case ACCEPT:
-                        switch (config.selectorFailureBehavior()) {
-                            case CHOOSE_MY_LAST_PROTOCOL:
-                            case NO_ADVERTISE:
-                                return new OpenSslDefaultApplicationProtocolNegotiator(
-                                        config);
-                            default:
-                                throw new UnsupportedOperationException(
-                                        new StringBuilder("OpenSSL provider does not support ")
-                                                .append(config.selectorFailureBehavior())
-                                                .append(" behavior").toString());
-                        }
-                    default:
-                        throw new UnsupportedOperationException(
-                                new StringBuilder("OpenSSL provider does not support ")
-                                        .append(config.selectedListenerFailureBehavior())
-                                        .append(" behavior").toString());
-                }
-            default:
-                throw new Error();
-        }
-    }
-
-    static boolean useExtendedTrustManager(X509TrustManager trustManager) {
-        return PlatformDependent.javaVersion() >= 7 && trustManager instanceof X509ExtendedTrustManager;
-    }
-
-    static boolean useExtendedKeyManager(X509KeyManager keyManager) {
-        return PlatformDependent.javaVersion() >= 7 && keyManager instanceof X509ExtendedKeyManager;
-    }
-
-    @Override
-    public final int refCnt() {
-        return refCnt.refCnt();
-    }
-
-    @Override
-    public final ReferenceCounted retain() {
-        refCnt.retain();
-        return this;
-    }
-
-    @Override
-    public final ReferenceCounted retain(int increment) {
-        refCnt.retain(increment);
-        return this;
-    }
-
-    @Override
-    public final boolean release() {
-        return refCnt.release();
-    }
-
-    @Override
-    public final boolean release(int decrement) {
-        return refCnt.release(decrement);
-    }
-
-    abstract static class AbstractCertificateVerifier implements CertificateVerifier {
-        private final OpenSslEngineMap engineMap;
-
-        AbstractCertificateVerifier(OpenSslEngineMap engineMap) {
-            this.engineMap = engineMap;
-        }
-
-        @Override
-        public final int verify(long ssl, byte[][] chain, String auth) {
-            X509Certificate[] peerCerts = certificates(chain);
-            final ReferenceCountedOpenSslEngine engine = engineMap.get(ssl);
-            try {
-                verify(engine, peerCerts, auth);
-                return CertificateVerifier.X509_V_OK;
-            } catch (Throwable cause) {
-                logger.debug("verification of certificate failed", cause);
-                SSLHandshakeException e = new SSLHandshakeException("General OpenSslEngine problem");
-                e.initCause(cause);
-                engine.handshakeException = e;
-
-                if (cause instanceof OpenSslCertificateException) {
-                    return ((OpenSslCertificateException) cause).errorCode();
-                }
-                if (cause instanceof CertificateExpiredException) {
-                    return CertificateVerifier.X509_V_ERR_CERT_HAS_EXPIRED;
-                }
-                if (cause instanceof CertificateNotYetValidException) {
-                    return CertificateVerifier.X509_V_ERR_CERT_NOT_YET_VALID;
-                }
-                if (PlatformDependent.javaVersion() >= 7 && cause instanceof CertificateRevokedException) {
-                    return CertificateVerifier.X509_V_ERR_CERT_REVOKED;
-                }
-                return CertificateVerifier.X509_V_ERR_UNSPECIFIED;
-            }
-        }
-
-        abstract void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts,
-                             String auth) throws Exception;
-    }
-
-    private static final class DefaultOpenSslEngineMap implements OpenSslEngineMap {
-        private final Map<Long, ReferenceCountedOpenSslEngine> engines = PlatformDependent.newConcurrentHashMap();
-
-        @Override
-        public ReferenceCountedOpenSslEngine remove(long ssl) {
-            return engines.remove(ssl);
-        }
-
-        @Override
-        public void add(ReferenceCountedOpenSslEngine engine) {
-            engines.put(engine.sslPointer(), engine);
-        }
-
-        @Override
-        public ReferenceCountedOpenSslEngine get(long ssl) {
-            return engines.get(ssl);
-        }
-    }
-
-    static void setKeyMaterial(long ctx, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword)
-            throws SSLException {
-         /* Load the certificate file and private key. */
-        long keyBio = 0;
-        long keyCertChainBio = 0;
-        long keyCertChainBio2 = 0;
-        PemEncoded encoded = null;
-        try {
-            // Only encode one time
-            encoded = PemX509Certificate.toPEM(ByteBufAllocator.DEFAULT, true, keyCertChain);
-            keyCertChainBio = toBIO(ByteBufAllocator.DEFAULT, encoded.retain());
-            keyCertChainBio2 = toBIO(ByteBufAllocator.DEFAULT, encoded.retain());
-
-            if (key != null) {
-                keyBio = toBIO(key);
-            }
-
-            SSLContext.setCertificateBio(
-                    ctx, keyCertChainBio, keyBio,
-                    keyPassword == null ? StringUtil.EMPTY_STRING : keyPassword);
-            // We may have more then one cert in the chain so add all of them now.
-            SSLContext.setCertificateChainBio(ctx, keyCertChainBio2, true);
-        } catch (SSLException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new SSLException("failed to set certificate and key", e);
-        } finally {
-            freeBio(keyBio);
-            freeBio(keyCertChainBio);
-            freeBio(keyCertChainBio2);
-            if (encoded != null) {
-                encoded.release();
-            }
-        }
-    }
-
-    static void freeBio(long bio) {
-        if (bio != 0) {
-            SSL.freeBIO(bio);
-        }
-    }
-
-    /**
-     * Return the pointer to a <a href="https://www.openssl.org/docs/crypto/BIO_get_mem_ptr.html">in-memory BIO</a>
-     * or {@code 0} if the {@code key} is {@code null}. The BIO contains the content of the {@code key}.
-     */
-    static long toBIO(PrivateKey key) throws Exception {
-        if (key == null) {
-            return 0;
-        }
-
-        ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
-        PemEncoded pem = PemPrivateKey.toPEM(allocator, true, key);
-        try {
-            return toBIO(allocator, pem.retain());
-        } finally {
-            pem.release();
-        }
-    }
-
-    /**
-     * Return the pointer to a <a href="https://www.openssl.org/docs/crypto/BIO_get_mem_ptr.html">in-memory BIO</a>
-     * or {@code 0} if the {@code certChain} is {@code null}. The BIO contains the content of the {@code certChain}.
-     */
-    static long toBIO(X509Certificate... certChain) throws Exception {
-        if (certChain == null) {
-            return 0;
-        }
-
-        if (certChain.length == 0) {
-            throw new IllegalArgumentException("certChain can't be empty");
-        }
-
-        ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
-        PemEncoded pem = PemX509Certificate.toPEM(allocator, true, certChain);
-        try {
-            return toBIO(allocator, pem.retain());
-        } finally {
-            pem.release();
-        }
-    }
-
-    static long toBIO(ByteBufAllocator allocator, PemEncoded pem) throws Exception {
-        try {
-            // We can turn direct buffers straight into BIOs. No need to
-            // make a yet another copy.
-            ByteBuf content = pem.content();
-
-            if (content.isDirect()) {
-                return newBIO(content.slice().retain());
-            }
-
-            ByteBuf buffer = allocator.directBuffer(content.readableBytes());
-            try {
-                buffer.writeBytes(content, content.readerIndex(), content.readableBytes());
-                return newBIO(buffer.slice().retain());
-            } finally {
-                try {
-                    // If the contents of the ByteBuf is sensitive (e.g. a PrivateKey) we
-                    // need to zero out the bytes of the copy before we're releasing it.
-                    if (pem.isSensitive()) {
-                        SslUtils.zeroout(buffer);
-                    }
-                } finally {
-                    buffer.release();
-                }
-            }
-        } finally {
-            pem.release();
-        }
-    }
-
-    private static long newBIO(ByteBuf buffer) throws Exception {
-        try {
-            long bio = SSL.newMemBIO();
-            int readable = buffer.readableBytes();
-            if (SSL.writeToBIO(bio, OpenSsl.memoryAddress(buffer) + buffer.readerIndex(), readable) != readable) {
-                SSL.freeBIO(bio);
-                throw new IllegalStateException("Could not write data to memory BIO");
-            }
-            return bio;
-        } finally {
-            buffer.release();
-        }
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java
deleted file mode 100644
index 6b28ca0..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java
+++ /dev/null
@@ -1,1936 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufAllocator;
-import io.netty.buffer.Unpooled;
-import io.netty.util.AbstractReferenceCounted;
-import io.netty.util.ReferenceCounted;
-import io.netty.util.ResourceLeak;
-import io.netty.util.ResourceLeakDetector;
-import io.netty.util.ResourceLeakDetectorFactory;
-import io.netty.util.internal.EmptyArrays;
-import io.netty.util.internal.InternalThreadLocalMap;
-import io.netty.util.internal.PlatformDependent;
-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 java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.nio.ReadOnlyBufferException;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSessionContext;
-import javax.security.cert.X509Certificate;
-
-import static io.netty.handler.ssl.OpenSsl.memoryAddress;
-import static io.netty.util.internal.ObjectUtil.checkNotNull;
-import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED;
-import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
-import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_WRAP;
-import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
-import static javax.net.ssl.SSLEngineResult.Status.BUFFER_OVERFLOW;
-import static javax.net.ssl.SSLEngineResult.Status.CLOSED;
-import static javax.net.ssl.SSLEngineResult.Status.OK;
-
-/**
- * Implements a {@link SSLEngine} using
- * <a href="https://www.openssl.org/docs/crypto/BIO_s_bio.html#EXAMPLE">OpenSSL BIO abstractions</a>.
- * <p>Instances of this class must be {@link #release() released} or else native memory will leak!
- *
- * <p>Instances of this class <strong>must</strong> be released before the {@link ReferenceCountedOpenSslContext}
- * the instance depends upon are released. Otherwise if any method of this class is called which uses the
- * the {@link ReferenceCountedOpenSslContext} JNI resources the JVM may crash.
- */
-public class ReferenceCountedOpenSslEngine extends SSLEngine implements ReferenceCounted {
-
-    private static final InternalLogger logger = InternalLoggerFactory.getInstance(ReferenceCountedOpenSslEngine.class);
-
-    private static final SSLException BEGIN_HANDSHAKE_ENGINE_CLOSED = ThrowableUtil.unknownStackTrace(
-            new SSLException("engine closed"), ReferenceCountedOpenSslEngine.class, "beginHandshake()");
-    private static final SSLException HANDSHAKE_ENGINE_CLOSED = ThrowableUtil.unknownStackTrace(
-            new SSLException("engine closed"), ReferenceCountedOpenSslEngine.class, "handshake()");
-    private static final SSLException RENEGOTIATION_UNSUPPORTED =  ThrowableUtil.unknownStackTrace(
-            new SSLException("renegotiation unsupported"), ReferenceCountedOpenSslEngine.class, "beginHandshake()");
-    private static final SSLException ENCRYPTED_PACKET_OVERSIZED = ThrowableUtil.unknownStackTrace(
-            new SSLException("encrypted packet oversized"), ReferenceCountedOpenSslEngine.class, "unwrap(...)");
-    private static final Class<?> SNI_HOSTNAME_CLASS;
-    private static final Method GET_SERVER_NAMES_METHOD;
-    private static final Method SET_SERVER_NAMES_METHOD;
-    private static final Method GET_ASCII_NAME_METHOD;
-    private static final Method GET_USE_CIPHER_SUITES_ORDER_METHOD;
-    private static final Method SET_USE_CIPHER_SUITES_ORDER_METHOD;
-    private static final ResourceLeakDetector<ReferenceCountedOpenSslEngine> leakDetector =
-            ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ReferenceCountedOpenSslEngine.class);
-
-    static {
-        AtomicIntegerFieldUpdater<ReferenceCountedOpenSslEngine> destroyedUpdater =
-                PlatformDependent.newAtomicIntegerFieldUpdater(ReferenceCountedOpenSslEngine.class, "destroyed");
-        if (destroyedUpdater == null) {
-            destroyedUpdater = AtomicIntegerFieldUpdater.newUpdater(ReferenceCountedOpenSslEngine.class, "destroyed");
-        }
-        DESTROYED_UPDATER = destroyedUpdater;
-
-        Method getUseCipherSuitesOrderMethod = null;
-        Method setUseCipherSuitesOrderMethod = null;
-        Class<?> sniHostNameClass = null;
-        Method getAsciiNameMethod = null;
-        Method getServerNamesMethod = null;
-        Method setServerNamesMethod = null;
-        if (PlatformDependent.javaVersion() >= 8) {
-            try {
-                getUseCipherSuitesOrderMethod = SSLParameters.class.getDeclaredMethod("getUseCipherSuitesOrder");
-                SSLParameters parameters = new SSLParameters();
-                @SuppressWarnings("unused")
-                Boolean order = (Boolean) getUseCipherSuitesOrderMethod.invoke(parameters);
-                setUseCipherSuitesOrderMethod = SSLParameters.class.getDeclaredMethod("setUseCipherSuitesOrder",
-                        boolean.class);
-                setUseCipherSuitesOrderMethod.invoke(parameters, true);
-            } catch (Throwable ignore) {
-                getUseCipherSuitesOrderMethod = null;
-                setUseCipherSuitesOrderMethod = null;
-            }
-            try {
-                sniHostNameClass = Class.forName("javax.net.ssl.SNIHostName", false,
-                        PlatformDependent.getClassLoader(ReferenceCountedOpenSslEngine.class));
-                Object sniHostName = sniHostNameClass.getConstructor(String.class).newInstance("netty.io");
-                getAsciiNameMethod = sniHostNameClass.getDeclaredMethod("getAsciiName");
-                @SuppressWarnings("unused")
-                String name = (String) getAsciiNameMethod.invoke(sniHostName);
-
-                getServerNamesMethod = SSLParameters.class.getDeclaredMethod("getServerNames");
-                setServerNamesMethod = SSLParameters.class.getDeclaredMethod("setServerNames", List.class);
-                SSLParameters parameters = new SSLParameters();
-                @SuppressWarnings({ "rawtypes", "unused" })
-                List serverNames = (List) getServerNamesMethod.invoke(parameters);
-                setServerNamesMethod.invoke(parameters, Collections.emptyList());
-            } catch (Throwable ingore) {
-                sniHostNameClass = null;
-                getAsciiNameMethod = null;
-                getServerNamesMethod = null;
-                setServerNamesMethod = null;
-            }
-        }
-        GET_USE_CIPHER_SUITES_ORDER_METHOD = getUseCipherSuitesOrderMethod;
-        SET_USE_CIPHER_SUITES_ORDER_METHOD = setUseCipherSuitesOrderMethod;
-        SNI_HOSTNAME_CLASS = sniHostNameClass;
-        GET_ASCII_NAME_METHOD = getAsciiNameMethod;
-        GET_SERVER_NAMES_METHOD = getServerNamesMethod;
-        SET_SERVER_NAMES_METHOD = setServerNamesMethod;
-    }
-
-    private static final int MAX_PLAINTEXT_LENGTH = 16 * 1024; // 2^14
-    private static final int MAX_COMPRESSED_LENGTH = MAX_PLAINTEXT_LENGTH + 1024;
-    private static final int MAX_CIPHERTEXT_LENGTH = MAX_COMPRESSED_LENGTH + 1024;
-
-    // Header (5) + Data (2^14) + Compression (1024) + Encryption (1024) + MAC (20) + Padding (256)
-    static final int MAX_ENCRYPTED_PACKET_LENGTH = MAX_CIPHERTEXT_LENGTH + 5 + 20 + 256;
-
-    static final int MAX_ENCRYPTION_OVERHEAD_LENGTH = MAX_ENCRYPTED_PACKET_LENGTH - MAX_PLAINTEXT_LENGTH;
-
-    private static final AtomicIntegerFieldUpdater<ReferenceCountedOpenSslEngine> DESTROYED_UPDATER;
-
-    private static final String INVALID_CIPHER = "SSL_NULL_WITH_NULL_NULL";
-
-    private static final long EMPTY_ADDR = Buffer.address(Unpooled.EMPTY_BUFFER.nioBuffer());
-
-    private static final SSLEngineResult NEED_UNWRAP_OK = new SSLEngineResult(OK, NEED_UNWRAP, 0, 0);
-    private static final SSLEngineResult NEED_UNWRAP_CLOSED = new SSLEngineResult(CLOSED, NEED_UNWRAP, 0, 0);
-    private static final SSLEngineResult NEED_WRAP_OK = new SSLEngineResult(OK, NEED_WRAP, 0, 0);
-    private static final SSLEngineResult NEED_WRAP_CLOSED = new SSLEngineResult(CLOSED, NEED_WRAP, 0, 0);
-    private static final SSLEngineResult CLOSED_NOT_HANDSHAKING = new SSLEngineResult(CLOSED, NOT_HANDSHAKING, 0, 0);
-
-    // OpenSSL state
-    private long ssl;
-    private long networkBIO;
-    private boolean certificateSet;
-
-    private enum HandshakeState {
-        /**
-         * Not started yet.
-         */
-        NOT_STARTED,
-        /**
-         * Started via unwrap/wrap.
-         */
-        STARTED_IMPLICITLY,
-        /**
-         * Started via {@link #beginHandshake()}.
-         */
-        STARTED_EXPLICITLY,
-
-        /**
-         * Handshake is finished.
-         */
-        FINISHED
-    }
-
-    private HandshakeState handshakeState = HandshakeState.NOT_STARTED;
-    private boolean receivedShutdown;
-    private volatile int destroyed;
-
-    // Reference Counting
-    private final ResourceLeak leak;
-    private final AbstractReferenceCounted refCnt = new AbstractReferenceCounted() {
-        @Override
-        protected void deallocate() {
-            shutdown();
-            if (leak != null) {
-                leak.close();
-            }
-        }
-    };
-
-    private volatile ClientAuth clientAuth = ClientAuth.NONE;
-
-    // Updated once a new handshake is started and so the SSLSession reused.
-    private volatile long lastAccessed = -1;
-
-    private String endPointIdentificationAlgorithm;
-    // Store as object as AlgorithmConstraints only exists since java 7.
-    private Object algorithmConstraints;
-    private List<?> sniHostNames;
-
-    // SSL Engine status variables
-    private boolean isInboundDone;
-    private boolean isOutboundDone;
-    private boolean engineClosed;
-
-    private final boolean clientMode;
-    private final ByteBufAllocator alloc;
-    private final OpenSslEngineMap engineMap;
-    private final OpenSslApplicationProtocolNegotiator apn;
-    private final boolean rejectRemoteInitiatedRenegation;
-    private final OpenSslSession session;
-    private final Certificate[] localCerts;
-    private final ByteBuffer[] singleSrcBuffer = new ByteBuffer[1];
-    private final ByteBuffer[] singleDstBuffer = new ByteBuffer[1];
-    private final OpenSslKeyMaterialManager keyMaterialManager;
-
-    // This is package-private as we set it from OpenSslContext if an exception is thrown during
-    // the verification step.
-    SSLHandshakeException handshakeException;
-
-    /**
-     * Create a new instance.
-     * @param context Reference count release responsibility is not transferred! The callee still owns this object.
-     * @param alloc The allocator to use.
-     * @param peerHost The peer host name.
-     * @param peerPort The peer port.
-     * @param leakDetection {@code true} to enable leak detection of this object.
-     */
-    ReferenceCountedOpenSslEngine(ReferenceCountedOpenSslContext context, ByteBufAllocator alloc, String peerHost,
-                                  int peerPort, boolean leakDetection) {
-        super(peerHost, peerPort);
-        OpenSsl.ensureAvailability();
-        leak = leakDetection ? leakDetector.open(this) : null;
-        this.alloc = checkNotNull(alloc, "alloc");
-        apn = (OpenSslApplicationProtocolNegotiator) context.applicationProtocolNegotiator();
-        ssl = SSL.newSSL(context.ctx, !context.isClient());
-        session = new ReferenceCountedOpenSslEngine.OpenSslSession(context.sessionContext());
-        networkBIO = SSL.makeNetworkBIO(ssl);
-        clientMode = context.isClient();
-        engineMap = context.engineMap;
-        rejectRemoteInitiatedRenegation = context.rejectRemoteInitiatedRenegotiation;
-        localCerts = context.keyCertChain;
-
-        // Set the client auth mode, this needs to be done via setClientAuth(...) method so we actually call the
-        // needed JNI methods.
-        setClientAuth(clientMode ? ClientAuth.NONE : context.clientAuth);
-
-        // Use SNI if peerHost was specified
-        // See https://github.com/netty/netty/issues/4746
-        if (clientMode && peerHost != null) {
-            SSL.setTlsExtHostName(ssl, peerHost);
-        }
-        keyMaterialManager = context.keyMaterialManager();
-    }
-
-    @Override
-    public final int refCnt() {
-        return refCnt.refCnt();
-    }
-
-    @Override
-    public final ReferenceCounted retain() {
-        refCnt.retain();
-        return this;
-    }
-
-    @Override
-    public final ReferenceCounted retain(int increment) {
-        refCnt.retain(increment);
-        return this;
-    }
-
-    @Override
-    public final boolean release() {
-        return refCnt.release();
-    }
-
-    @Override
-    public final boolean release(int decrement) {
-        return refCnt.release(decrement);
-    }
-
-    @Override
-    public final synchronized SSLSession getHandshakeSession() {
-        // Javadocs state return value should be:
-        // null if this instance is not currently handshaking, or if the current handshake has not
-        // progressed far enough to create a basic SSLSession. Otherwise, this method returns the
-        // SSLSession currently being negotiated.
-        switch(handshakeState) {
-            case NOT_STARTED:
-            case FINISHED:
-                return null;
-            default:
-                return session;
-        }
-    }
-
-    /**
-     * Returns the pointer to the {@code SSL} object for this {@link ReferenceCountedOpenSslEngine}.
-     * Be aware that it is freed as soon as the {@link #release()} or {@link #shutdown()} methods are called.
-     * At this point {@code 0} will be returned.
-     */
-    public final synchronized long sslPointer() {
-        return ssl;
-    }
-
-    /**
-     * Destroys this engine.
-     */
-    public final synchronized void shutdown() {
-        if (DESTROYED_UPDATER.compareAndSet(this, 0, 1)) {
-            engineMap.remove(ssl);
-            SSL.freeSSL(ssl);
-            SSL.freeBIO(networkBIO);
-            ssl = networkBIO = 0;
-
-            // internal errors can cause shutdown without marking the engine closed
-            isInboundDone = isOutboundDone = engineClosed = true;
-        }
-
-        // On shutdown clear all errors
-        SSL.clearError();
-    }
-
-    /**
-     * Write plaintext data to the OpenSSL internal BIO
-     *
-     * Calling this function with src.remaining == 0 is undefined.
-     */
-    private int writePlaintextData(final ByteBuffer src) {
-        final int pos = src.position();
-        final int limit = src.limit();
-        final int len = Math.min(limit - pos, MAX_PLAINTEXT_LENGTH);
-        final int sslWrote;
-
-        if (src.isDirect()) {
-            final long addr = Buffer.address(src) + pos;
-            sslWrote = SSL.writeToSSL(ssl, addr, len);
-            if (sslWrote > 0) {
-                src.position(pos + sslWrote);
-            }
-        } else {
-            ByteBuf buf = alloc.directBuffer(len);
-            try {
-                final long addr = memoryAddress(buf);
-
-                src.limit(pos + len);
-
-                buf.setBytes(0, src);
-                src.limit(limit);
-
-                sslWrote = SSL.writeToSSL(ssl, addr, len);
-                if (sslWrote > 0) {
-                    src.position(pos + sslWrote);
-                } else {
-                    src.position(pos);
-                }
-            } finally {
-                buf.release();
-            }
-        }
-        return sslWrote;
-    }
-
-    /**
-     * Write encrypted data to the OpenSSL network BIO.
-     */
-    private int writeEncryptedData(final ByteBuffer src) {
-        final int pos = src.position();
-        final int len = src.remaining();
-        final int netWrote;
-        if (src.isDirect()) {
-            final long addr = Buffer.address(src) + pos;
-            netWrote = SSL.writeToBIO(networkBIO, addr, len);
-            if (netWrote >= 0) {
-                src.position(pos + netWrote);
-            }
-        } else {
-            final ByteBuf buf = alloc.directBuffer(len);
-            try {
-                final long addr = memoryAddress(buf);
-
-                buf.setBytes(0, src);
-
-                netWrote = SSL.writeToBIO(networkBIO, addr, len);
-                if (netWrote >= 0) {
-                    src.position(pos + netWrote);
-                } else {
-                    src.position(pos);
-                }
-            } finally {
-                buf.release();
-            }
-        }
-
-        return netWrote;
-    }
-
-    /**
-     * Read plaintext data from the OpenSSL internal BIO
-     */
-    private int readPlaintextData(final ByteBuffer dst) {
-        final int sslRead;
-        if (dst.isDirect()) {
-            final int pos = dst.position();
-            final long addr = Buffer.address(dst) + pos;
-            final int len = dst.limit() - pos;
-            sslRead = SSL.readFromSSL(ssl, addr, len);
-            if (sslRead > 0) {
-                dst.position(pos + sslRead);
-            }
-        } else {
-            final int pos = dst.position();
-            final int limit = dst.limit();
-            final int len = Math.min(MAX_ENCRYPTED_PACKET_LENGTH, limit - pos);
-            final ByteBuf buf = alloc.directBuffer(len);
-            try {
-                final long addr = memoryAddress(buf);
-
-                sslRead = SSL.readFromSSL(ssl, addr, len);
-                if (sslRead > 0) {
-                    dst.limit(pos + sslRead);
-                    buf.getBytes(0, dst);
-                    dst.limit(limit);
-                }
-            } finally {
-                buf.release();
-            }
-        }
-
-        return sslRead;
-    }
-
-    /**
-     * Read encrypted data from the OpenSSL network BIO
-     */
-    private int readEncryptedData(final ByteBuffer dst, final int pending) {
-        final int bioRead;
-
-        if (dst.isDirect() && dst.remaining() >= pending) {
-            final int pos = dst.position();
-            final long addr = Buffer.address(dst) + pos;
-            bioRead = SSL.readFromBIO(networkBIO, addr, pending);
-            if (bioRead > 0) {
-                dst.position(pos + bioRead);
-                return bioRead;
-            }
-        } else {
-            final ByteBuf buf = alloc.directBuffer(pending);
-            try {
-                final long addr = memoryAddress(buf);
-
-                bioRead = SSL.readFromBIO(networkBIO, addr, pending);
-                if (bioRead > 0) {
-                    int oldLimit = dst.limit();
-                    dst.limit(dst.position() + bioRead);
-                    buf.getBytes(0, dst);
-                    dst.limit(oldLimit);
-                    return bioRead;
-                }
-            } finally {
-                buf.release();
-            }
-        }
-
-        return bioRead;
-    }
-
-    private SSLEngineResult readPendingBytesFromBIO(ByteBuffer dst, int bytesConsumed, int bytesProduced,
-                                                    SSLEngineResult.HandshakeStatus status) throws SSLException {
-        // Check to see if the engine wrote data into the network BIO
-        int pendingNet = SSL.pendingWrittenBytesInBIO(networkBIO);
-        if (pendingNet > 0) {
-
-            // Do we have enough room in dst to write encrypted data?
-            int capacity = dst.remaining();
-            if (capacity < pendingNet) {
-                return new SSLEngineResult(BUFFER_OVERFLOW,
-                        mayFinishHandshake(status != FINISHED ? getHandshakeStatus(pendingNet) : status),
-                        bytesConsumed, bytesProduced);
-            }
-
-            // Write the pending data from the network BIO into the dst buffer
-            int produced = readEncryptedData(dst, pendingNet);
-
-            if (produced <= 0) {
-                // We ignore BIO_* errors here as we use in memory BIO anyway and will do another SSL_* call later
-                // on in which we will produce an exception in case of an error
-                SSL.clearError();
-            } else {
-                bytesProduced += produced;
-                pendingNet -= produced;
-            }
-            // If isOuboundDone is set, then the data from the network BIO
-            // was the close_notify message -- we are not required to wait
-            // for the receipt the peer's close_notify message -- shutdown.
-            if (isOutboundDone) {
-                shutdown();
-            }
-
-            return new SSLEngineResult(getEngineStatus(),
-                    mayFinishHandshake(status != FINISHED ? getHandshakeStatus(pendingNet) : status),
-                    bytesConsumed, bytesProduced);
-        }
-        return null;
-    }
-
-    @Override
-    public final SSLEngineResult wrap(
-            final ByteBuffer[] srcs, final int offset, final int length, final ByteBuffer dst) throws SSLException {
-        // Throw required runtime exceptions
-        if (srcs == null) {
-            throw new IllegalArgumentException("srcs is null");
-        }
-        if (dst == null) {
-            throw new IllegalArgumentException("dst is null");
-        }
-
-        if (offset >= srcs.length || offset + length > srcs.length) {
-            throw new IndexOutOfBoundsException(
-                    "offset: " + offset + ", length: " + length +
-                            " (expected: offset <= offset + length <= srcs.length (" + srcs.length + "))");
-        }
-
-        if (dst.isReadOnly()) {
-            throw new ReadOnlyBufferException();
-        }
-
-        synchronized (this) {
-            // Check to make sure the engine has not been closed
-            if (isDestroyed()) {
-                return CLOSED_NOT_HANDSHAKING;
-            }
-
-            SSLEngineResult.HandshakeStatus status = NOT_HANDSHAKING;
-            // Prepare OpenSSL to work in server mode and receive handshake
-            if (handshakeState != HandshakeState.FINISHED) {
-                if (handshakeState != HandshakeState.STARTED_EXPLICITLY) {
-                    // Update accepted so we know we triggered the handshake via wrap
-                    handshakeState = HandshakeState.STARTED_IMPLICITLY;
-                }
-
-                status = handshake();
-                if (status == NEED_UNWRAP) {
-                    return NEED_UNWRAP_OK;
-                }
-
-                if (engineClosed) {
-                    return NEED_UNWRAP_CLOSED;
-                }
-            }
-
-            // There was no pending data in the network BIO -- encrypt any application data
-            int bytesProduced = 0;
-            int bytesConsumed = 0;
-            int endOffset = offset + length;
-            for (int i = offset; i < endOffset; ++i) {
-                final ByteBuffer src = srcs[i];
-                if (src == null) {
-                    throw new IllegalArgumentException("srcs[" + i + "] is null");
-                }
-                while (src.hasRemaining()) {
-                    final SSLEngineResult pendingNetResult;
-                    // Write plaintext application data to the SSL engine
-                    int result = writePlaintextData(src);
-                    if (result > 0) {
-                        bytesConsumed += result;
-
-                        pendingNetResult = readPendingBytesFromBIO(dst, bytesConsumed, bytesProduced, status);
-                        if (pendingNetResult != null) {
-                            if (pendingNetResult.getStatus() != OK) {
-                                return pendingNetResult;
-                            }
-                            bytesProduced = pendingNetResult.bytesProduced();
-                        }
-                    } else {
-                        int sslError = SSL.getError(ssl, result);
-                        switch (sslError) {
-                            case SSL.SSL_ERROR_ZERO_RETURN:
-                                // This means the connection was shutdown correctly, close inbound and outbound
-                                if (!receivedShutdown) {
-                                    closeAll();
-                                }
-                                pendingNetResult = readPendingBytesFromBIO(dst, bytesConsumed, bytesProduced, status);
-                                return pendingNetResult != null ? pendingNetResult : CLOSED_NOT_HANDSHAKING;
-                            case SSL.SSL_ERROR_WANT_READ:
-                                // If there is no pending data to read from BIO we should go back to event loop and try
-                                // to read more data [1]. It is also possible that event loop will detect the socket
-                                // has been closed. [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html
-                                pendingNetResult = readPendingBytesFromBIO(dst, bytesConsumed, bytesProduced, status);
-                                return pendingNetResult != null ? pendingNetResult :
-                                        new SSLEngineResult(getEngineStatus(),
-                                                NEED_UNWRAP, bytesConsumed, bytesProduced);
-                            case SSL.SSL_ERROR_WANT_WRITE:
-                                // SSL_ERROR_WANT_WRITE typically means that the underlying transport is not writable
-                                // and we should set the "want write" flag on the selector and try again when the
-                                // underlying transport is writable [1]. However we are not directly writing to the
-                                // underlying transport and instead writing to a BIO buffer. The OpenSsl documentation
-                                // says we should do the following [1]:
-                                //
-                                // "When using a buffering BIO, like a BIO pair, data must be written into or retrieved
-                                // out of the BIO before being able to continue."
-                                //
-                                // So we attempt to drain the BIO buffer below, but if there is no data this condition
-                                // is undefined and we assume their is a fatal error with the openssl engine and close.
-                                // [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html
-                                pendingNetResult = readPendingBytesFromBIO(dst, bytesConsumed, bytesProduced, status);
-                                return pendingNetResult != null ? pendingNetResult : NEED_WRAP_CLOSED;
-                            default:
-                                // Everything else is considered as error
-                                throw shutdownWithError("SSL_write");
-                        }
-                    }
-                }
-            }
-            // We need to check if pendingWrittenBytesInBIO was checked yet, as we may not checked if the srcs was
-            // empty, or only contained empty buffers.
-            if (bytesConsumed == 0) {
-                SSLEngineResult pendingNetResult = readPendingBytesFromBIO(dst, 0, bytesProduced, status);
-                if (pendingNetResult != null) {
-                    return pendingNetResult;
-                }
-            }
-
-            return newResult(bytesConsumed, bytesProduced, status);
-        }
-    }
-
-    /**
-     * Log the error, shutdown the engine and throw an exception.
-     */
-    private SSLException shutdownWithError(String operations) {
-        String err = SSL.getLastError();
-        return shutdownWithError(operations, err);
-    }
-
-    private SSLException shutdownWithError(String operation, String err) {
-        if (logger.isDebugEnabled()) {
-            logger.debug("{} failed: OpenSSL error: {}", operation, err);
-        }
-
-        // There was an internal error -- shutdown
-        shutdown();
-        if (handshakeState == HandshakeState.FINISHED) {
-            return new SSLException(err);
-        }
-        return new SSLHandshakeException(err);
-    }
-
-    public final SSLEngineResult unwrap(
-            final ByteBuffer[] srcs, int srcsOffset, final int srcsLength,
-            final ByteBuffer[] dsts, final int dstsOffset, final int dstsLength) throws SSLException {
-
-        // Throw required runtime exceptions
-        if (srcs == null) {
-            throw new NullPointerException("srcs");
-        }
-        if (srcsOffset >= srcs.length
-                || srcsOffset + srcsLength > srcs.length) {
-            throw new IndexOutOfBoundsException(
-                    "offset: " + srcsOffset + ", length: " + srcsLength +
-                            " (expected: offset <= offset + length <= srcs.length (" + srcs.length + "))");
-        }
-        if (dsts == null) {
-            throw new IllegalArgumentException("dsts is null");
-        }
-        if (dstsOffset >= dsts.length || dstsOffset + dstsLength > dsts.length) {
-            throw new IndexOutOfBoundsException(
-                    "offset: " + dstsOffset + ", length: " + dstsLength +
-                            " (expected: offset <= offset + length <= dsts.length (" + dsts.length + "))");
-        }
-        long capacity = 0;
-        final int endOffset = dstsOffset + dstsLength;
-        for (int i = dstsOffset; i < endOffset; i ++) {
-            ByteBuffer dst = dsts[i];
-            if (dst == null) {
-                throw new IllegalArgumentException("dsts[" + i + "] is null");
-            }
-            if (dst.isReadOnly()) {
-                throw new ReadOnlyBufferException();
-            }
-            capacity += dst.remaining();
-        }
-
-        final int srcsEndOffset = srcsOffset + srcsLength;
-        long len = 0;
-        for (int i = srcsOffset; i < srcsEndOffset; i++) {
-            ByteBuffer src = srcs[i];
-            if (src == null) {
-                throw new IllegalArgumentException("srcs[" + i + "] is null");
-            }
-            len += src.remaining();
-        }
-
-        synchronized (this) {
-            // Check to make sure the engine has not been closed
-            if (isDestroyed()) {
-                return CLOSED_NOT_HANDSHAKING;
-            }
-
-            // protect against protocol overflow attack vector
-            if (len > MAX_ENCRYPTED_PACKET_LENGTH) {
-                isInboundDone = true;
-                isOutboundDone = true;
-                engineClosed = true;
-                shutdown();
-                throw ENCRYPTED_PACKET_OVERSIZED;
-            }
-
-            SSLEngineResult.HandshakeStatus status = NOT_HANDSHAKING;
-            // Prepare OpenSSL to work in server mode and receive handshake
-            if (handshakeState != HandshakeState.FINISHED) {
-                if (handshakeState != HandshakeState.STARTED_EXPLICITLY) {
-                    // Update accepted so we know we triggered the handshake via wrap
-                    handshakeState = HandshakeState.STARTED_IMPLICITLY;
-                }
-
-                status = handshake();
-                if (status == NEED_WRAP) {
-                    return NEED_WRAP_OK;
-                }
-                if (engineClosed) {
-                    return NEED_WRAP_CLOSED;
-                }
-            }
-
-            // Write encrypted data to network BIO
-            int bytesConsumed = 0;
-            if (srcsOffset < srcsEndOffset) {
-                do {
-                    ByteBuffer src = srcs[srcsOffset];
-                    int remaining = src.remaining();
-                    if (remaining == 0) {
-                        // We must skip empty buffers as BIO_write will return 0 if asked to write something
-                        // with length 0.
-                        srcsOffset++;
-                        continue;
-                    }
-                    int written = writeEncryptedData(src);
-                    if (written > 0) {
-                        bytesConsumed += written;
-
-                        if (written == remaining) {
-                            srcsOffset++;
-                        } else {
-                            // We were not able to write everything into the BIO so break the write loop as otherwise
-                            // we will produce an error on the next write attempt, which will trigger a SSL.clearError()
-                            // later.
-                            break;
-                        }
-                    } else {
-                        // BIO_write returned a negative or zero number, this means we could not complete the write
-                        // operation and should retry later.
-                        // We ignore BIO_* errors here as we use in memory BIO anyway and will do another SSL_* call
-                        // later on in which we will produce an exception in case of an error
-                        SSL.clearError();
-                        break;
-                    }
-                } while (srcsOffset < srcsEndOffset);
-            }
-
-            // Number of produced bytes
-            int bytesProduced = 0;
-
-            if (capacity > 0) {
-                // Write decrypted data to dsts buffers
-                int idx = dstsOffset;
-                while (idx < endOffset) {
-                    ByteBuffer dst = dsts[idx];
-                    if (!dst.hasRemaining()) {
-                        idx++;
-                        continue;
-                    }
-
-                    int bytesRead = readPlaintextData(dst);
-
-                    // TODO: We may want to consider if we move this check and only do it in a less often called place
-                    // at the price of not being 100% accurate, like for example when calling SSL.getError(...).
-                    rejectRemoteInitiatedRenegation();
-
-                    if (bytesRead > 0) {
-                        bytesProduced += bytesRead;
-
-                        if (!dst.hasRemaining()) {
-                            idx++;
-                        } else {
-                            // We read everything return now.
-                            return newResult(bytesConsumed, bytesProduced, status);
-                        }
-                    } else {
-                        int sslError = SSL.getError(ssl, bytesRead);
-                        switch (sslError) {
-                            case SSL.SSL_ERROR_ZERO_RETURN:
-                                // This means the connection was shutdown correctly, close inbound and outbound
-                                if (!receivedShutdown) {
-                                    closeAll();
-                                }
-                                // fall-trough!
-                            case SSL.SSL_ERROR_WANT_READ:
-                            case SSL.SSL_ERROR_WANT_WRITE:
-                                // break to the outer loop
-                                return newResult(bytesConsumed, bytesProduced, status);
-                            default:
-                                return sslReadErrorResult(SSL.getLastErrorNumber(), bytesConsumed, bytesProduced);
-                        }
-                    }
-                }
-            } else {
-                // If the capacity of all destination buffers is 0 we need to trigger a SSL_read anyway to ensure
-                // everything is flushed in the BIO pair and so we can detect it in the pendingAppData() call.
-                if (SSL.readFromSSL(ssl, EMPTY_ADDR, 0) <= 0) {
-                    // We do not check SSL_get_error as we are not interested in any error that is not fatal.
-                    int err = SSL.getLastErrorNumber();
-                    if (OpenSsl.isError(err)) {
-                        return sslReadErrorResult(err, bytesConsumed, bytesProduced);
-                    }
-                }
-            }
-            if (pendingAppData() > 0) {
-                // We filled all buffers but there is still some data pending in the BIO buffer, return BUFFER_OVERFLOW.
-                return new SSLEngineResult(
-                        BUFFER_OVERFLOW, mayFinishHandshake(status != FINISHED ? getHandshakeStatus() : status),
-                        bytesConsumed, bytesProduced);
-            }
-
-            // Check to see if we received a close_notify message from the peer.
-            if (!receivedShutdown && (SSL.getShutdown(ssl) & SSL.SSL_RECEIVED_SHUTDOWN) == SSL.SSL_RECEIVED_SHUTDOWN) {
-                closeAll();
-            }
-
-            return newResult(bytesConsumed, bytesProduced, status);
-        }
-    }
-
-    private SSLEngineResult sslReadErrorResult(int err, int bytesConsumed, int bytesProduced) throws SSLException {
-        String errStr = SSL.getErrorString(err);
-
-        // Check if we have a pending handshakeException and if so see if we need to consume all pending data from the
-        // BIO first or can just shutdown and throw it now.
-        // This is needed so we ensure close_notify etc is correctly send to the remote peer.
-        // See https://github.com/netty/netty/issues/3900
-        if (SSL.pendingWrittenBytesInBIO(networkBIO) > 0) {
-            if (handshakeException == null && handshakeState != HandshakeState.FINISHED) {
-                // we seems to have data left that needs to be transfered and so the user needs
-                // call wrap(...). Store the error so we can pick it up later.
-                handshakeException = new SSLHandshakeException(errStr);
-            }
-            return new SSLEngineResult(OK, NEED_WRAP, bytesConsumed, bytesProduced);
-        }
-        throw shutdownWithError("SSL_read", errStr);
-    }
-
-    private int pendingAppData() {
-        // There won't be any application data until we're done handshaking.
-        // We first check handshakeFinished to eliminate the overhead of extra JNI call if possible.
-        return handshakeState == HandshakeState.FINISHED ? SSL.pendingReadableBytesInSSL(ssl) : 0;
-    }
-
-    private SSLEngineResult newResult(
-            int bytesConsumed, int bytesProduced, SSLEngineResult.HandshakeStatus status) throws SSLException {
-        return new SSLEngineResult(
-                getEngineStatus(), mayFinishHandshake(status != FINISHED ? getHandshakeStatus() : status)
-                , bytesConsumed, bytesProduced);
-    }
-
-    private void closeAll() throws SSLException {
-        receivedShutdown = true;
-        closeOutbound();
-        closeInbound();
-    }
-
-    private void rejectRemoteInitiatedRenegation() throws SSLHandshakeException {
-        if (rejectRemoteInitiatedRenegation && SSL.getHandshakeCount(ssl) > 1) {
-            // TODO: In future versions me may also want to send a fatal_alert to the client and so notify it
-            // that the renegotiation failed.
-            shutdown();
-            throw new SSLHandshakeException("remote-initiated renegotation not allowed");
-        }
-    }
-
-    public final SSLEngineResult unwrap(final ByteBuffer[] srcs, final ByteBuffer[] dsts) throws SSLException {
-        return unwrap(srcs, 0, srcs.length, dsts, 0, dsts.length);
-    }
-
-    private ByteBuffer[] singleSrcBuffer(ByteBuffer src) {
-        singleSrcBuffer[0] = src;
-        return singleSrcBuffer;
-    }
-
-    private void resetSingleSrcBuffer() {
-        singleSrcBuffer[0] = null;
-    }
-
-    private ByteBuffer[] singleDstBuffer(ByteBuffer src) {
-        singleDstBuffer[0] = src;
-        return singleDstBuffer;
-    }
-
-    private void resetSingleDstBuffer() {
-        singleDstBuffer[0] = null;
-    }
-
-    @Override
-    public final synchronized SSLEngineResult unwrap(
-            final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException {
-        try {
-            return unwrap(singleSrcBuffer(src), 0, 1, dsts, offset, length);
-        } finally {
-            resetSingleSrcBuffer();
-        }
-    }
-
-    @Override
-    public final synchronized SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
-        try {
-            return wrap(singleSrcBuffer(src), dst);
-        } finally {
-            resetSingleSrcBuffer();
-        }
-    }
-
-    @Override
-    public final synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
-        try {
-            return unwrap(singleSrcBuffer(src), singleDstBuffer(dst));
-        } finally {
-            resetSingleSrcBuffer();
-            resetSingleDstBuffer();
-        }
-    }
-
-    @Override
-    public final synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException {
-        try {
-            return unwrap(singleSrcBuffer(src), dsts);
-        } finally {
-            resetSingleSrcBuffer();
-        }
-    }
-
-    @Override
-    public final Runnable getDelegatedTask() {
-        // Currently, we do not delegate SSL computation tasks
-        // TODO: in the future, possibly create tasks to do encrypt / decrypt async
-
-        return null;
-    }
-
-    @Override
-    public final synchronized void closeInbound() throws SSLException {
-        if (isInboundDone) {
-            return;
-        }
-
-        isInboundDone = true;
-        engineClosed = true;
-
-        shutdown();
-
-        if (handshakeState != HandshakeState.NOT_STARTED && !receivedShutdown) {
-            throw new SSLException(
-                    "Inbound closed before receiving peer's close_notify: possible truncation attack?");
-        }
-    }
-
-    @Override
-    public final synchronized boolean isInboundDone() {
-        return isInboundDone || engineClosed;
-    }
-
-    @Override
-    public final synchronized void closeOutbound() {
-        if (isOutboundDone) {
-            return;
-        }
-
-        isOutboundDone = true;
-        engineClosed = true;
-
-        if (handshakeState != HandshakeState.NOT_STARTED && !isDestroyed()) {
-            int mode = SSL.getShutdown(ssl);
-            if ((mode & SSL.SSL_SENT_SHUTDOWN) != SSL.SSL_SENT_SHUTDOWN) {
-                int err = SSL.shutdownSSL(ssl);
-                if (err < 0) {
-                    int sslErr = SSL.getError(ssl, err);
-                    switch (sslErr) {
-                        case SSL.SSL_ERROR_NONE:
-                        case SSL.SSL_ERROR_WANT_ACCEPT:
-                        case SSL.SSL_ERROR_WANT_CONNECT:
-                        case SSL.SSL_ERROR_WANT_WRITE:
-                        case SSL.SSL_ERROR_WANT_READ:
-                        case SSL.SSL_ERROR_WANT_X509_LOOKUP:
-                        case SSL.SSL_ERROR_ZERO_RETURN:
-                            // Nothing to do here
-                            break;
-                        case SSL.SSL_ERROR_SYSCALL:
-                        case SSL.SSL_ERROR_SSL:
-                            if (logger.isDebugEnabled()) {
-                                logger.debug("SSL_shutdown failed: OpenSSL error: {}", SSL.getLastError());
-                            }
-                            // There was an internal error -- shutdown
-                            shutdown();
-                            break;
-                        default:
-                            SSL.clearError();
-                            break;
-                    }
-                }
-            }
-        } else {
-            // engine closing before initial handshake
-            shutdown();
-        }
-    }
-
-    @Override
-    public final synchronized boolean isOutboundDone() {
-        return isOutboundDone;
-    }
-
-    @Override
-    public final String[] getSupportedCipherSuites() {
-        return OpenSsl.AVAILABLE_CIPHER_SUITES.toArray(new String[OpenSsl.AVAILABLE_CIPHER_SUITES.size()]);
-    }
-
-    @Override
-    public final String[] getEnabledCipherSuites() {
-        final String[] enabled;
-        synchronized (this) {
-            if (!isDestroyed()) {
-                enabled = SSL.getCiphers(ssl);
-            } else {
-                return EmptyArrays.EMPTY_STRINGS;
-            }
-        }
-        if (enabled == null) {
-            return EmptyArrays.EMPTY_STRINGS;
-        } else {
-            synchronized (this) {
-                for (int i = 0; i < enabled.length; i++) {
-                    String mapped = toJavaCipherSuite(enabled[i]);
-                    if (mapped != null) {
-                        enabled[i] = mapped;
-                    }
-                }
-            }
-            return enabled;
-        }
-    }
-
-    @Override
-    public final void setEnabledCipherSuites(String[] cipherSuites) {
-        checkNotNull(cipherSuites, "cipherSuites");
-
-        final StringBuilder buf = new StringBuilder();
-        for (String c: cipherSuites) {
-            if (c == null) {
-                break;
-            }
-
-            String converted = CipherSuiteConverter.toOpenSsl(c);
-            if (converted == null) {
-                converted = c;
-            }
-
-            if (!OpenSsl.isCipherSuiteAvailable(converted)) {
-                throw new IllegalArgumentException("unsupported cipher suite: " + c + '(' + converted + ')');
-            }
-
-            buf.append(converted);
-            buf.append(':');
-        }
-
-        if (buf.length() == 0) {
-            throw new IllegalArgumentException("empty cipher suites");
-        }
-        buf.setLength(buf.length() - 1);
-
-        final String cipherSuiteSpec = buf.toString();
-
-        synchronized (this) {
-            if (!isDestroyed()) {
-                try {
-                    SSL.setCipherSuites(ssl, cipherSuiteSpec);
-                } catch (Exception e) {
-                    throw new IllegalStateException("failed to enable cipher suites: " + cipherSuiteSpec, e);
-                }
-            } else {
-                throw new IllegalStateException("failed to enable cipher suites: " + cipherSuiteSpec);
-            }
-        }
-    }
-
-    @Override
-    public final String[] getSupportedProtocols() {
-        return OpenSsl.SUPPORTED_PROTOCOLS_SET.toArray(new String[OpenSsl.SUPPORTED_PROTOCOLS_SET.size()]);
-    }
-
-    @Override
-    public final String[] getEnabledProtocols() {
-        List<String> enabled = InternalThreadLocalMap.get().arrayList();
-        // Seems like there is no way to explict disable SSLv2Hello in openssl so it is always enabled
-        enabled.add(OpenSsl.PROTOCOL_SSL_V2_HELLO);
-
-        int opts;
-        synchronized (this) {
-            if (!isDestroyed()) {
-                opts = SSL.getOptions(ssl);
-            } else {
-                return enabled.toArray(new String[1]);
-            }
-        }
-        if ((opts & SSL.SSL_OP_NO_TLSv1) == 0) {
-            enabled.add(OpenSsl.PROTOCOL_TLS_V1);
-        }
-        if ((opts & SSL.SSL_OP_NO_TLSv1_1) == 0) {
-            enabled.add(OpenSsl.PROTOCOL_TLS_V1_1);
-        }
-        if ((opts & SSL.SSL_OP_NO_TLSv1_2) == 0) {
-            enabled.add(OpenSsl.PROTOCOL_TLS_V1_2);
-        }
-        if ((opts & SSL.SSL_OP_NO_SSLv2) == 0) {
-            enabled.add(OpenSsl.PROTOCOL_SSL_V2);
-        }
-        if ((opts & SSL.SSL_OP_NO_SSLv3) == 0) {
-            enabled.add(OpenSsl.PROTOCOL_SSL_V3);
-        }
-        return enabled.toArray(new String[enabled.size()]);
-    }
-
-    @Override
-    public final void setEnabledProtocols(String[] protocols) {
-        if (protocols == null) {
-            // This is correct from the API docs
-            throw new IllegalArgumentException();
-        }
-        boolean sslv2 = false;
-        boolean sslv3 = false;
-        boolean tlsv1 = false;
-        boolean tlsv1_1 = false;
-        boolean tlsv1_2 = false;
-        for (String p: protocols) {
-            if (!OpenSsl.SUPPORTED_PROTOCOLS_SET.contains(p)) {
-                throw new IllegalArgumentException("Protocol " + p + " is not supported.");
-            }
-            if (p.equals(OpenSsl.PROTOCOL_SSL_V2)) {
-                sslv2 = true;
-            } else if (p.equals(OpenSsl.PROTOCOL_SSL_V3)) {
-                sslv3 = true;
-            } else if (p.equals(OpenSsl.PROTOCOL_TLS_V1)) {
-                tlsv1 = true;
-            } else if (p.equals(OpenSsl.PROTOCOL_TLS_V1_1)) {
-                tlsv1_1 = true;
-            } else if (p.equals(OpenSsl.PROTOCOL_TLS_V1_2)) {
-                tlsv1_2 = true;
-            }
-        }
-        synchronized (this) {
-            if (!isDestroyed()) {
-                // Enable all and then disable what we not want
-                SSL.setOptions(ssl, SSL.SSL_OP_ALL);
-
-                // Clear out options which disable protocols
-                SSL.clearOptions(ssl, SSL.SSL_OP_NO_SSLv2 | SSL.SSL_OP_NO_SSLv3 | SSL.SSL_OP_NO_TLSv1 |
-                        SSL.SSL_OP_NO_TLSv1_1 | SSL.SSL_OP_NO_TLSv1_2);
-
-                int opts = 0;
-                if (!sslv2) {
-                    opts |= SSL.SSL_OP_NO_SSLv2;
-                }
-                if (!sslv3) {
-                    opts |= SSL.SSL_OP_NO_SSLv3;
-                }
-                if (!tlsv1) {
-                    opts |= SSL.SSL_OP_NO_TLSv1;
-                }
-                if (!tlsv1_1) {
-                    opts |= SSL.SSL_OP_NO_TLSv1_1;
-                }
-                if (!tlsv1_2) {
-                    opts |= SSL.SSL_OP_NO_TLSv1_2;
-                }
-
-                // Disable protocols we do not want
-                SSL.setOptions(ssl, opts);
-            } else {
-                throw new IllegalStateException("failed to enable protocols: " + Arrays.asList(protocols));
-            }
-        }
-    }
-
-    @Override
-    public final SSLSession getSession() {
-        return session;
-    }
-
-    @Override
-    public final synchronized void beginHandshake() throws SSLException {
-        switch (handshakeState) {
-            case STARTED_IMPLICITLY:
-                checkEngineClosed(BEGIN_HANDSHAKE_ENGINE_CLOSED);
-
-                // A user did not start handshake by calling this method by him/herself,
-                // but handshake has been started already by wrap() or unwrap() implicitly.
-                // Because it's the user's first time to call this method, it is unfair to
-                // raise an exception.  From the user's standpoint, he or she never asked
-                // for renegotiation.
-
-                handshakeState = HandshakeState.STARTED_EXPLICITLY; // Next time this method is invoked by the user,
-                // we should raise an exception.
-                break;
-            case STARTED_EXPLICITLY:
-                // Nothing to do as the handshake is not done yet.
-                break;
-            case FINISHED:
-                if (clientMode) {
-                    // Only supported for server mode at the moment.
-                    throw RENEGOTIATION_UNSUPPORTED;
-                }
-                // For renegotiate on the server side we need to issue the following command sequence with openssl:
-                //
-                // SSL_renegotiate(ssl)
-                // SSL_do_handshake(ssl)
-                // ssl->state = SSL_ST_ACCEPT
-                // SSL_do_handshake(ssl)
-                //
-                // Bcause of this we fall-through to call handshake() after setting the state, as this will also take
-                // care of updating the internal OpenSslSession object.
-                //
-                // See also:
-                // https://github.com/apache/httpd/blob/2.4.16/modules/ssl/ssl_engine_kernel.c#L812
-                // http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s03.html
-                if (SSL.renegotiate(ssl) != 1 || SSL.doHandshake(ssl) != 1) {
-                    throw shutdownWithError("renegotiation failed");
-                }
-
-                SSL.setState(ssl, SSL.SSL_ST_ACCEPT);
-
-                lastAccessed = System.currentTimeMillis();
-
-                // fall-through
-            case NOT_STARTED:
-                handshakeState = HandshakeState.STARTED_EXPLICITLY;
-                handshake();
-                break;
-            default:
-                throw new Error();
-        }
-    }
-
-    private void checkEngineClosed(SSLException cause) throws SSLException {
-        if (engineClosed || isDestroyed()) {
-            throw cause;
-        }
-    }
-
-    private static SSLEngineResult.HandshakeStatus pendingStatus(int pendingStatus) {
-        // Depending on if there is something left in the BIO we need to WRAP or UNWRAP
-        return pendingStatus > 0 ? NEED_WRAP : NEED_UNWRAP;
-    }
-
-    private SSLEngineResult.HandshakeStatus handshake() throws SSLException {
-        if (handshakeState == HandshakeState.FINISHED) {
-            return FINISHED;
-        }
-        checkEngineClosed(HANDSHAKE_ENGINE_CLOSED);
-
-        // Check if we have a pending handshakeException and if so see if we need to consume all pending data from the
-        // BIO first or can just shutdown and throw it now.
-        // This is needed so we ensure close_notify etc is correctly send to the remote peer.
-        // See https://github.com/netty/netty/issues/3900
-        SSLHandshakeException exception = handshakeException;
-        if (exception != null) {
-            if (SSL.pendingWrittenBytesInBIO(networkBIO) > 0) {
-                // There is something pending, we need to consume it first via a WRAP so we not loose anything.
-                return NEED_WRAP;
-            }
-            // No more data left to send to the remote peer, so null out the exception field, shutdown and throw
-            // the exception.
-            handshakeException = null;
-            shutdown();
-            throw exception;
-        }
-
-        // Adding the OpenSslEngine to the OpenSslEngineMap so it can be used in the AbstractCertificateVerifier.
-        engineMap.add(this);
-        if (lastAccessed == -1) {
-            lastAccessed = System.currentTimeMillis();
-        }
-
-        if (!certificateSet && keyMaterialManager != null) {
-            certificateSet = true;
-            keyMaterialManager.setKeyMaterial(this);
-        }
-
-        int code = SSL.doHandshake(ssl);
-        if (code <= 0) {
-            // Check if we have a pending exception that was created during the handshake and if so throw it after
-            // shutdown the connection.
-            if (handshakeException != null) {
-                exception = handshakeException;
-                handshakeException = null;
-                shutdown();
-                throw exception;
-            }
-
-            int sslError = SSL.getError(ssl, code);
-
-            switch (sslError) {
-                case SSL.SSL_ERROR_WANT_READ:
-                case SSL.SSL_ERROR_WANT_WRITE:
-                    return pendingStatus(SSL.pendingWrittenBytesInBIO(networkBIO));
-                default:
-                    // Everything else is considered as error
-                    throw shutdownWithError("SSL_do_handshake");
-            }
-        }
-        // if SSL_do_handshake returns > 0 or sslError == SSL.SSL_ERROR_NAME it means the handshake was finished.
-        session.handshakeFinished();
-        engineMap.remove(ssl);
-        return FINISHED;
-    }
-
-    private SSLEngineResult.Status getEngineStatus() {
-        return engineClosed? CLOSED : OK;
-    }
-
-    private SSLEngineResult.HandshakeStatus mayFinishHandshake(SSLEngineResult.HandshakeStatus status)
-            throws SSLException {
-        if (status == NOT_HANDSHAKING && handshakeState != HandshakeState.FINISHED) {
-            // If the status was NOT_HANDSHAKING and we not finished the handshake we need to call
-            // SSL_do_handshake() again
-            return handshake();
-        }
-        return status;
-    }
-
-    @Override
-    public final synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() {
-        // Check if we are in the initial handshake phase or shutdown phase
-        return needPendingStatus() ? pendingStatus(SSL.pendingWrittenBytesInBIO(networkBIO)) : NOT_HANDSHAKING;
-    }
-
-    private SSLEngineResult.HandshakeStatus getHandshakeStatus(int pending) {
-        // Check if we are in the initial handshake phase or shutdown phase
-        return needPendingStatus() ? pendingStatus(pending) : NOT_HANDSHAKING;
-    }
-
-    private boolean needPendingStatus() {
-        return handshakeState != HandshakeState.NOT_STARTED && !isDestroyed()
-                && (handshakeState != HandshakeState.FINISHED || engineClosed);
-    }
-
-    /**
-     * Converts the specified OpenSSL cipher suite to the Java cipher suite.
-     */
-    private String toJavaCipherSuite(String openSslCipherSuite) {
-        if (openSslCipherSuite == null) {
-            return null;
-        }
-
-        String prefix = toJavaCipherSuitePrefix(SSL.getVersion(ssl));
-        return CipherSuiteConverter.toJava(openSslCipherSuite, prefix);
-    }
-
-    /**
-     * Converts the protocol version string returned by {@link SSL#getVersion(long)} to protocol family string.
-     */
-    private static String toJavaCipherSuitePrefix(String protocolVersion) {
-        final char c;
-        if (protocolVersion == null || protocolVersion.length() == 0) {
-            c = 0;
-        } else {
-            c = protocolVersion.charAt(0);
-        }
-
-        switch (c) {
-            case 'T':
-                return "TLS";
-            case 'S':
-                return "SSL";
-            default:
-                return "UNKNOWN";
-        }
-    }
-
-    @Override
-    public final void setUseClientMode(boolean clientMode) {
-        if (clientMode != this.clientMode) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    @Override
-    public final boolean getUseClientMode() {
-        return clientMode;
-    }
-
-    @Override
-    public final void setNeedClientAuth(boolean b) {
-        setClientAuth(b ? ClientAuth.REQUIRE : ClientAuth.NONE);
-    }
-
-    @Override
-    public final boolean getNeedClientAuth() {
-        return clientAuth == ClientAuth.REQUIRE;
-    }
-
-    @Override
-    public final void setWantClientAuth(boolean b) {
-        setClientAuth(b ? ClientAuth.OPTIONAL : ClientAuth.NONE);
-    }
-
-    @Override
-    public final boolean getWantClientAuth() {
-        return clientAuth == ClientAuth.OPTIONAL;
-    }
-
-    private void setClientAuth(ClientAuth mode) {
-        if (clientMode) {
-            return;
-        }
-        synchronized (this) {
-            if (clientAuth == mode) {
-                // No need to issue any JNI calls if the mode is the same
-                return;
-            }
-            switch (mode) {
-                case NONE:
-                    SSL.setVerify(ssl, SSL.SSL_CVERIFY_NONE, OpenSslContext.VERIFY_DEPTH);
-                    break;
-                case REQUIRE:
-                    SSL.setVerify(ssl, SSL.SSL_CVERIFY_REQUIRE, OpenSslContext.VERIFY_DEPTH);
-                    break;
-                case OPTIONAL:
-                    SSL.setVerify(ssl, SSL.SSL_CVERIFY_OPTIONAL, OpenSslContext.VERIFY_DEPTH);
-                    break;
-                default:
-                    throw new Error(mode.toString());
-            }
-            clientAuth = mode;
-        }
-    }
-
-    @Override
-    public final void setEnableSessionCreation(boolean b) {
-        if (b) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    @Override
-    public final boolean getEnableSessionCreation() {
-        return false;
-    }
-
-    @Override
-    public final synchronized SSLParameters getSSLParameters() {
-        SSLParameters sslParameters = super.getSSLParameters();
-
-        int version = PlatformDependent.javaVersion();
-        if (version >= 7) {
-            sslParameters.setEndpointIdentificationAlgorithm(endPointIdentificationAlgorithm);
-            SslParametersUtils.setAlgorithmConstraints(sslParameters, algorithmConstraints);
-            if (version >= 8) {
-                if (SET_SERVER_NAMES_METHOD != null && sniHostNames != null) {
-                    try {
-                        SET_SERVER_NAMES_METHOD.invoke(sslParameters, sniHostNames);
-                    } catch (IllegalAccessException e) {
-                        throw new Error(e);
-                    } catch (InvocationTargetException e) {
-                        throw new Error(e);
-                    }
-                }
-                if (SET_USE_CIPHER_SUITES_ORDER_METHOD != null && !isDestroyed()) {
-                    try {
-                        SET_USE_CIPHER_SUITES_ORDER_METHOD.invoke(sslParameters,
-                                (SSL.getOptions(ssl) & SSL.SSL_OP_CIPHER_SERVER_PREFERENCE) != 0);
-                    } catch (IllegalAccessException e) {
-                        throw new Error(e);
-                    } catch (InvocationTargetException e) {
-                        throw new Error(e);
-                    }
-                }
-            }
-        }
-        return sslParameters;
-    }
-
-    @Override
-    public final synchronized void setSSLParameters(SSLParameters sslParameters) {
-        super.setSSLParameters(sslParameters);
-
-        int version = PlatformDependent.javaVersion();
-        if (version >= 7) {
-            endPointIdentificationAlgorithm = sslParameters.getEndpointIdentificationAlgorithm();
-            algorithmConstraints = sslParameters.getAlgorithmConstraints();
-            if (version >= 8) {
-                if (SNI_HOSTNAME_CLASS != null && clientMode && !isDestroyed()) {
-                    assert GET_SERVER_NAMES_METHOD != null;
-                    assert GET_ASCII_NAME_METHOD != null;
-                    try {
-                        List<?> servernames = (List<?>) GET_SERVER_NAMES_METHOD.invoke(sslParameters);
-                        if (servernames != null) {
-                            for (Object serverName : servernames) {
-                                if (SNI_HOSTNAME_CLASS.isInstance(serverName)) {
-                                    SSL.setTlsExtHostName(ssl, (String) GET_ASCII_NAME_METHOD.invoke(serverName));
-                                } else {
-                                    throw new IllegalArgumentException("Only " + SNI_HOSTNAME_CLASS.getName()
-                                            + " instances are supported, but found: " +
-                                            serverName);
-                                }
-                            }
-                        }
-                        sniHostNames = servernames;
-                    } catch (IllegalAccessException e) {
-                        throw new Error(e);
-                    } catch (InvocationTargetException e) {
-                        throw new Error(e);
-                    }
-                }
-                if (GET_USE_CIPHER_SUITES_ORDER_METHOD != null && !isDestroyed()) {
-                    try {
-                        if ((Boolean) GET_USE_CIPHER_SUITES_ORDER_METHOD.invoke(sslParameters)) {
-                            SSL.setOptions(ssl, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
-                        } else {
-                            SSL.clearOptions(ssl, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
-                        }
-                    } catch (IllegalAccessException e) {
-                        throw new Error(e);
-                    } catch (InvocationTargetException e) {
-                        throw new Error(e);
-                    }
-                }
-            }
-        }
-    }
-
-    private boolean isDestroyed() {
-        return destroyed != 0;
-    }
-
-    private final class OpenSslSession implements SSLSession, ApplicationProtocolAccessor {
-        private final OpenSslSessionContext sessionContext;
-
-        // These are guarded by synchronized(OpenSslEngine.this) as handshakeFinished() may be triggered by any
-        // thread.
-        private X509Certificate[] x509PeerCerts;
-        private String protocol;
-        private String applicationProtocol;
-        private Certificate[] peerCerts;
-        private String cipher;
-        private byte[] id;
-        private long creationTime;
-
-        // lazy init for memory reasons
-        private Map<String, Object> values;
-
-        OpenSslSession(OpenSslSessionContext sessionContext) {
-            this.sessionContext = sessionContext;
-        }
-
-        @Override
-        public byte[] getId() {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (id == null) {
-                    return EmptyArrays.EMPTY_BYTES;
-                }
-                return id.clone();
-            }
-        }
-
-        @Override
-        public SSLSessionContext getSessionContext() {
-            return sessionContext;
-        }
-
-        @Override
-        public long getCreationTime() {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (creationTime == 0 && !isDestroyed()) {
-                    creationTime = SSL.getTime(ssl) * 1000L;
-                }
-            }
-            return creationTime;
-        }
-
-        @Override
-        public long getLastAccessedTime() {
-            long lastAccessed = ReferenceCountedOpenSslEngine.this.lastAccessed;
-            // if lastAccessed is -1 we will just return the creation time as the handshake was not started yet.
-            return lastAccessed == -1 ? getCreationTime() : lastAccessed;
-        }
-
-        @Override
-        public void invalidate() {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (!isDestroyed()) {
-                    SSL.setTimeout(ssl, 0);
-                }
-            }
-        }
-
-        @Override
-        public boolean isValid() {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (!isDestroyed()) {
-                    return System.currentTimeMillis() - (SSL.getTimeout(ssl) * 1000L) < (SSL.getTime(ssl) * 1000L);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public void putValue(String name, Object value) {
-            if (name == null) {
-                throw new NullPointerException("name");
-            }
-            if (value == null) {
-                throw new NullPointerException("value");
-            }
-            Map<String, Object> values = this.values;
-            if (values == null) {
-                // Use size of 2 to keep the memory overhead small
-                values = this.values = new HashMap<String, Object>(2);
-            }
-            Object old = values.put(name, value);
-            if (value instanceof SSLSessionBindingListener) {
-                ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name));
-            }
-            notifyUnbound(old, name);
-        }
-
-        @Override
-        public Object getValue(String name) {
-            if (name == null) {
-                throw new NullPointerException("name");
-            }
-            if (values == null) {
-                return null;
-            }
-            return values.get(name);
-        }
-
-        @Override
-        public void removeValue(String name) {
-            if (name == null) {
-                throw new NullPointerException("name");
-            }
-            Map<String, Object> values = this.values;
-            if (values == null) {
-                return;
-            }
-            Object old = values.remove(name);
-            notifyUnbound(old, name);
-        }
-
-        @Override
-        public String[] getValueNames() {
-            Map<String, Object> values = this.values;
-            if (values == null || values.isEmpty()) {
-                return EmptyArrays.EMPTY_STRINGS;
-            }
-            return values.keySet().toArray(new String[values.size()]);
-        }
-
-        private void notifyUnbound(Object value, String name) {
-            if (value instanceof SSLSessionBindingListener) {
-                ((SSLSessionBindingListener) value).valueUnbound(new SSLSessionBindingEvent(this, name));
-            }
-        }
-
-        /**
-         * Finish the handshake and so init everything in the {@link OpenSslSession} that should be accessible by
-         * the user.
-         */
-        void handshakeFinished() throws SSLException {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (!isDestroyed()) {
-                    id = SSL.getSessionId(ssl);
-                    cipher = toJavaCipherSuite(SSL.getCipherForSSL(ssl));
-                    protocol = SSL.getVersion(ssl);
-
-                    initPeerCerts();
-                    selectApplicationProtocol();
-
-                    handshakeState = HandshakeState.FINISHED;
-                } else {
-                    throw new SSLException("Already closed");
-                }
-            }
-        }
-
-        /**
-         * Init peer certificates that can be obtained via {@link #getPeerCertificateChain()}
-         * and {@link #getPeerCertificates()}.
-         */
-        private void initPeerCerts() {
-            // Return the full chain from the JNI layer.
-            byte[][] chain = SSL.getPeerCertChain(ssl);
-            final byte[] clientCert;
-            if (!clientMode) {
-                // if used on the server side SSL_get_peer_cert_chain(...) will not include the remote peer
-                // certificate. We use SSL_get_peer_certificate to get it in this case and add it to our
-                // array later.
-                //
-                // See https://www.openssl.org/docs/ssl/SSL_get_peer_cert_chain.html
-                clientCert = SSL.getPeerCertificate(ssl);
-            } else {
-                clientCert = null;
-            }
-
-            if (chain == null || chain.length == 0) {
-                if (clientCert == null || clientCert.length == 0) {
-                    peerCerts = EmptyArrays.EMPTY_CERTIFICATES;
-                    x509PeerCerts = EmptyArrays.EMPTY_JAVAX_X509_CERTIFICATES;
-                } else {
-                    peerCerts = new Certificate[1];
-                    x509PeerCerts = new X509Certificate[1];
-
-                    peerCerts[0] = new OpenSslX509Certificate(clientCert);
-                    x509PeerCerts[0] = new OpenSslJavaxX509Certificate(clientCert);
-                }
-            } else if (clientCert == null || clientCert.length == 0) {
-                peerCerts = new Certificate[chain.length];
-                x509PeerCerts = new X509Certificate[chain.length];
-
-                for (int a = 0; a < chain.length; ++a) {
-                    byte[] bytes = chain[a];
-                    peerCerts[a] = new OpenSslX509Certificate(bytes);
-                    x509PeerCerts[a] = new OpenSslJavaxX509Certificate(bytes);
-                }
-            } else {
-                int len = clientCert.length + 1;
-                peerCerts = new Certificate[len];
-                x509PeerCerts = new X509Certificate[len];
-
-                peerCerts[0] = new OpenSslX509Certificate(clientCert);
-                x509PeerCerts[0] = new OpenSslJavaxX509Certificate(clientCert);
-
-                for (int a = 0, i = 1; a < chain.length; ++a, ++i) {
-                    byte[] bytes = chain[a];
-                    peerCerts[i] = new OpenSslX509Certificate(bytes);
-                    x509PeerCerts[i] = new OpenSslJavaxX509Certificate(bytes);
-                }
-            }
-        }
-
-        /**
-         * Select the application protocol used.
-         */
-        private void selectApplicationProtocol() throws SSLException {
-            ApplicationProtocolConfig.SelectedListenerFailureBehavior behavior = apn.selectedListenerFailureBehavior();
-            List<String> protocols = apn.protocols();
-            String applicationProtocol;
-            switch (apn.protocol()) {
-                case NONE:
-                    break;
-                // We always need to check for applicationProtocol == null as the remote peer may not support
-                // the TLS extension or may have returned an empty selection.
-                case ALPN:
-                    applicationProtocol = SSL.getAlpnSelected(ssl);
-                    if (applicationProtocol != null) {
-                        this.applicationProtocol = selectApplicationProtocol(
-                                protocols, behavior, applicationProtocol);
-                    }
-                    break;
-                case NPN:
-                    applicationProtocol = SSL.getNextProtoNegotiated(ssl);
-                    if (applicationProtocol != null) {
-                        this.applicationProtocol = selectApplicationProtocol(
-                                protocols, behavior, applicationProtocol);
-                    }
-                    break;
-                case NPN_AND_ALPN:
-                    applicationProtocol = SSL.getAlpnSelected(ssl);
-                    if (applicationProtocol == null) {
-                        applicationProtocol = SSL.getNextProtoNegotiated(ssl);
-                    }
-                    if (applicationProtocol != null) {
-                        this.applicationProtocol = selectApplicationProtocol(
-                                protocols, behavior, applicationProtocol);
-                    }
-                    break;
-                default:
-                    throw new Error();
-            }
-        }
-
-        private String selectApplicationProtocol(List<String> protocols,
-                                                 ApplicationProtocolConfig.SelectedListenerFailureBehavior behavior,
-                                                 String applicationProtocol) throws SSLException {
-            if (behavior == ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT) {
-                return applicationProtocol;
-            } else {
-                int size = protocols.size();
-                assert size > 0;
-                if (protocols.contains(applicationProtocol)) {
-                    return applicationProtocol;
-                } else {
-                    if (behavior == ApplicationProtocolConfig.SelectedListenerFailureBehavior.CHOOSE_MY_LAST_PROTOCOL) {
-                        return protocols.get(size - 1);
-                    } else {
-                        throw new SSLException("unknown protocol " + applicationProtocol);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (peerCerts == null || peerCerts.length == 0) {
-                    throw new SSLPeerUnverifiedException("peer not verified");
-                }
-                return peerCerts.clone();
-            }
-        }
-
-        @Override
-        public Certificate[] getLocalCertificates() {
-            if (localCerts == null) {
-                return null;
-            }
-            return localCerts.clone();
-        }
-
-        @Override
-        public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (x509PeerCerts == null || x509PeerCerts.length == 0) {
-                    throw new SSLPeerUnverifiedException("peer not verified");
-                }
-                return x509PeerCerts.clone();
-            }
-        }
-
-        @Override
-        public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
-            Certificate[] peer = getPeerCertificates();
-            // No need for null or length > 0 is needed as this is done in getPeerCertificates()
-            // already.
-            return ((java.security.cert.X509Certificate) peer[0]).getSubjectX500Principal();
-        }
-
-        @Override
-        public Principal getLocalPrincipal() {
-            Certificate[] local = localCerts;
-            if (local == null || local.length == 0) {
-                return null;
-            }
-            return ((java.security.cert.X509Certificate) local[0]).getIssuerX500Principal();
-        }
-
-        @Override
-        public String getCipherSuite() {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                if (cipher == null) {
-                    return INVALID_CIPHER;
-                }
-                return cipher;
-            }
-        }
-
-        @Override
-        public String getProtocol() {
-            String protocol = this.protocol;
-            if (protocol == null) {
-                synchronized (ReferenceCountedOpenSslEngine.this) {
-                    if (!isDestroyed()) {
-                        protocol = SSL.getVersion(ssl);
-                    } else {
-                        protocol = StringUtil.EMPTY_STRING;
-                    }
-                }
-            }
-            return protocol;
-        }
-
-        @Override
-        public String getApplicationProtocol() {
-            synchronized (ReferenceCountedOpenSslEngine.this) {
-                return applicationProtocol;
-            }
-        }
-
-        @Override
-        public String getPeerHost() {
-            return ReferenceCountedOpenSslEngine.this.getPeerHost();
-        }
-
-        @Override
-        public int getPeerPort() {
-            return ReferenceCountedOpenSslEngine.this.getPeerPort();
-        }
-
-        @Override
-        public int getPacketBufferSize() {
-            return MAX_ENCRYPTED_PACKET_LENGTH;
-        }
-
-        @Override
-        public int getApplicationBufferSize() {
-            return MAX_PLAINTEXT_LENGTH;
-        }
-    }
-}
-
diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java
deleted file mode 100644
index ace2153..0000000
--- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslServerContext.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.apache.tomcat.jni.SSL;
-import org.apache.tomcat.jni.SSLContext;
-
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509ExtendedTrustManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-
-import static io.netty.util.internal.ObjectUtil.checkNotNull;
-
-/**
- * A server-side {@link SslContext} which uses OpenSSL's SSL/TLS implementation.
- * <p>Instances of this class must be {@link #release() released} or else native memory will leak!
- *
- * <p>Instances of this class <strong>must not</strong> be released before any {@link ReferenceCountedOpenSslEngine}
- * which depends upon the instance of this class is released. Otherwise if any method of
- * {@link ReferenceCountedOpenSslEngine} is called which uses this class's JNI resources the JVM may crash.
- */
-public final class ReferenceCountedOpenSslServerContext extends ReferenceCountedOpenSslContext {
-    private static final byte[] ID = {'n', 'e', 't', 't', 'y'};
-    private final OpenSslServerSessionContext sessionContext;
-    private final OpenSslKeyMaterialManager keyMaterialManager;
-
-    ReferenceCountedOpenSslServerContext(
-            X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-            X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-            long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, boolean startTls) throws SSLException {
-        this(trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers,
-                cipherFilter, toNegotiator(apn), sessionCacheSize, sessionTimeout, clientAuth, startTls);
-    }
-
-    private ReferenceCountedOpenSslServerContext(
-            X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-            X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
-            long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, boolean startTls) throws SSLException {
-        super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, keyCertChain,
-              clientAuth, startTls, true);
-        // Create a new SSL_CTX and configure it.
-        boolean success = false;
-        try {
-            ServerContext context = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
-                                                      keyCertChain, key, keyPassword, keyManagerFactory);
-            sessionContext = context.sessionContext;
-            keyMaterialManager = context.keyMaterialManager;
-            success = true;
-        } finally {
-            if (!success) {
-                release();
-            }
-        }
-    }
-
-    @Override
-    public OpenSslServerSessionContext sessionContext() {
-        return sessionContext;
-    }
-
-    @Override
-    OpenSslKeyMaterialManager keyMaterialManager() {
-        return keyMaterialManager;
-    }
-
-    static final class ServerContext {
-        OpenSslServerSessionContext sessionContext;
-        OpenSslKeyMaterialManager keyMaterialManager;
-    }
-
-    static ServerContext newSessionContext(ReferenceCountedOpenSslContext thiz, long ctx, OpenSslEngineMap engineMap,
-                                           X509Certificate[] trustCertCollection,
-                                           TrustManagerFactory trustManagerFactory,
-                                           X509Certificate[] keyCertChain, PrivateKey key,
-                                           String keyPassword, KeyManagerFactory keyManagerFactory)
-            throws SSLException {
-        ServerContext result = new ServerContext();
-        synchronized (ReferenceCountedOpenSslContext.class) {
-            try {
-                SSLContext.setVerify(ctx, SSL.SSL_CVERIFY_NONE, VERIFY_DEPTH);
-                if (!OpenSsl.useKeyManagerFactory()) {
-                    if (keyManagerFactory != null) {
-                        throw new IllegalArgumentException(
-                                "KeyManagerFactory not supported");
-                    }
-                    checkNotNull(keyCertChain, "keyCertChain");
-
-                        /* Set certificate verification policy. */
-                    SSLContext.setVerify(ctx, SSL.SSL_CVERIFY_NONE, VERIFY_DEPTH);
-
-                    setKeyMaterial(ctx, keyCertChain, key, keyPassword);
-                } else {
-                    // javadocs state that keyManagerFactory has precedent over keyCertChain, and we must have a
-                    // keyManagerFactory for the server so build one if it is not specified.
-                    if (keyManagerFactory == null) {
-                        keyManagerFactory = buildKeyManagerFactory(
-                                keyCertChain, key, keyPassword, keyManagerFactory);
-                    }
-                    X509KeyManager keyManager = chooseX509KeyManager(keyManagerFactory.getKeyManagers());
-                    result.keyMaterialManager = useExtendedKeyManager(keyManager) ?
-                            new OpenSslExtendedKeyMaterialManager(
-                                    (X509ExtendedKeyManager) keyManager, keyPassword) :
-                            new OpenSslKeyMaterialManager(keyManager, keyPassword);
-                }
-            } catch (Exception e) {
-                throw new SSLException("failed to set certificate and key", e);
-            }
-            try {
-                if (trustCertCollection != null) {
-                    trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory);
-                } else if (trustManagerFactory == null) {
-                    // Mimic the way SSLContext.getInstance(KeyManager[], null, null) works
-                    trustManagerFactory = TrustManagerFactory.getInstance(
-                            TrustManagerFactory.getDefaultAlgorithm());
-                    trustManagerFactory.init((KeyStore) null);
-                }
-
-                final X509TrustManager manager = chooseTrustManager(trustManagerFactory.getTrustManagers());
-
-                // IMPORTANT: The callbacks set for verification must be static to prevent memory leak as
-                //            otherwise the context can never be collected. This is because the JNI code holds
-                //            a global reference to the callbacks.
-                //
-                //            See https://github.com/netty/netty/issues/5372
-
-                // Use this to prevent an error when running on java < 7
-                if (useExtendedTrustManager(manager)) {
-                    SSLContext.setCertVerifyCallback(ctx,
-                            new ExtendedTrustManagerVerifyCallback(engineMap, (X509ExtendedTrustManager) manager));
-                } else {
-                    SSLContext.setCertVerifyCallback(ctx, new TrustManagerVerifyCallback(engineMap, manager));
-                }
-            } catch (Exception e) {
-                throw new SSLException("unable to setup trustmanager", e);
-            }
-        }
-
-        result.sessionContext = new OpenSslServerSessionContext(thiz);
-        result.sessionContext.setSessionIdContext(ID);
-        return result;
-    }
-
-    private static final class TrustManagerVerifyCallback extends AbstractCertificateVerifier {
-        private final X509TrustManager manager;
-
-        TrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509TrustManager manager) {
-            super(engineMap);
-            this.manager = manager;
-        }
-
-        @Override
-        void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth)
-                throws Exception {
-            manager.checkClientTrusted(peerCerts, auth);
-        }
-    }
-
-    private static final class ExtendedTrustManagerVerifyCallback extends AbstractCertificateVerifier {
-        private final X509ExtendedTrustManager manager;
-
-        ExtendedTrustManagerVerifyCallback(OpenSslEngineMap engineMap, X509ExtendedTrustManager manager) {
-            super(engineMap);
-            this.manager = manager;
-        }
-
-        @Override
-        void verify(ReferenceCountedOpenSslEngine engine, X509Certificate[] peerCerts, String auth)
-                throws Exception {
-            manager.checkClientTrusted(peerCerts, auth, engine);
-        }
-    }
-}
diff --git a/handler/src/main/java/io/netty/handler/ssl/SslContext.java b/handler/src/main/java/io/netty/handler/ssl/SslContext.java
index 9a40d92..b76e4af 100644
--- a/handler/src/main/java/io/netty/handler/ssl/SslContext.java
+++ b/handler/src/main/java/io/netty/handler/ssl/SslContext.java
@@ -114,11 +114,7 @@ public abstract class SslContext {
     }
 
     private static SslProvider defaultProvider() {
-        if (OpenSsl.isAvailable()) {
-            return SslProvider.OPENSSL;
-        } else {
-            return SslProvider.JDK;
-        }
+    	return SslProvider.JDK;
     }
 
     /**
@@ -410,16 +406,6 @@ public abstract class SslContext {
                     trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
                     keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
                     clientAuth, startTls);
-        case OPENSSL:
-            return new OpenSslServerContext(
-                    trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
-                    keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
-                    clientAuth, startTls);
-        case OPENSSL_REFCNT:
-            return new ReferenceCountedOpenSslServerContext(
-                    trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
-                    keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
-                    clientAuth, startTls);
         default:
             throw new Error(provider.toString());
         }
@@ -751,14 +737,6 @@ public abstract class SslContext {
                 return new JdkSslClientContext(
                         trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
                         keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
-            case OPENSSL:
-                return new OpenSslClientContext(
-                        trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
-                        keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
-            case OPENSSL_REFCNT:
-                return new ReferenceCountedOpenSslClientContext(
-                        trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
-                        keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
             default:
                 throw new Error(provider.toString());
         }
diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java
index 55c09ae..a9cb9ae 100644
--- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java
+++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java
@@ -159,6 +159,14 @@ import static io.netty.handler.ssl.SslUtils.getEncryptedPacketLength;
  */
 public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundHandler {
 
+	private static final int MAX_PLAINTEXT_LENGTH = 16 * 1024; // 2^14
+	private static final int MAX_COMPRESSED_LENGTH = MAX_PLAINTEXT_LENGTH + 1024;
+	private static final int MAX_CIPHERTEXT_LENGTH = MAX_COMPRESSED_LENGTH + 1024;
+	
+	// Header (5) + Data (2^14) + Compression (1024) + Encryption (1024) + MAC (20) + Padding (256)
+	static final int MAX_ENCRYPTED_PACKET_LENGTH = MAX_CIPHERTEXT_LENGTH + 5 + 20 + 256;
+	
+	static final int MAX_ENCRYPTION_OVERHEAD_LENGTH = MAX_ENCRYPTED_PACKET_LENGTH - MAX_PLAINTEXT_LENGTH;
     private static final InternalLogger logger =
             InternalLoggerFactory.getInstance(SslHandler.class);
 
@@ -281,7 +289,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
         this.startTls = startTls;
         maxPacketBufferSize = engine.getSession().getPacketBufferSize();
 
-        boolean opensslEngine = engine instanceof OpenSslEngine;
+        boolean opensslEngine = false;
         wantsDirectBuffer = opensslEngine;
         wantsLargeOutboundNetworkBuffer = !opensslEngine;
 
@@ -415,9 +423,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
             // Check if queue is not empty first because create a new ChannelException is expensive
             pendingUnencryptedWrites.removeAndFailAll(new ChannelException("Pending write on removal of SslHandler"));
         }
-        if (engine instanceof ReferenceCountedOpenSslEngine) {
-            ((ReferenceCountedOpenSslEngine) engine).release();
-        }
     }
 
     @Override
@@ -853,7 +858,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
 
         boolean nonSslRecord = false;
 
-        while (totalLength < OpenSslEngine.MAX_ENCRYPTED_PACKET_LENGTH) {
+        while (totalLength < MAX_ENCRYPTED_PACKET_LENGTH) {
             final int readableBytes = endOffset - offset;
             if (readableBytes < SslUtils.SSL_RECORD_HEADER_LENGTH) {
                 break;
@@ -874,7 +879,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
             }
 
             int newTotalLength = totalLength + packetLength;
-            if (newTotalLength > OpenSslEngine.MAX_ENCRYPTED_PACKET_LENGTH) {
+            if (newTotalLength > MAX_ENCRYPTED_PACKET_LENGTH) {
                 // Don't read too much.
                 break;
             }
@@ -1076,27 +1081,10 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
 
     private SSLEngineResult unwrap(
             SSLEngine engine, ByteBuf in, int readerIndex, int len, ByteBuf out) throws SSLException {
-        int nioBufferCount = in.nioBufferCount();
         int writerIndex = out.writerIndex();
         final SSLEngineResult result;
-        if (engine instanceof OpenSslEngine && nioBufferCount > 1) {
-            /**
-             * If {@link OpenSslEngine} is in use,
-             * we can use a special {@link OpenSslEngine#unwrap(ByteBuffer[], ByteBuffer[])} method
-             * that accepts multiple {@link ByteBuffer}s without additional memory copies.
-             */
-            OpenSslEngine opensslEngine = (OpenSslEngine) engine;
-            try {
-                singleBuffer[0] = toByteBuffer(out, writerIndex, out.writableBytes());
-                result = opensslEngine.unwrap(in.nioBuffers(readerIndex, len), singleBuffer);
-                out.writerIndex(writerIndex + result.bytesProduced());
-            } finally {
-                singleBuffer[0] = null;
-            }
-        } else {
-            result = engine.unwrap(toByteBuffer(in, readerIndex, len),
+        result = engine.unwrap(toByteBuffer(in, readerIndex, len),
                                                    toByteBuffer(out, writerIndex, out.writableBytes()));
-        }
         out.writerIndex(writerIndex + result.bytesProduced());
         return result;
     }
@@ -1482,7 +1470,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
             return allocate(ctx, maxPacketBufferSize);
         } else {
             return allocate(ctx, Math.min(
-                    pendingBytes + OpenSslEngine.MAX_ENCRYPTION_OVERHEAD_LENGTH,
+                    pendingBytes + MAX_ENCRYPTION_OVERHEAD_LENGTH,
                     maxPacketBufferSize));
         }
     }
diff --git a/handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java b/handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java
deleted file mode 100644
index 381df73..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/JdkOpenSslEngineInteroptTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.junit.BeforeClass;
-
-import static org.junit.Assume.assumeTrue;
-
-public class JdkOpenSslEngineInteroptTest extends SSLEngineTest {
-    @BeforeClass
-    public static void checkOpenSsl() {
-        assumeTrue(OpenSsl.isAvailable());
-    }
-
-    @Override
-    protected SslProvider sslClientProvider() {
-        return SslProvider.JDK;
-    }
-
-    @Override
-    protected SslProvider sslServerProvider() {
-        return SslProvider.OPENSSL;
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslClientContextTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslClientContextTest.java
deleted file mode 100644
index 6011cf7..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslClientContextTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import org.junit.BeforeClass;
-
-import javax.net.ssl.SSLException;
-import java.io.File;
-
-import static org.junit.Assume.assumeTrue;
-
-public class OpenSslClientContextTest extends SslContextTest  {
-
-    @BeforeClass
-    public static void checkOpenSsl() {
-        assumeTrue(OpenSsl.isAvailable());
-    }
-
-    @Override
-    protected SslContext newServerContext(File crtFile, File keyFile, String pass) throws SSLException {
-        return new OpenSslClientContext(crtFile, InsecureTrustManagerFactory.INSTANCE, crtFile, keyFile, pass,
-                null, null, IdentityCipherSuiteFilter.INSTANCE, ApplicationProtocolConfig.DISABLED, 0, 0);
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java
deleted file mode 100644
index 2ef0a6c..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslEngineTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2015 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.buffer.UnpooledByteBufAllocator;
-import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
-import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
-import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import io.netty.handler.ssl.util.SelfSignedCertificate;
-import io.netty.util.internal.ThreadLocalRandom;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assume.assumeTrue;
-
-public class OpenSslEngineTest extends SSLEngineTest {
-    private static final String PREFERRED_APPLICATION_LEVEL_PROTOCOL = "my-protocol-http2";
-    private static final String FALLBACK_APPLICATION_LEVEL_PROTOCOL = "my-protocol-http1_1";
-
-    @BeforeClass
-    public static void checkOpenSsl() {
-        assumeTrue(OpenSsl.isAvailable());
-    }
-
-    @Test
-    public void testNpn() throws Exception {
-        ApplicationProtocolConfig apn = acceptingNegotiator(Protocol.NPN,
-                PREFERRED_APPLICATION_LEVEL_PROTOCOL);
-        setupHandlers(apn);
-        runTest(PREFERRED_APPLICATION_LEVEL_PROTOCOL);
-    }
-
-    @Test
-    public void testAlpn() throws Exception {
-        assumeTrue(OpenSsl.isAlpnSupported());
-        ApplicationProtocolConfig apn = acceptingNegotiator(Protocol.ALPN,
-                PREFERRED_APPLICATION_LEVEL_PROTOCOL);
-        setupHandlers(apn);
-        runTest(PREFERRED_APPLICATION_LEVEL_PROTOCOL);
-    }
-
-    @Test
-    public void testAlpnCompatibleProtocolsDifferentClientOrder() throws Exception {
-        assumeTrue(OpenSsl.isAlpnSupported());
-        ApplicationProtocolConfig clientApn = acceptingNegotiator(Protocol.ALPN,
-                FALLBACK_APPLICATION_LEVEL_PROTOCOL, PREFERRED_APPLICATION_LEVEL_PROTOCOL);
-        ApplicationProtocolConfig serverApn = acceptingNegotiator(Protocol.ALPN,
-                PREFERRED_APPLICATION_LEVEL_PROTOCOL, FALLBACK_APPLICATION_LEVEL_PROTOCOL);
-        setupHandlers(serverApn, clientApn);
-        assertNull(serverException);
-        runTest(PREFERRED_APPLICATION_LEVEL_PROTOCOL);
-    }
-
-    @Test
-    public void testEnablingAnAlreadyDisabledSslProtocol() throws Exception {
-        testEnablingAnAlreadyDisabledSslProtocol(new String[]{PROTOCOL_SSL_V2_HELLO},
-            new String[]{PROTOCOL_SSL_V2_HELLO, PROTOCOL_TLS_V1_2});
-    }
-    @Test
-    public void testWrapHeapBuffersNoWritePendingError() throws Exception {
-        clientSslCtx = SslContextBuilder.forClient()
-                .trustManager(InsecureTrustManagerFactory.INSTANCE)
-                .sslProvider(sslClientProvider())
-                .build();
-        SelfSignedCertificate ssc = new SelfSignedCertificate();
-        serverSslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
-                .sslProvider(sslServerProvider())
-                .build();
-        SSLEngine clientEngine = null;
-        SSLEngine serverEngine = null;
-        try {
-            clientEngine = clientSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT);
-            serverEngine = serverSslCtx.newEngine(UnpooledByteBufAllocator.DEFAULT);
-            handshake(clientEngine, serverEngine);
-
-            ByteBuffer src = ByteBuffer.allocate(1024 * 10);
-            ThreadLocalRandom.current().nextBytes(src.array());
-            ByteBuffer dst = ByteBuffer.allocate(1);
-            // Try to wrap multiple times so we are more likely to hit the issue.
-            for (int i = 0; i < 100; i++) {
-                src.position(0);
-                dst.position(0);
-                assertSame(SSLEngineResult.Status.BUFFER_OVERFLOW, clientEngine.wrap(src, dst).getStatus());
-            }
-        } finally {
-            cleanupClientSslEngine(clientEngine);
-            cleanupServerSslEngine(serverEngine);
-        }
-    }
-
-    @Override
-    protected SslProvider sslClientProvider() {
-        return SslProvider.OPENSSL;
-    }
-
-    @Override
-    protected SslProvider sslServerProvider() {
-        return SslProvider.OPENSSL;
-    }
-
-    private static ApplicationProtocolConfig acceptingNegotiator(Protocol protocol,
-            String... supportedProtocols) {
-        return new ApplicationProtocolConfig(protocol,
-                SelectorFailureBehavior.NO_ADVERTISE,
-                SelectedListenerFailureBehavior.ACCEPT,
-                supportedProtocols);
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java
deleted file mode 100644
index 9954f69..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslJdkSslEngineInteroptTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.junit.BeforeClass;
-
-import static org.junit.Assume.assumeTrue;
-
-public class OpenSslJdkSslEngineInteroptTest extends SSLEngineTest {
-
-    @BeforeClass
-    public static void checkOpenSsl() {
-        assumeTrue(OpenSsl.isAvailable());
-    }
-
-    @Override
-    protected SslProvider sslClientProvider() {
-        return SslProvider.OPENSSL;
-    }
-
-    @Override
-    protected SslProvider sslServerProvider() {
-        return SslProvider.JDK;
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslRenegotiateTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslRenegotiateTest.java
deleted file mode 100644
index 8f3dfee..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslRenegotiateTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2015 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import org.junit.BeforeClass;
-
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
-public class OpenSslRenegotiateTest extends RenegotiateTest {
-
-    @BeforeClass
-    public static void checkOpenSsl() {
-        assumeTrue(OpenSsl.isAvailable());
-        // BoringSSL does not support renegotiation intentionally.
-        assumeFalse("BoringSSL".equals(OpenSsl.versionString()));
-    }
-
-    @Override
-    protected SslProvider serverSslProvider() {
-        return SslProvider.OPENSSL;
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslServerContextTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslServerContextTest.java
deleted file mode 100644
index f22d045..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/OpenSslServerContextTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package io.netty.handler.ssl;
-
-import org.junit.Assume;
-import org.junit.BeforeClass;
-
-import javax.net.ssl.SSLException;
-import java.io.File;
-
-import static org.junit.Assume.assumeTrue;
-
-public class OpenSslServerContextTest extends SslContextTest {
-
-    @BeforeClass
-    public static void checkOpenSsl() {
-        assumeTrue(OpenSsl.isAvailable());
-    }
-
-    @Override
-    protected SslContext newServerContext(File crtFile, File keyFile, String pass) throws SSLException {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        return new OpenSslServerContext(crtFile, keyFile, pass);
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/PemEncodedTest.java b/handler/src/test/java/io/netty/handler/ssl/PemEncodedTest.java
deleted file mode 100644
index 793f772..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/PemEncodedTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package io.netty.handler.ssl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-import org.junit.Test;
-
-import io.netty.handler.ssl.util.SelfSignedCertificate;
-import io.netty.util.ReferenceCountUtil;
-
-public class PemEncodedTest {
-
-    @Test
-    public void testPemEncodedOpenSsl() throws Exception {
-        testPemEncoded(SslProvider.OPENSSL);
-    }
-
-    @Test
-    public void testPemEncodedOpenSslRef() throws Exception {
-        testPemEncoded(SslProvider.OPENSSL_REFCNT);
-    }
-
-    private static void testPemEncoded(SslProvider provider) throws Exception {
-        assumeTrue(OpenSsl.isAvailable());
-        assumeFalse(OpenSsl.useKeyManagerFactory());
-        PemPrivateKey pemKey;
-        PemX509Certificate pemCert;
-        SelfSignedCertificate ssc = new SelfSignedCertificate();
-        try {
-            pemKey = PemPrivateKey.valueOf(toByteArray(ssc.privateKey()));
-            pemCert = PemX509Certificate.valueOf(toByteArray(ssc.certificate()));
-        } finally {
-            ssc.delete();
-        }
-
-        SslContext context = SslContextBuilder.forServer(pemKey, pemCert)
-                .sslProvider(provider)
-                .build();
-        assertEquals(1, pemKey.refCnt());
-        assertEquals(1, pemCert.refCnt());
-        try {
-            assertTrue(context instanceof ReferenceCountedOpenSslContext);
-        } finally {
-            ReferenceCountUtil.release(context);
-            assertRelease(pemKey);
-            assertRelease(pemCert);
-        }
-    }
-
-    private static void assertRelease(PemEncoded encoded) {
-        assertTrue(encoded.release());
-    }
-
-    private static byte[] toByteArray(File file) throws Exception {
-        FileInputStream in = new FileInputStream(file);
-        try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            try {
-                byte[] buf = new byte[1024];
-                int len;
-                while ((len = in.read(buf)) != -1) {
-                    baos.write(buf, 0, len);
-                }
-            } finally {
-                baos.close();
-            }
-
-            return baos.toByteArray();
-        } finally {
-            in.close();
-        }
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java
deleted file mode 100644
index 40b3193..0000000
--- a/handler/src/test/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngineTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2016 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package io.netty.handler.ssl;
-
-import io.netty.util.ReferenceCountUtil;
-
-import javax.net.ssl.SSLEngine;
-
-public class ReferenceCountedOpenSslEngineTest extends OpenSslEngineTest {
-    @Override
-    protected SslProvider sslClientProvider() {
-        return SslProvider.OPENSSL_REFCNT;
-    }
-
-    @Override
-    protected SslProvider sslServerProvider() {
-        return SslProvider.OPENSSL_REFCNT;
-    }
-
-    @Override
-    protected void cleanupClientSslContext(SslContext ctx) {
-        ReferenceCountUtil.release(ctx);
-    }
-
-    @Override
-    protected void cleanupClientSslEngine(SSLEngine engine) {
-        ReferenceCountUtil.release(engine);
-    }
-
-    @Override
-    protected void cleanupServerSslContext(SslContext ctx) {
-        ReferenceCountUtil.release(ctx);
-    }
-
-    @Override
-    protected void cleanupServerSslEngine(SSLEngine engine) {
-        ReferenceCountUtil.release(engine);
-    }
-}
diff --git a/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java b/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java
index 1ad3c56..2bb510d 100644
--- a/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java
@@ -40,24 +40,6 @@ public class SniClientTest {
         testSniClient(SslProvider.JDK, SslProvider.JDK);
     }
 
-    @Test(timeout = 5000)
-    public void testSniClientOpenSslServerOpenSsl() throws Exception {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        testSniClient(SslProvider.OPENSSL, SslProvider.OPENSSL);
-    }
-
-    @Test(timeout = 5000)
-    public void testSniClientJdkSslServerOpenSsl() throws Exception {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        testSniClient(SslProvider.JDK, SslProvider.OPENSSL);
-    }
-
-    @Test(timeout = 5000)
-    public void testSniClientOpenSslServerJdkSsl() throws Exception {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        testSniClient(SslProvider.OPENSSL, SslProvider.JDK);
-    }
-
     @SuppressWarnings("deprecation")
     private static void testSniClient(SslProvider sslClientProvider, SslProvider sslServerProvider) throws Exception {
         final String sniHost = "sni.netty.io";
diff --git a/handler/src/test/java/io/netty/handler/ssl/SslContextBuilderTest.java b/handler/src/test/java/io/netty/handler/ssl/SslContextBuilderTest.java
index 752424c..4cd3c76 100644
--- a/handler/src/test/java/io/netty/handler/ssl/SslContextBuilderTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/SslContextBuilderTest.java
@@ -33,44 +33,20 @@ public class SslContextBuilderTest {
     }
 
     @Test
-    public void testClientContextFromFileOpenssl() throws Exception {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        testClientContextFromFile(SslProvider.OPENSSL);
-    }
-
-    @Test
     public void testClientContextJdk() throws Exception {
         testClientContext(SslProvider.JDK);
     }
 
     @Test
-    public void testClientContextOpenssl() throws Exception {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        testClientContext(SslProvider.OPENSSL);
-    }
-
-    @Test
     public void testServerContextFromFileJdk() throws Exception {
         testServerContextFromFile(SslProvider.JDK);
     }
 
     @Test
-    public void testServerContextFromFileOpenssl() throws Exception {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        testServerContextFromFile(SslProvider.OPENSSL);
-    }
-
-    @Test
     public void testServerContextJdk() throws Exception {
         testServerContext(SslProvider.JDK);
     }
 
-    @Test
-    public void testServerContextOpenssl() throws Exception {
-        Assume.assumeTrue(OpenSsl.isAvailable());
-        testServerContext(SslProvider.OPENSSL);
-    }
-
     private static void testClientContextFromFile(SslProvider provider) throws Exception {
         SelfSignedCertificate cert = new SelfSignedCertificate();
         SslContextBuilder builder = SslContextBuilder.forClient()
diff --git a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
index 7d50460..ddcf3bd 100644
--- a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java
@@ -94,34 +94,6 @@ public class SslHandlerTest {
         ch.writeOutbound(new Object());
     }
 
-    @Test
-    public void testReleaseSslEngine() throws Exception {
-        assumeTrue(OpenSsl.isAvailable());
-
-        SelfSignedCertificate cert = new SelfSignedCertificate();
-        try {
-            SslContext sslContext = SslContextBuilder.forServer(cert.certificate(), cert.privateKey())
-                .sslProvider(SslProvider.OPENSSL)
-                .build();
-            try {
-                SSLEngine sslEngine = sslContext.newEngine(ByteBufAllocator.DEFAULT);
-                EmbeddedChannel ch = new EmbeddedChannel(new SslHandler(sslEngine));
-
-                assertEquals(1, ((ReferenceCounted) sslContext).refCnt());
-                assertEquals(1, ((ReferenceCounted) sslEngine).refCnt());
-
-                ch.close().syncUninterruptibly();
-
-                assertEquals(1, ((ReferenceCounted) sslContext).refCnt());
-                assertEquals(0, ((ReferenceCounted) sslEngine).refCnt());
-            } finally {
-                ReferenceCountUtil.release(sslContext);
-            }
-        } finally {
-            cert.delete();
-        }
-    }
-
     private static final class TlsReadTest extends ChannelOutboundHandlerAdapter {
         private volatile boolean readIssued;
 
-- 
2.7.4