From b1f723c503b371776b2ae67a8cb78c8765387174 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 3 Mar 2017 12:41:39 +0000 Subject: [PATCH] Provide a function to test whether we have unread records pending Also updates SSL_has_pending() to use it. This actually fixes a bug in SSL_has_pending() which is supposed to return 1 if we have any processed or unprocessed data sitting in OpenSSL buffers. However it failed to return 1 if we had processed non-application data pending. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2875) (cherry picked from commit b8c49611bc26c8f9a980b814496a3069cd524b79) --- ssl/record/rec_layer_s3.c | 13 +++++++++++++ ssl/record/record.h | 1 + ssl/ssl_lib.c | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 4a7e59bc99..2f105a4c4d 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -76,11 +76,24 @@ void RECORD_LAYER_release(RECORD_LAYER *rl) SSL3_RECORD_release(rl->rrec, SSL_MAX_PIPELINES); } +/* Checks if we have unprocessed read ahead data pending */ int RECORD_LAYER_read_pending(const RECORD_LAYER *rl) { return SSL3_BUFFER_get_left(&rl->rbuf) != 0; } +/* Checks if we have decrypted unread record data pending */ +int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl) +{ + size_t curr_rec = 0, num_recs = RECORD_LAYER_get_numrpipes(rl); + const SSL3_RECORD *rr = rl->rrec; + + while (curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec])) + curr_rec++; + + return curr_rec < num_recs; +} + int RECORD_LAYER_write_pending(const RECORD_LAYER *rl) { return (rl->numwpipes > 0) diff --git a/ssl/record/record.h b/ssl/record/record.h index 3e1530f139..9bb24311be 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -207,6 +207,7 @@ void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s); void RECORD_LAYER_clear(RECORD_LAYER *rl); void RECORD_LAYER_release(RECORD_LAYER *rl); int RECORD_LAYER_read_pending(const RECORD_LAYER *rl); +int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl); int RECORD_LAYER_write_pending(const RECORD_LAYER *rl); int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len); void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 08af56b452..e6e59f2635 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1313,7 +1313,7 @@ int SSL_has_pending(const SSL *s) * data. That data may not result in any application data, or we may fail * to parse the records for some reason. */ - if (SSL_pending(s)) + if (RECORD_LAYER_processed_read_pending(&s->rlayer)) return 1; return RECORD_LAYER_read_pending(&s->rlayer); -- 2.25.1