Provide a function to test whether we have unread records pending
authorMatt Caswell <matt@openssl.org>
Fri, 3 Mar 2017 12:41:39 +0000 (12:41 +0000)
committerMatt Caswell <matt@openssl.org>
Tue, 7 Mar 2017 16:45:34 +0000 (16:45 +0000)
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 <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2875)
(cherry picked from commit b8c49611bc26c8f9a980b814496a3069cd524b79)

ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/ssl_lib.c

index 4a7e59bc990bd61d33ea29ab0635d7e055655d3d..2f105a4c4d27408f7fe2551f250620964a3a7994 100644 (file)
@@ -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)
index 3e1530f1391012d2a4b662c26d3fcbdebdb45b92..9bb24311be43df0f24b5b9aaa4c342a50b9ed66c 100644 (file)
@@ -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);
index 08af56b452bcf46302f98bb8a3727613fa1279e9..e6e59f26358b221d1147c29a8630652b552d4b3d 100644 (file)
@@ -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);