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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/netty/876f9cb6-9b29-43fa-9309-239b24661432%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to