Repository: netty/netty
Issue: NPE with BoringSSL when trying to init with unsupported Cipher

Trying to run the code from #8165 will NPE when a client attempts to connect.

```java
java.lang.NullPointerException: null
	at io.netty.handler.ssl.ReferenceCountedOpenSslContext.destroy(ReferenceCountedOpenSslContext.java:489) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.ReferenceCountedOpenSslContext.access$100(ReferenceCountedOpenSslContext.java:75) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.ReferenceCountedOpenSslContext$2.deallocate(ReferenceCountedOpenSslContext.java:122) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.util.AbstractReferenceCounted.release0(AbstractReferenceCounted.java:82) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.util.AbstractReferenceCounted.release(AbstractReferenceCounted.java:71) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.ReferenceCountedOpenSslContext.release(ReferenceCountedOpenSslContext.java:601) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.ReferenceCountedOpenSslContext.<init>(ReferenceCountedOpenSslContext.java:309) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.OpenSslContext.<init>(OpenSslContext.java:43) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.OpenSslServerContext.<init>(OpenSslServerContext.java:347) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.OpenSslServerContext.<init>(OpenSslServerContext.java:335) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.SslContext.newServerContextInternal(SslContext.java:421) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.handler.ssl.SslContextBuilder.build(SslContextBuilder.java:447) ~[netty-all-4.1.28.Final.jar:4.1.28.Final]
	at Main$1.initChannel(Main.java:40) ~[test/:?]
	at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:115) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:107) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:637) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.DefaultChannelPipeline.access$000(DefaultChannelPipeline.java:46) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1487) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1161) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:686) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:510) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:423) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:482) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-all-4.1.28.Final.jar:4.1.28.Final]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_172]
```

### Expected behavior

### Actual behavior

### Steps to reproduce

### Minimal yet complete reproducer code (or URL to code)

### Netty version

### JVM version (e.g. `java -version`)

### OS version (e.g. `uname -a`)


Issue comments:
Will try to check later today. 

Pull request review comments:

Patch that resolved the issue:
diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java
index 4a020226776..18c86795744 100644
--- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java
+++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java
@@ -486,7 +486,11 @@ private void destroy() {
 
                 SSLContext.free(ctx);
                 ctx = 0;
-                sessionContext().destroy();
+
+                OpenSslSessionContext context = sessionContext();
+                if (context != null) {
+                    context.destroy();
+                }
             }
         } finally {
             writerLock.unlock();


Test patch:
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 752424cfb55..0a9429e9c1a 100644
--- a/handler/src/test/java/io/netty/handler/ssl/SslContextBuilderTest.java
+++ b/handler/src/test/java/io/netty/handler/ssl/SslContextBuilderTest.java
@@ -24,6 +24,8 @@
 import org.junit.Test;
 
 import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+import java.util.Collections;
 
 public class SslContextBuilderTest {
 
@@ -71,6 +73,30 @@ public void testServerContextOpenssl() throws Exception {
         testServerContext(SslProvider.OPENSSL);
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidCipherJdk() throws Exception {
+        Assume.assumeTrue(OpenSsl.isAvailable());
+        testInvalidCipher(SslProvider.JDK);
+    }
+
+    @Test(expected = SSLException.class)
+    public void testInvalidCipherOpenSSL() throws Exception {
+        Assume.assumeTrue(OpenSsl.isAvailable());
+        testInvalidCipher(SslProvider.OPENSSL);
+    }
+
+    private static void testInvalidCipher(SslProvider provider) throws Exception {
+        SelfSignedCertificate cert = new SelfSignedCertificate();
+        SslContextBuilder builder = SslContextBuilder.forClient()
+                .sslProvider(provider)
+                .ciphers(Collections.singleton("SOME_INVALID_CIPHER"))
+                .keyManager(cert.certificate(),
+                        cert.privateKey())
+                .trustManager(cert.certificate());
+        SslContext context = builder.build();
+        context.newEngine(UnpooledByteBufAllocator.DEFAULT);
+    }
+
     private static void testClientContextFromFile(SslProvider provider) throws Exception {
         SelfSignedCertificate cert = new SelfSignedCertificate();
         SslContextBuilder builder = SslContextBuilder.forClient()