Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Got handshake_failure using java/netty, but succeeded with curl for the same https url

Tags:

java

ssl

netty

I have an MITM proxy server built with java/netty. Recently I ran into an https url, for which my proxy gets an SSL handshake failure but the curl command is able to access in TLS protocol. In my proxy code, the client SSL context uses a trust-all trust manager. Below is how I create the client-side SSL context and SSL handler.

public static SSLContext createClientSslContext() throws NoSuchAlgorithmException, KeyManagementException {
    SSLContext context = SSLContext.getInstance("TLS");

    // create a trust-all manager
    TrustManager trustAllManager = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            log.debug("do nothing - getAcceptedIssuers");
            return new X509Certificate[0];
        }
    };
    context.init(null, new TrustManager[]{trustAllManager}, null);
    return context;
}


private SslHandler createClientSslHandler() {
    try {
        SSLContext context = SslContextFactory.createClientSslContext();
        SSLEngine engine = context.createSSLEngine();
        engine.setUseClientMode(true);
        engine.setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"});
        return new SslHandler(engine);
    } catch (Exception e) {
        log.error("Failed to create SslHandler with exception:", e);
        return null;
    }
}

I set javax.net.debug=all. Below is error output.

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1429274460 bytes = { 38, 155, 211, 75, 172, 225, 176, 73, 59, 96, 150, 25, 105, 108, 225, 216, 178, 171, 40, 154, 59, 187, 206, 50, 87, 63, 46, 137 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
[write] MD5 and SHA1 hashes:  len = 193
0000: 01 00 00 BD 03 03 55 31   FF 5C 26 9B D3 4B AC E1  ......U1.\&..K..
0010: B0 49 3B 60 96 19 69 6C   E1 D8 B2 AB 28 9A 3B BB  .I;`..il....(.;.
0020: CE 32 57 3F 2E 89 00 00   38 C0 23 C0 27 00 3C C0  .2W?....8.#.'.<.
0030: 25 C0 29 00 67 00 40 C0   09 C0 13 00 2F C0 04 C0  %.).g.@...../...
0040: 0E 00 33 00 32 C0 08 C0   12 00 0A C0 03 C0 0D 00  ..3.2...........
0050: 16 00 13 C0 07 C0 11 00   05 C0 02 C0 0C 00 04 00  ................
0060: FF 01 00 00 5C 00 0A 00   34 00 32 00 17 00 01 00  ....\...4.2.....
0070: 03 00 13 00 15 00 06 00   07 00 09 00 0A 00 18 00  ................
0080: 0B 00 0C 00 19 00 0D 00   0E 00 0F 00 10 00 11 00  ................
0090: 02 00 12 00 04 00 05 00   14 00 08 00 16 00 0B 00  ................
00A0: 02 01 00 00 0D 00 1A 00   18 06 03 06 01 05 03 05  ................
00B0: 01 04 03 04 01 03 03 03   01 02 03 02 01 02 02 01  ................
00C0: 01                                                 .
nioEventLoopGroup-15-0, WRITE: TLSv1.2 Handshake, length = 193
[Raw write]: length = 198
0000: 16 03 03 00 C1 01 00 00   BD 03 03 55 31 FF 5C 26  ...........U1.\&
0010: 9B D3 4B AC E1 B0 49 3B   60 96 19 69 6C E1 D8 B2  ..K...I;`..il...
0020: AB 28 9A 3B BB CE 32 57   3F 2E 89 00 00 38 C0 23  .(.;..2W?....8.#
0030: C0 27 00 3C C0 25 C0 29   00 67 00 40 C0 09 C0 13  .'.<.%.).g.@....
0040: 00 2F C0 04 C0 0E 00 33   00 32 C0 08 C0 12 00 0A  ./.....3.2......
0050: C0 03 C0 0D 00 16 00 13   C0 07 C0 11 00 05 C0 02  ................
0060: C0 0C 00 04 00 FF 01 00   00 5C 00 0A 00 34 00 32  .........\...4.2
0070: 00 17 00 01 00 03 00 13   00 15 00 06 00 07 00 09  ................
0080: 00 0A 00 18 00 0B 00 0C   00 19 00 0D 00 0E 00 0F  ................
0090: 00 10 00 11 00 02 00 12   00 04 00 05 00 14 00 08  ................
00A0: 00 16 00 0B 00 02 01 00   00 0D 00 1A 00 18 06 03  ................
00B0: 06 01 05 03 05 01 04 03   04 01 03 03 03 01 02 03  ................
00C0: 02 01 02 02 01 01                                  ......
[Raw read]: length = 5
0000: 15 03 03 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
nioEventLoopGroup-15-0, READ: TLSv1.2 Alert, length = 2
nioEventLoopGroup-15-0, RECV TLSv1 ALERT:  fatal, handshake_failure
nioEventLoopGroup-15-0, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-15-0, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-15-0, called closeOutbound()
nioEventLoopGroup-15-0, closeOutboundInternal()
nioEventLoopGroup-15-0, SEND TLSv1 ALERT:  warning, description = close_notify
nioEventLoopGroup-15-0, WRITE: TLSv1 Alert, length = 2
nioEventLoopGroup-15-0, called closeInbound()
nioEventLoopGroup-15-0, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
2015-04-17 23:53:16.246 [nioEventLoopGroup-15-0] ERROR ClientHandler#exceptionCaught(): Caught exception
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: handshake_failure
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:347) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:230) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at com.company.proxy.handler.TrafficCounterHandler.channelRead(TrafficCounterHandler.java:29) [classes/:na]
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:956) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:514) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:471) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:385) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:351) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126) [netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
Caused by: javax.net.ssl.SSLException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[na:1.7.0_80]
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1639) ~[na:1.7.0_80]
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1607) ~[na:1.7.0_80]
    at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1776) ~[na:1.7.0_80]
    at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1068) ~[na:1.7.0_80]
    at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:890) ~[na:1.7.0_80]
    at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:764) ~[na:1.7.0_80]
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[na:1.7.0_80]
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1071) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:938) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:891) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:316) ~[netty-all-5.0.0.Alpha2.jar:5.0.0.Alpha2]
    ... 23 common frames omitted
nioEventLoopGroup-15-0, called closeOutbound()
nioEventLoopGroup-15-0, closeOutboundInternal()
nioEventLoopGroup-15-0, called closeInbound()
nioEventLoopGroup-15-0, closeInboundInternal()
nioEventLoopGroup-15-0, closeOutboundInternal()

I have tried both JDK 7 and JDK 8, and neither gave me any luck. I also installed the unlimited-strength JCE policies, but no luck either. Given that curl command is able to access the https url successfully, I think the url itself should be fine. So, how can I make it work in Java/netty?

BTW, I am not sure if it is ok to disclose the https url in question, so I choose not to in order to avoid unnecessary trouble.

update
From the curl -v output, I can see this line:

* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

The cipher TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 is present in the ClientHello message, so missing-cipher is unlikely the root cause here.

update
I made two tests for the same https url, one using jersey-client, and the other using my own custom netty client. Below is the code.

@Test
public void testHandshakeFailedUrlWithJersey() throws Exception {
    String url = "https://cdn.prod.paperg.com/ajax/libs/require.js/2.1.10/require.js";
    Client client = ClientBuilder.newClient();

    Response response = null;
    try {
        response = client.target(url).request().get();
    } catch (Exception e) {
        e.printStackTrace();
    }
    log.info("Response - {}", response);
}

@Test
public void testHandshakeFailedUrlWithNetty() throws Exception {
    String url = "https://cdn.prod.paperg.com/ajax/libs/require.js/2.1.10/require.js";
    Bootstrap clientBootstrap = new Bootstrap();
    EventLoopGroup clientGroup = new NioEventLoopGroup();

    SSLContext context = SslContextFactory.createClientSslContext();
    SSLEngine engine = context.createSSLEngine();
    engine.setUseClientMode(true);
    engine.setEnabledProtocols(new String[]{"TLSv1"});
    final SslHandler sslHandler = new SslHandler(engine);

    clientBootstrap.group(clientGroup)
            .channel(NioSocketChannel.class)
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline p = ch.pipeline();
                    p.addLast(CLIENT_SSL_HANDLER, sslHandler)
                            .addLast(HTTP_CLIENT_CODEC, new HttpClientCodec())
                            .addLast(HTTP_CONTENT_AGGREGATOR, new HttpObjectAggregator(MAX_HTTP_CONTENT_LENGTH))
                            .addLast(CLIENT_HANDLER, new ChannelHandlerAdapter(){
                                @Override
                                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                    log.info("Received message");
                                }
                            });
                }
            });

    String host = "cdn.prod.paperg.com";
    InetSocketAddress inetSocketAddress = new InetSocketAddress(host, 443);
    FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_0,
            HttpMethod.GET, url);
    Channel channel = clientBootstrap.connect(inetSocketAddress).sync().channel();
    channel.writeAndFlush(request);
}

It turns out that the jersey-client test is able to get a valid response, but the netty-client test fails with the same handshake_failure error. BTW, I verified the netty-client test code with https://www.google.com, and it was able to complete the SSL handshake successfully and get a valid certificate.

Below are relevant logs.

From jersey-client test:

trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1429371593 bytes = { 30, 195, 29, 134, 181, 7, 17, 54, 187, 208, 156, 70, 39, 155, 224, 131, 105, 241, 174, 168, 211, 230, 57, 162, 17, 27, 183, 151 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: cdn.prod.paperg.com]
***
main, WRITE: TLSv1 Handshake, length = 191
main, READ: TLSv1 Handshake, length = 61
*** ServerHello, TLSv1
RandomCookie:  GMT: -1685243653 bytes = { 168, 78, 151, 192, 211, 185, 197, 74, 192, 90, 94, 113, 176, 188, 210, 43, 19, 253, 221, 73, 35, 104, 243, 6, 28, 79, 40, 190 }
Session ID:  {}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension server_name, server_name:
Extension renegotiation_info, renegotiated_connection: <empty>
Extension ec_point_formats, formats: [uncompressed, ansiX962_compressed_prime, ansiX962_compressed_char2]
***
%% Initialized:  [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
** TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
main, READ: TLSv1 Handshake, length = 2560
*** Certificate chain

From netty-client test:

trigger seeding of SecureRandom
done seeding SecureRandom
Using SSLEngineImpl.
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1429371694 bytes = { 31, 45, 240, 255, 71, 215, 187, 150, 66, 220, 94, 118, 163, 1, 24, 38, 155, 158, 254, 201, 249, 203, 125, 96, 56, 225, 162, 247 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
nioEventLoopGroup-0-1, WRITE: TLSv1 Handshake, length = 163
nioEventLoopGroup-0-1, READ: TLSv1 Alert, length = 2
nioEventLoopGroup-0-1, RECV TLSv1 ALERT:  fatal, handshake_failure
nioEventLoopGroup-0-1, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-0-1, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
nioEventLoopGroup-0-1, called closeOutbound()
nioEventLoopGroup-0-1, closeOutboundInternal()
nioEventLoopGroup-0-1, SEND TLSv1 ALERT:  warning, description = close_notify
nioEventLoopGroup-0-1, WRITE: TLSv1 Alert, length = 2
nioEventLoopGroup-0-1, called closeInbound()
nioEventLoopGroup-0-1, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?

The only difference that I can see from the two tests is that the jersey-client puts this message in the ClientHello:

Extension server_name, server_name

which is not present in the netty-client test.

like image 630
JBT Avatar asked Oct 20 '22 14:10

JBT


2 Answers

It turns out that the peer host and port matter in my case. This line fixed the issue:

SSLEngine engine = context.createSSLEngine(host, 443);
like image 144
JBT Avatar answered Oct 29 '22 01:10

JBT


OK, here is what solved a similar issue for me (in case anyone else is hitting this problem).

Using the Webupd8 packages on Ubuntu, I had to install oracle-java8-unlimited-jce-policy separately. This enables strong encryption which falls under some US export limitation.

Go figure.

like image 20
Manuel Avatar answered Oct 29 '22 00:10

Manuel