[openssl-users] ssl_pending returns 0 despite having data to read
Michael.Wojcik at microfocus.com
Wed Jan 11 20:45:01 UTC 2017
> From: openssl-users [mailto:openssl-users-bounces at openssl.org] On Behalf
> Of Nadia Lapkovskaya
> Sent: Wednesday, January 11, 2017 15:08
> During first ssl_read we received eight bytes, and after that ssl_pending
> returns 0. If we continue reading despite having no pending data, ssl_read
> returns the rest of the data.
Are you setting SSL_CTRL_SET_READ_AHEAD? SSL_pending doesn't work if read-ahead is set. See the comment in the definition of SSL_pending in ssl_lib.c
Did the client send a TLS record with more than 8 bytes of application data?
SSL_pending returns true if there's more application data to be read from the current record. (At least that's my interpretation from a quick glance at the source.)
TLS is a record-oriented protocol, but the API is not strictly record-oriented. TLS segments outbound application data into "fragments", with one fragment for each TLS record. If the application makes a single call to SSL_write with a data length that fits in a single fragment, that *should* go out as a single TLS record (I believe); but if the application makes multiple calls to SSL_write or sends a chunk of data that's bigger than the maximum fragment size for the connection, then the partitioning of application data into records is harder to predict.
If you want to know whether there might be additional records waiting, query the socket directly with an API such as select or poll. (If the records haven't made it into the socket's receive buffer yet, you're out of luck; there's no way for the application to tell that more data might arrive some time in the future.)
This isn't an issue for HTTP because HTTP is a self-delimiting protocol. The application can continue to issue receives, parsing what it's received so far, until it knows that it has the entire message. SSL_pending isn't particularly useful for such a protocol, unless it's doing non-blocking I/O - in which case the typical pattern is to loop calling SSL_read as long as either SSL_pending is true or the socket is readable. (Or until OpenSSL returns SSL_WANT_WRITE, in which case you have to wait until the socket is writable instead, because you're renegotiating.)
That's all off the top of my head, so I may have gone wrong there somewhere - in which case no doubt someone will correct me shortly.
Distinguished Engineer, Micro Focus
More information about the openssl-users