Hey Rogan, Maybe you want to provide a PR for netty to not pass I note null stuff ?
Sorry but I never used Bouncycastle so I am not a big help. > On 25. Oct 2017, at 16:03, Rogan Dawes <[email protected]> wrote: > > Seems like I'm talking to myself here :-( > > Anyway, current status is that BouncyCastle requires use of the PKIX > implementation of a KeyManager, and this is not the default. In order to do > this, it looks like I have to replicate a whole lot of code that already > exists in SslContextBuilder and SslContext, unless I do: > > Security.setProperty("ssl.KeyManagerFactory.algorithm","PKIX"); > > But that feels like a "big stick" approach, being a global change! :-( > > Also also noted that I have to change JdkSslServerContext (and place a copy > in my own code), because when initialising the SSLContext, it passes a null > value instead of a SecureRandom instance.: > > SSLContext ctx = sslContextProvider == null ? > SSLContext.getInstance(PROTOCOL) > : SSLContext.getInstance(PROTOCOL, sslContextProvider); > ctx.init(keyManagerFactory.getKeyManagers(), > trustManagerFactory == null ? null : > trustManagerFactory.getTrustManagers(), > null); > > BouncyCastle does not like that at all. > > Rogan > > On Thursday, October 5, 2017 at 1:06:20 PM UTC+2, Rogan Dawes wrote: > Ok, so I figured out I could specify > > sslContextBuilder.sslContextProvider(Security.getProvider("BCJSSE")); > > > Now it seems that I'm not configuring something correctly for EC algorithms, > or else Netty and BouncyCastle are not playing nicely together. Below is a > slightly modified EchoServer. It pre-loads the BouncyCastle providers, and > uses a pre-generated EC key and certificate, since SelfSignedCertificate is > hard coded to use RSA. > > package io.netty.example.echo; > > > > import java.io.ByteArrayInputStream; > > import java.security.Security; > > > > import javax.net.ssl.SSLEngine; > > > > import org.bouncycastle.jce.provider.BouncyCastleProvider; > > import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; > > > > import io.netty.bootstrap.ServerBootstrap; > > import io.netty.channel.ChannelFuture; > > import io.netty.channel.ChannelHandler.Sharable; > > import io.netty.channel.ChannelHandlerContext; > > import io.netty.channel.ChannelInboundHandlerAdapter; > > import io.netty.channel.ChannelInitializer; > > import io.netty.channel.ChannelOption; > > import io.netty.channel.ChannelPipeline; > > import io.netty.channel.EventLoopGroup; > > import io.netty.channel.nio.NioEventLoopGroup; > > import io.netty.channel.socket.SocketChannel; > > import io.netty.channel.socket.nio.NioServerSocketChannel; > > import io.netty.handler.logging.LogLevel; > > import io.netty.handler.logging.LoggingHandler; > > import io.netty.handler.ssl.SslContext; > > import io.netty.handler.ssl.SslContextBuilder; > > import io.netty.handler.ssl.SslHandler; > > > > /** > > * Echoes back any received data from a client. > > */ > > public final class EchoServer { > > > > private static byte[] KEY = > > ("-----BEGIN PRIVATE KEY-----\n" > > + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgujVVI0eva1wiEgIK\n" > > + "lBon2bp0ZFnS8JCuYe3djnfvPG6hRANCAARXIyQz9p/u9IdnLX/hKokNTD5VLMTX\n" > > + "OwA+sTCBY4i2iyZBr0IJQ2ckcoOaljMIFDL/ZKsZKM0hJsoylUD9ZVW1\n" > > + "-----END PRIVATE KEY-----\n").getBytes(); > > private static byte[] CERT = > > ("-----BEGIN CERTIFICATE-----\n" > > + "MIIBHDCBwqADAgECAgRZ1gxLMAoGCCqGSM49BAMCMBYxFDASBgNVBAMMC2V4YW1w\n" > > + "bGUub3JnMB4XDTE3MTAwNTEwNDIxOFoXDTE4MTAwNTEwNDIxOFowFjEUMBIGA1UE\n" > > + "AwwLZXhhbXBsZS5vcmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARXIyQz9p/u\n" > > + "9IdnLX/hKokNTD5VLMTXOwA+sTCBY4i2iyZBr0IJQ2ckcoOaljMIFDL/ZKsZKM0h\n" > > + "JsoylUD9ZVW1MAoGCCqGSM49BAMCA0kAMEYCIQD2/7J9u4Cz5ewdgXAe7jM9B3w2\n" > > + "R8Cg4Tph4i9629mF1QIhAL59cMvwwEuN7HxYYZoZNB3nGOoMVFXwVvdZwuMhOo5Z\n" > > + "-----END CERTIFICATE-----").getBytes(); > > > > public static void main(String[] args) throws Exception { > > // Configure SSL. > > Security.addProvider(new BouncyCastleProvider()); > > BouncyCastleJsseProvider bcjsp = new BouncyCastleJsseProvider(); > > Security.addProvider(bcjsp); > > > > ByteArrayInputStream cert = new ByteArrayInputStream(CERT); > > ByteArrayInputStream key = new ByteArrayInputStream(KEY); > > final SslContext sslCtx = SslContextBuilder.forServer(cert, > key).sslContextProvider(bcjsp).build(); > > > > // Configure the server. > > EventLoopGroup bossGroup = new NioEventLoopGroup(1); > > EventLoopGroup workerGroup = new NioEventLoopGroup(); > > try { > > ServerBootstrap b = new ServerBootstrap(); > > b.group(bossGroup, > workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, > 100) > > .handler(new LoggingHandler(LogLevel.INFO)).childHandler(new > ChannelInitializer<SocketChannel>() { > > @Override > > public void initChannel(SocketChannel ch) throws Exception { > > ChannelPipeline p = ch.pipeline(); > > > SslHandler s = sslCtx.newHandler(ch.alloc()); > > SSLEngine e = s.engine(); > > e.setEnabledCipherSuites(e.getSupportedCipherSuites()); > > p.addLast(s); > > > p.addLast(new LoggingHandler(LogLevel.INFO)); > > p.addLast(new EchoServerHandler()); > > } > > }); > > > > // Start the server. > > ChannelFuture f = b.bind(4433).sync(); > > > > // Wait until the server socket is closed. > > f.channel().closeFuture().sync(); > > } finally { > > // Shut down all event loops to terminate all threads. > > bossGroup.shutdownGracefully(); > > workerGroup.shutdownGracefully(); > > } > > } > > > > @Sharable > > public static class EchoServerHandler extends ChannelInboundHandlerAdapter { > > > > @Override > > public void channelRead(ChannelHandlerContext ctx, Object msg) { > > ctx.write(msg); > > } > > > > @Override > > public void channelReadComplete(ChannelHandlerContext ctx) { > > ctx.flush(); > > } > > > > @Override > > public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { > > // Close the connection when an exception is raised. > > cause.printStackTrace(); > > ctx.close(); > > } > > } > > } > > > I try to connect to it using OpenSSL (1.1 has better support for EC > algorithms, it seems, in particular): > > openssl s_client > > And I get: > > Oct 05, 2017 1:00:48 PM org.bouncycastle.jsse.provider.ProvTlsServer > notifyAlertRaised > > INFO: Server raised fatal(2) handshake_failure(40) alert: Failed to read > record > > org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40) > > at org.bouncycastle.tls.AbstractTlsServer.getSelectedCipherSuite(Unknown > Source) > > at > org.bouncycastle.jsse.provider.ProvTlsServer.getSelectedCipherSuite(Unknown > Source) > > at org.bouncycastle.tls.TlsServerProtocol.sendServerHelloMessage(Unknown > Source) > > at org.bouncycastle.tls.TlsServerProtocol.handleHandshakeMessage(Unknown > Source) > > at org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(Unknown Source) > > at org.bouncycastle.tls.TlsProtocol.processRecord(Unknown Source) > > at org.bouncycastle.tls.RecordStream.readRecord(Unknown Source) > > at org.bouncycastle.tls.TlsProtocol.safeReadRecord(Unknown Source) > > at org.bouncycastle.tls.TlsProtocol.offerInput(Unknown Source) > > at org.bouncycastle.jsse.provider.ProvSSLEngine.unwrap(Unknown Source) > > at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) > > at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:281) > > at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1215) > > at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1127) > > at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1162) > > at > io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) > > at > io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) > > at > io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) > > at > io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) > > at > io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) > > at > io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) > > at > io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359) > > at > io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) > > at > io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) > > at > io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935) > > at > io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) > > at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) > > at > io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) > > at > io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) > > at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) > > at > io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) > > at > io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138) > > at java.lang.Thread.run(Thread.java:748) > > > I have confirmed that this works using old-style Threads, etc, and can > provide that code here if needed. > > Any idea what I am doing wrong? If I remove the > "builder.sslContextProvider(bcjsp)", it also works, BUT only BouncyCastle has > support for "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", which need! Sigh! > > Rogan > > On Tuesday, September 26, 2017 at 9:40:55 AM UTC+2, Rogan Dawes wrote: > Hi, > > I'm trying to write a proxy to intercept COAP connections from an embedded > device. I am able to clone the TLS certificates that it thinks it is > connecting to, obviously using my own keys (for the TLS server side), and > insert the CA cert into the firmware of this device. By this, I mean that an > ASN.1 dump of my CA certificate and the "expected" CA certificate show > differences only in the actual key values, not any other parameters of the > keys or certificates. > > However, so far I have been unable to convince netty to negotiate a > connection using the only supported algorithm offered by the device, being > TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8. When I do, I get handshake errors that > the handshaker was unable to establish a common cipher suite. > > I have tried using the native JDK 8 options (build 1.8.0_102-b14), as well as > tried specifying use of the Openssl provider via > > > sslContext = SslContextBuilder.forServer(km.getPrivateKey(target), > km.getCertificateChain(target)) > > .sslContextProvider(new BouncyCastleProvider()).build(); > > > > I have also tried: > > > > sslContext = SslContextBuilder.forServer(km.getPrivateKey(target), > km.getCertificateChain(target)) > > > .sslProvider(SslProvider.OPENSSL).build(); > > > > where km is an X509KeyManager instance that holds the relevant keys. > > > > Any suggestions? > > > > Rogan > > > > > -- > You received this message because you are subscribed to the Google Groups > "Netty discussions" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected] > <mailto:[email protected]>. > To view this discussion on the web visit > https://groups.google.com/d/msgid/netty/08e97b0d-4be2-4ab3-8c6b-65455a0c5d57%40googlegroups.com > > <https://groups.google.com/d/msgid/netty/08e97b0d-4be2-4ab3-8c6b-65455a0c5d57%40googlegroups.com?utm_medium=email&utm_source=footer>. > For more options, visit https://groups.google.com/d/optout > <https://groups.google.com/d/optout>. -- You received this message because you are subscribed to the Google Groups "Netty discussions" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/netty/9980AA91-B445-4B29-BB16-8264FADF1470%40googlemail.com. For more options, visit https://groups.google.com/d/optout.
