Hi guys,
the way we handle incomming SSL data on the server will not work if the
data are fragmented.
Let's say we are receiving some Handshake data. This is typically a few
hundreds of bytes, that usually comes in one block. In this case, we are
all good. But if those data aren't read in one block, then we are dead.
I have simulated such a fragmentation by sending a ClientHello block of
data in three parts : as soon as the SslEngine if given the second block
of data, it throws an exception :
2013-05-03 15:07:15,546 ERROR [SelectorWorker Server-I/O-1]
tcp.NioTcpSession (NioTcpSession.java:330) - Exception while reading :
javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
at
sun.security.ssl.EngineInputRecord.bytesInCompletePacket(EngineInputRecord.java:116)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:845)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:758)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at org.apache.mina.session.SslHelper.unwrap(SslHelper.java:190)
This is plain normal : when we read the first block of data, we unwrap
it, and the SslEngine resturn with a BUFFER_UNDERFLOW status (expected).
Now, we return back to the main loop, and we *clear* the reaBuffer. We
then lose the first bytes we have read, parts that the SslEngine is
expecting to have the next time we call it.
There is one way to avoid such a problem : we just have to compact the
buffer instead of clearing it.
Now, regarding the SSL code, it's really messy atm. The fact that we
separate the handshake from the normal processing of data is wrong. When
we do an unwrap, it will initiate a handshake if needed. The fact is we
have to review the full code and rewrite it...
I'm currently doing some experiments here, but I would be please to
share ideas, suggestion, proposals from any of you...