Search in sources :

Example 11 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project vert.x by eclipse.

the class ChannelProvider method initSSL.

private void initSSL(Handler<Channel> handler, SocketAddress peerAddress, String serverName, boolean ssl, boolean useAlpn, Channel ch, Promise<Channel> channelHandler) {
    if (ssl) {
        SslHandler sslHandler = new SslHandler(sslHelper.createEngine(context.owner(), peerAddress, serverName, useAlpn));
        sslHandler.setHandshakeTimeout(sslHelper.getSslHandshakeTimeout(), sslHelper.getSslHandshakeTimeoutUnit());
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast("ssl", sslHandler);
        pipeline.addLast(new ChannelInboundHandlerAdapter() {

            @Override
            public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                if (evt instanceof SslHandshakeCompletionEvent) {
                    // Notify application
                    SslHandshakeCompletionEvent completion = (SslHandshakeCompletionEvent) evt;
                    if (completion.isSuccess()) {
                        // Remove from the pipeline after handshake result
                        ctx.pipeline().remove(this);
                        applicationProtocol = sslHandler.applicationProtocol();
                        if (handler != null) {
                            context.dispatch(ch, handler);
                        }
                        channelHandler.setSuccess(ctx.channel());
                    } else {
                        SSLHandshakeException sslException = new SSLHandshakeException("Failed to create SSL connection");
                        sslException.initCause(completion.cause());
                        channelHandler.setFailure(sslException);
                    }
                }
                ctx.fireUserEventTriggered(evt);
            }

            @Override
            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            // Ignore these exception as they will be reported to the handler
            }
        });
    }
}
Also used : SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) SslHandler(io.netty.handler.ssl.SslHandler) SSLHandshakeException(javax.net.ssl.SSLHandshakeException)

Example 12 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.

the class SocketSslEchoTest method testSslEcho.

public void testSslEcho(ServerBootstrap sb, Bootstrap cb) throws Throwable {
    final ExecutorService delegatedTaskExecutor = Executors.newCachedThreadPool();
    reset();
    sb.childOption(ChannelOption.AUTO_READ, autoRead);
    cb.option(ChannelOption.AUTO_READ, autoRead);
    sb.childHandler(new ChannelInitializer<Channel>() {

        @Override
        public void initChannel(Channel sch) {
            serverChannel = sch;
            if (serverUsesDelegatedTaskExecutor) {
                SSLEngine sse = serverCtx.newEngine(sch.alloc());
                serverSslHandler = new SslHandler(sse, delegatedTaskExecutor);
            } else {
                serverSslHandler = serverCtx.newHandler(sch.alloc());
            }
            serverSslHandler.setHandshakeTimeoutMillis(0);
            sch.pipeline().addLast("ssl", serverSslHandler);
            if (useChunkedWriteHandler) {
                sch.pipeline().addLast(new ChunkedWriteHandler());
            }
            sch.pipeline().addLast("serverHandler", serverHandler);
        }
    });
    final CountDownLatch clientHandshakeEventLatch = new CountDownLatch(1);
    cb.handler(new ChannelInitializer<Channel>() {

        @Override
        public void initChannel(Channel sch) {
            clientChannel = sch;
            if (clientUsesDelegatedTaskExecutor) {
                SSLEngine cse = clientCtx.newEngine(sch.alloc());
                clientSslHandler = new SslHandler(cse, delegatedTaskExecutor);
            } else {
                clientSslHandler = clientCtx.newHandler(sch.alloc());
            }
            clientSslHandler.setHandshakeTimeoutMillis(0);
            sch.pipeline().addLast("ssl", clientSslHandler);
            if (useChunkedWriteHandler) {
                sch.pipeline().addLast(new ChunkedWriteHandler());
            }
            sch.pipeline().addLast("clientHandler", clientHandler);
            sch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

                @Override
                public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                    if (evt instanceof SslHandshakeCompletionEvent) {
                        clientHandshakeEventLatch.countDown();
                    }
                    ctx.fireUserEventTriggered(evt);
                }
            });
        }
    });
    final Channel sc = sb.bind().sync().channel();
    cb.connect(sc.localAddress()).sync();
    final Future<Channel> clientHandshakeFuture = clientSslHandler.handshakeFuture();
    // Wait for the handshake to complete before we flush anything. SslHandler should flush non-application data.
    clientHandshakeFuture.sync();
    clientHandshakeEventLatch.await();
    clientChannel.writeAndFlush(Unpooled.wrappedBuffer(data, 0, FIRST_MESSAGE_SIZE));
    clientSendCounter.set(FIRST_MESSAGE_SIZE);
    boolean needsRenegotiation = renegotiation.type == RenegotiationType.CLIENT_INITIATED;
    Future<Channel> renegoFuture = null;
    while (clientSendCounter.get() < data.length) {
        int clientSendCounterVal = clientSendCounter.get();
        int length = Math.min(random.nextInt(1024 * 64), data.length - clientSendCounterVal);
        ByteBuf buf = Unpooled.wrappedBuffer(data, clientSendCounterVal, length);
        if (useCompositeByteBuf) {
            buf = Unpooled.compositeBuffer().addComponent(true, buf);
        }
        ChannelFuture future = clientChannel.writeAndFlush(buf);
        clientSendCounter.set(clientSendCounterVal += length);
        future.sync();
        if (needsRenegotiation && clientSendCounterVal >= data.length / 2) {
            needsRenegotiation = false;
            clientSslHandler.engine().setEnabledCipherSuites(new String[] { renegotiation.cipherSuite });
            renegoFuture = clientSslHandler.renegotiate();
            logStats("CLIENT RENEGOTIATES");
            assertThat(renegoFuture, is(not(sameInstance(clientHandshakeFuture))));
        }
    }
    // Ensure all data has been exchanged.
    while (clientRecvCounter.get() < data.length) {
        if (serverException.get() != null) {
            break;
        }
        if (serverException.get() != null) {
            break;
        }
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
        // Ignore.
        }
    }
    while (serverRecvCounter.get() < data.length) {
        if (serverException.get() != null) {
            break;
        }
        if (clientException.get() != null) {
            break;
        }
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
        // Ignore.
        }
    }
    // Wait until renegotiation is done.
    if (renegoFuture != null) {
        renegoFuture.sync();
    }
    if (serverHandler.renegoFuture != null) {
        serverHandler.renegoFuture.sync();
    }
    serverChannel.close().awaitUninterruptibly();
    clientChannel.close().awaitUninterruptibly();
    sc.close().awaitUninterruptibly();
    delegatedTaskExecutor.shutdown();
    if (serverException.get() != null && !(serverException.get() instanceof IOException)) {
        throw serverException.get();
    }
    if (clientException.get() != null && !(clientException.get() instanceof IOException)) {
        throw clientException.get();
    }
    if (serverException.get() != null) {
        throw serverException.get();
    }
    if (clientException.get() != null) {
        throw clientException.get();
    }
    // When renegotiation is done, at least the initiating side should be notified.
    try {
        switch(renegotiation.type) {
            case SERVER_INITIATED:
                assertThat(serverSslHandler.engine().getSession().getCipherSuite(), is(renegotiation.cipherSuite));
                assertThat(serverNegoCounter.get(), is(2));
                assertThat(clientNegoCounter.get(), anyOf(is(1), is(2)));
                break;
            case CLIENT_INITIATED:
                assertThat(serverNegoCounter.get(), anyOf(is(1), is(2)));
                assertThat(clientSslHandler.engine().getSession().getCipherSuite(), is(renegotiation.cipherSuite));
                assertThat(clientNegoCounter.get(), is(2));
                break;
            case NONE:
                assertThat(serverNegoCounter.get(), is(1));
                assertThat(clientNegoCounter.get(), is(1));
        }
    } finally {
        logStats("STATS");
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) SSLEngine(javax.net.ssl.SSLEngine) Channel(io.netty.channel.Channel) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuf(io.netty.buffer.ByteBuf) SslHandler(io.netty.handler.ssl.SslHandler) ChunkedWriteHandler(io.netty.handler.stream.ChunkedWriteHandler) ExecutorService(java.util.concurrent.ExecutorService) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter)

Example 13 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.

the class Http2MultiplexTransportTest method testSslException.

private void testSslException(SslProvider provider, final boolean tlsv13) throws Exception {
    assumeTrue(SslProvider.isAlpnSupported(provider));
    if (tlsv13) {
        assumeTrue(SslProvider.isTlsv13Supported(provider));
    }
    final String protocol = tlsv13 ? "TLSv1.3" : "TLSv1.2";
    SelfSignedCertificate ssc = null;
    try {
        ssc = new SelfSignedCertificate();
        final SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).trustManager(new X509TrustManager() {

            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                throw new CertificateExpiredException();
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                throw new CertificateExpiredException();
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }).sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).protocols(protocol).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers.
        ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers.
        ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).clientAuth(ClientAuth.REQUIRE).build();
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(eventLoopGroup);
        sb.channel(NioServerSocketChannel.class);
        sb.childHandler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
                ch.pipeline().addLast(new Http2FrameCodecBuilder(true).build());
                ch.pipeline().addLast(new Http2MultiplexHandler(DISCARD_HANDLER));
            }
        });
        serverChannel = sb.bind(new InetSocketAddress(NetUtil.LOCALHOST, 0)).syncUninterruptibly().channel();
        final SslContext clientCtx = SslContextBuilder.forClient().keyManager(ssc.key(), ssc.cert()).sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).trustManager(InsecureTrustManagerFactory.INSTANCE).protocols(protocol).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers.
        ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers.
        ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
        final CountDownLatch latch = new CountDownLatch(2);
        final AtomicReference<AssertionError> errorRef = new AtomicReference<AssertionError>();
        Bootstrap bs = new Bootstrap();
        bs.group(eventLoopGroup);
        bs.channel(NioSocketChannel.class);
        bs.handler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(clientCtx.newHandler(ch.alloc()));
                ch.pipeline().addLast(new Http2FrameCodecBuilder(false).build());
                ch.pipeline().addLast(new Http2MultiplexHandler(DISCARD_HANDLER));
                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

                    @Override
                    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                        if (evt instanceof SslHandshakeCompletionEvent) {
                            SslHandshakeCompletionEvent handshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
                            if (handshakeCompletionEvent.isSuccess()) {
                                // the mTLS failure will be send in the next round-trip.
                                if (!tlsv13) {
                                    errorRef.set(new AssertionError("TLSv1.3 expected"));
                                }
                                Http2StreamChannelBootstrap h2Bootstrap = new Http2StreamChannelBootstrap(ctx.channel());
                                h2Bootstrap.handler(new ChannelInboundHandlerAdapter() {

                                    @Override
                                    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                                        if (cause.getCause() instanceof SSLException) {
                                            latch.countDown();
                                        }
                                    }

                                    @Override
                                    public void channelInactive(ChannelHandlerContext ctx) {
                                        latch.countDown();
                                    }
                                });
                                h2Bootstrap.open().addListener(new FutureListener<Channel>() {

                                    @Override
                                    public void operationComplete(Future<Channel> future) {
                                        if (future.isSuccess()) {
                                            future.getNow().writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), false));
                                        }
                                    }
                                });
                            } else if (handshakeCompletionEvent.cause() instanceof SSLException) {
                                // the mTLS failure will be send in the same round-trip.
                                if (tlsv13) {
                                    errorRef.set(new AssertionError("TLSv1.2 expected"));
                                }
                                latch.countDown();
                                latch.countDown();
                            }
                        }
                    }
                });
            }
        });
        clientChannel = bs.connect(serverChannel.localAddress()).syncUninterruptibly().channel();
        latch.await();
        AssertionError error = errorRef.get();
        if (error != null) {
            throw error;
        }
    } finally {
        if (ssc != null) {
            ssc.delete();
        }
    }
}
Also used : SelfSignedCertificate(io.netty.handler.ssl.util.SelfSignedCertificate) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) CertificateExpiredException(java.security.cert.CertificateExpiredException) InetSocketAddress(java.net.InetSocketAddress) CertificateException(java.security.cert.CertificateException) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) SSLException(javax.net.ssl.SSLException) ApplicationProtocolConfig(io.netty.handler.ssl.ApplicationProtocolConfig) Bootstrap(io.netty.bootstrap.Bootstrap) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) SslContext(io.netty.handler.ssl.SslContext) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) Channel(io.netty.channel.Channel) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) X509Certificate(java.security.cert.X509Certificate) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) X509TrustManager(javax.net.ssl.X509TrustManager) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter)

Example 14 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project rest.li by linkedin.

the class Http2AlpnHandler method userEventTriggered.

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    if (evt instanceof SslHandshakeCompletionEvent) {
        SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;
        if (handshakeEvent.isSuccess()) {
            LOG.debug("SSL handshake succeeded");
            SslHandler sslHandler = ctx.pipeline().get(SslHandler.class);
            if (sslHandler == null) {
                ctx.fireExceptionCaught(new IllegalStateException("cannot find a SslHandler in the pipeline (required for " + "application-level protocol negotiation)"));
                return;
            }
            String protocol = sslHandler.applicationProtocol();
            if (ApplicationProtocolNames.HTTP_2.equals(protocol)) {
                LOG.debug("HTTP/2 is negotiated");
                // Add HTTP/2 handler
                // by "adding before" the alpn handler, we guarantee that once the alpnPromise is completed
                // the request will be handled by the codec and all the possible exceptions thrown will be
                // handled by a single stream instead of the whole channel
                ctx.pipeline().addBefore(PIPELINE_ALPN_HANDLER, Http2StreamCodec.PIPELINE_HTTP2_CODEC_HANDLER, _http2Handler);
                // Remove handler from pipeline after negotiation is complete
                ctx.pipeline().remove(this);
                _alpnPromise.setSuccess();
            } else {
                LOG.error("Protocol {}, instead of HTTP/2, is negotiated through ALPN", protocol);
                _alpnPromise.setFailure(new IllegalStateException("HTTP/2 ALPN negotiation failed"));
            }
        } else {
            LOG.error("SSL handshake failed", handshakeEvent.cause());
            _alpnPromise.setFailure(handshakeEvent.cause());
        }
    }
    ctx.fireUserEventTriggered(evt);
}
Also used : SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) SessionResumptionSslHandler(com.linkedin.r2.netty.handler.common.SessionResumptionSslHandler) SslHandler(io.netty.handler.ssl.SslHandler)

Example 15 with SslHandshakeCompletionEvent

use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project vert.x by eclipse.

the class SslHandshakeCompletionHandler method userEventTriggered.

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
    if (evt instanceof SniCompletionEvent) {
        // Shall we care ?
        SniCompletionEvent completion = (SniCompletionEvent) evt;
        Attribute<String> val = ctx.channel().attr(SERVER_NAME_ATTR);
        val.set(completion.hostname());
    } else if (evt instanceof SslHandshakeCompletionEvent) {
        SslHandshakeCompletionEvent completion = (SslHandshakeCompletionEvent) evt;
        if (completion.isSuccess()) {
            ctx.pipeline().remove(this);
            promise.setSuccess(null);
        } else {
            promise.tryFailure(completion.cause());
        }
    } else {
        ctx.fireUserEventTriggered(evt);
    }
}
Also used : SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) SniCompletionEvent(io.netty.handler.ssl.SniCompletionEvent)

Aggregations

SslHandshakeCompletionEvent (io.netty.handler.ssl.SslHandshakeCompletionEvent)16 SslHandler (io.netty.handler.ssl.SslHandler)8 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)7 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)7 Channel (io.netty.channel.Channel)5 Bootstrap (io.netty.bootstrap.Bootstrap)4 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)4 NioServerSocketChannel (io.netty.channel.socket.nio.NioServerSocketChannel)4 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)4 SslContext (io.netty.handler.ssl.SslContext)4 InetSocketAddress (java.net.InetSocketAddress)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 ChannelFuture (io.netty.channel.ChannelFuture)3 ChannelFutureListener (io.netty.channel.ChannelFutureListener)2 ChannelInitializer (io.netty.channel.ChannelInitializer)2 EventLoopGroup (io.netty.channel.EventLoopGroup)2 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)2 NioDatagramChannel (io.netty.channel.socket.nio.NioDatagramChannel)2 ApplicationProtocolConfig (io.netty.handler.ssl.ApplicationProtocolConfig)2 SniCompletionEvent (io.netty.handler.ssl.SniCompletionEvent)2