Repository: netty/netty
Issue: IBM J9 uses slightly different cipher names -> HTTP2.0 connection fails

While investigating https://github.com/netty/netty/issues/6437, i found an interesting problem:
```
SslHandshakeCompletionEvent(javax.net.ssl.SSLHandshakeException: No appropriate protocol, may be no appropriate cipher suite specified or protocols are deactivated)
```

It turns out that netty qants the following http2 ciphers:
```
io.netty.handler.codec.http2.Http2SecurityUtil.CIPHERS
            /* Java 8 */
            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", /* openssl = ECDHE-ECDSA-AES256-GCM-SHA384 */
            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", /* openssl = ECDHE-ECDSA-AES128-GCM-SHA256 */
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", /* openssl = ECDHE-RSA-AES256-GCM-SHA384 */
            /* REQUIRED BY HTTP/2 SPEC */
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", /* openssl = ECDHE-RSA-AES128-GCM-SHA256 */
            /* REQUIRED BY HTTP/2 SPEC */
            "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", /* openssl = DHE-RSA-AES128-GCM-SHA256 */
            "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" /* openssl = DHE-DSS-AES128-GCM-SHA256 */));
```

none of those is provided by J9
However J9 has those:
```
Default Cipher
        SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
*       SSL_DHE_DSS_WITH_AES_128_CBC_SHA
*       SSL_DHE_DSS_WITH_AES_128_CBC_SHA256
*       SSL_DHE_DSS_WITH_AES_128_GCM_SHA256
        SSL_DHE_DSS_WITH_DES_CBC_SHA
        SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
*       SSL_DHE_RSA_WITH_AES_128_CBC_SHA
*       SSL_DHE_RSA_WITH_AES_128_CBC_SHA256
*       SSL_DHE_RSA_WITH_AES_128_GCM_SHA256
        SSL_DHE_RSA_WITH_DES_CBC_SHA
        SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
        SSL_DH_anon_WITH_AES_128_CBC_SHA
        SSL_DH_anon_WITH_AES_128_CBC_SHA256
        SSL_DH_anon_WITH_DES_CBC_SHA
*       SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
*       SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
*       SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        SSL_ECDHE_ECDSA_WITH_NULL_SHA
*       SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA
*       SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256
*       SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        SSL_ECDHE_RSA_WITH_NULL_SHA
*       SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA
*       SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
*       SSL_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
        SSL_ECDH_ECDSA_WITH_NULL_SHA
*       SSL_ECDH_RSA_WITH_AES_128_CBC_SHA
*       SSL_ECDH_RSA_WITH_AES_128_CBC_SHA256
*       SSL_ECDH_RSA_WITH_AES_128_GCM_SHA256
        SSL_ECDH_RSA_WITH_NULL_SHA
        SSL_ECDH_anon_WITH_AES_128_CBC_SHA
        SSL_ECDH_anon_WITH_NULL_SHA
        SSL_KRB5_EXPORT_WITH_DES_CBC_40_MD5
        SSL_KRB5_EXPORT_WITH_DES_CBC_40_SHA
        SSL_KRB5_WITH_DES_CBC_MD5
        SSL_KRB5_WITH_DES_CBC_SHA
        SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
        SSL_RSA_FIPS_WITH_DES_CBC_SHA
*       SSL_RSA_WITH_AES_128_CBC_SHA
*       SSL_RSA_WITH_AES_128_CBC_SHA256
*       SSL_RSA_WITH_AES_128_GCM_SHA256
        SSL_RSA_WITH_DES_CBC_SHA
        SSL_RSA_WITH_NULL_MD5
        SSL_RSA_WITH_NULL_SHA
        SSL_RSA_WITH_NULL_SHA256
*       TLS_EMPTY_RENEGOTIATION_INFO_SCSV
```
(Output from https://confluence.atlassian.com/stashkb/list-ciphers-used-by-jvm-679609085.html)

So all ciphers required by the http2 spec are actually present, but their name is slightly different (SSL instead of TLS)
Only the SHA384 ciphers are not available (on the the j9 i use, according to docs like https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_8.0.0/com.ibm.mq.dev.doc/q113210_.htm they can exist).

So probably we just need to extend the list?


Issue comments:
And confirmed, that adding the same names but with SSL works. I am going to open a PR, then we can discuss if this is the right thing to do :)
Hmm it seems that the JSSE spec wants to treat the "TLS" and "SSL" prefix as interchangeable [1].

> The names mentioned in the TLS RFCs prefixed with TLS_ are functionally equivalent to the JSSE cipher suites prefixed with SSL_.

If the `SupportedCipherSuiteFilter` is used then hopefully adding both prefixes will not have any impact ... but we can verify with unit tests.

[1] http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
closed in 4.1.9

Pull request review comments:
@CodingFabian  nit: On OpenJDK and Oracle JDK ?
Well i consider Oracle JDK to be OpenJDK, but I happily will adjust to your preferred wording.
But the TLS_ names work correctly on Azul Zulu, so we should add that, or say OpenJDK based JVMs?
OpenJDK based sounds good
I think its better to just say that the JSSE allows for the "TLS" and "SSL" prefix to be interchanged (and also link to the docs) [1]:

> The names mentioned in the TLS RFCs prefixed with TLS_ are functionally equivalent to the JSSE cipher suites prefixed with SSL_.

[1] http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html

Patch that resolved the issue:
diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2SecurityUtil.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2SecurityUtil.java
index 2ddd16f63ce..e0450fba58e 100644
--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2SecurityUtil.java
+++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2SecurityUtil.java
@@ -34,26 +34,51 @@ public final class Http2SecurityUtil {
      * href="https://wiki.mozilla.org/Security/Server_Side_TLS#Non-Backward_Compatible_Ciphersuite">Mozilla Cipher
      * Suites</a> in accordance with the <a
      * href="https://tools.ietf.org/html/draft-ietf-httpbis-http2-16#section-9.2.2">HTTP/2 Specification</a>.
+     *
+     * According to the <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html">
+     * JSSE documentation</a> "the names mentioned in the TLS RFCs prefixed with TLS_ are functionally equivalent
+     * to the JSSE cipher suites prefixed with SSL_".
+     * Both variants are used to support JVMs supporting the one or the other.
      */
     public static final List<String> CIPHERS;
 
     private static final List<String> CIPHERS_JAVA_MOZILLA_INCREASED_SECURITY = Collections.unmodifiableList(Arrays
             .asList(
             /* Java 8 */
-            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", /* openssl = ECDHE-ECDSA-AES256-GCM-SHA384 */
-            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", /* openssl = ECDHE-ECDSA-AES128-GCM-SHA256 */
-            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", /* openssl = ECDHE-RSA-AES256-GCM-SHA384 */
+            /* openssl = ECDHE-ECDSA-AES256-GCM-SHA384 */
+            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+            "SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+            /* openssl = ECDHE-ECDSA-AES128-GCM-SHA256 */
+            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+            "SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+            /* openssl = ECDHE-RSA-AES256-GCM-SHA384 */
+            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+            "SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+
             /* REQUIRED BY HTTP/2 SPEC */
-            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", /* openssl = ECDHE-RSA-AES128-GCM-SHA256 */
+            /* openssl = ECDHE-RSA-AES128-GCM-SHA256 */
+            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+            "SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+
             /* REQUIRED BY HTTP/2 SPEC */
-            "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", /* openssl = DHE-RSA-AES128-GCM-SHA256 */
-            "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" /* openssl = DHE-DSS-AES128-GCM-SHA256 */));
+            /* openssl = DHE-RSA-AES128-GCM-SHA256 */
+            "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
+            "SSL_DHE_RSA_WITH_AES_128_GCM_SHA256",
+            /* openssl = DHE-DSS-AES128-GCM-SHA256 */
+            "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
+            "SSL_DHE_DSS_WITH_AES_128_GCM_SHA256"
+            ));
 
     private static final List<String> CIPHERS_JAVA_NO_MOZILLA_INCREASED_SECURITY = Collections.unmodifiableList(Arrays
             .asList(
             /* Java 8 */
-            "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", /* openssl = DHE-RSA-AES256-GCM-SHA384 */
-            "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384" /* openssl = DHE-DSS-AES256-GCM-SHA384 */));
+            /* openssl = DHE-RSA-AES256-GCM-SHA384 */
+            "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
+            "SSL_DHE_RSA_WITH_AES_256_GCM_SHA384",
+            /* openssl = DHE-DSS-AES256-GCM-SHA384 */
+            "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
+            "SSL_DHE_DSS_WITH_AES_256_GCM_SHA384"
+            ));
 
     static {
         List<String> ciphers = new ArrayList<String>(CIPHERS_JAVA_MOZILLA_INCREASED_SECURITY.size()


Test patch: