Skip to content
Advertisement

SSLEngine Handshake stuck at second loop

I’m trying to implement an SSL Handshake using SSLEngine, I need to do it both ways as a sever and as a client as well, however I’m stuck and I cannot figure it out why.

The handshake starts correctly, the Hello’s are exchanged, the keys are exchanged, but then I’m getting into a NEED_UNWRAP state.

Here is the handshake code I’m using:

JavaScript

This is my SSLEngine creating class:

JavaScript

When I’m attempting a handshake as a client. As you can see from the logs, I start in NEED_WRAP, send data to server, states gets to NEED_UNWRAP (which is correct) server responds, I parse the answer without any error, but instead of advancing to NEED_WRAP I get stuck in NEED_UNWRAP…

JavaScript

If I try to do the handshake as a server, logs looks like this. As you can see from the logs, the first read is fine, I respond to the client, I get the second bit of data from the client, and instead of having a NEED_WRAP and being able to carry on with the handshake I’m hit with a NEED_UNWRAP message, but of course there is no more data to be read from the client….

JavaScript

I did had a look at some similar questions on StackOverflow before posting, but they were mainly about order being wrong, which I think I got right in this case… I’m pretty sure I’m missing the obvious, but I just cannot seem to figure it out…

Advertisement

Answer

After 2 days of chasing my own tale, I have finally found the problem as described here: https://github.com/netty/netty/issues/5975

I found that our stream-based wrapper around SSLEngine doesn’t read all incoming data from the SSLEngine when there is no new incoming data from the network, so the application gets stuck waiting for incoming data. After some debugging I found out that with netty’s openssl SSLEngine unwrap seems to produce plain text data in smaller chunks (probably single TLS frames) and keeps buffering the rest of the data internally. The src buffer is fully consumed but calling unwrap again with an empty src buffer will still produce more data. This differs from what the JDK SSLEngine does in two points:

  • the JDK SSLEngine consumes and produces as much data as possible in one go while the openssl one produces less output in one call
  • the JDK SSLEngine doesn’t buffer encrypted data internally between calls to unwrap but “puts them back” into the src buffer

So even my code was “correct” I needed to do multiple loops so now my unwrap codes looks something like this:

JavaScript
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement