marianobarrios / tls-channel

A Java library that implements a ByteChannel interface over SSLEngine, enabling easy-to-use (socket-like) TLS for Java applications.
MIT License
191 stars 49 forks source link

client channel reads only first TLS record #25

Closed caribbeantiger closed 3 years ago

caribbeantiger commented 3 years ago

when using Selector loop for client channel, if TLS Server sends multiple TLS Records in same TCP packet, we only get the first TLS Record from read method.

tcpdump show packet contains multiple TLS Records

48 2021-08-16 15:23:50.236035636 x.x.x.x -> y.y.y.y TLSv1.2 1391 Application Data, Application Data, Application Data

                            TLSv1.2 Record Layer: Application Data Protocol: Application Data
                                Content Type: Application Data (23)
                                Version: TLS 1.2 (0x0303)
                                Length: 173
                                Encrypted Application Data: e0e5033ea1811614857cb954f51fa26e21919788d611f895...
                            TLSv1.2 Record Layer: Application Data Protocol: Application Data
                                Content Type: Application Data (23)
                                Version: TLS 1.2 (0x0303)
                                Length: 173
                                Encrypted Application Data: e0e5033ea181161522c96bca30dde18cd7ad32e352c874bc...
                            TLSv1.2 Record Layer: Application Data Protocol: Application Data
                                Content Type: Application Data (23)
                                Version: TLS 1.2 (0x0303)
                                Length: 964
                                Encrypted Application Data: e0e5033ea181161636ff5acc89b1cddf97ec288eb3f3e204...

here in the log you can see it reads 1325 from rawsocket, but then sends only 149 bytes, which would be just the first TLS record

08-16-2021 15:23:50,236 TRACE [TlsChannelImpl] Read from channel; response: 1325, buffer: java.nio.DirectByteBuffer[pos=1325 lim=4096 cap=4096] 08-16-2021 15:23:50,237 TRACE [TlsChannelImpl] engine.unwrap() result [status=OK,handshakeStatus=NOT_HANDSHAKING,bytesProduced=149,bytesConsumed=178]. Engine status: NOT_HANDSHAKING; inEncrypted tlschannel.impl.BufferHolder@41ec220d; inPlain: ByteBufferSet[array=[java.n io.HeapByteBuffer[pos=149 lim=4096 cap=4096]], offset=0, length=1] 08-16-2021 15:23:50,237 TRACE [Connection] Total Bytes read from TLS Buffer: 149

marianobarrios commented 3 years ago

Hi JMC,

I am not sure if I understand the problem. TLS channel consumes indeed TLS records, but emits the unencrypted byte stream, not records. In TLS records sometimes come and go (negotiation and renegotiation) without any plaintext bytes being received.

That said, I would like to clarify that the read() method will return as soon plantext bytes are there, even if encrypted bytes were already read. However, a subsequent read() should return the following bytes immediately (without blocking).

Hope that helps. In any case, a small test case of the failure would be useful.

Regards.