Fix bug with SSL_read_early_data()
authorMatt Caswell <matt@openssl.org>
Wed, 29 Mar 2017 16:00:55 +0000 (17:00 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 30 Mar 2017 08:09:21 +0000 (09:09 +0100)
If read_ahead is set, or SSL_MODE_AUTO_RETRY is used then if
SSL_read_early_data() hits an EndOfEarlyData message then it will
immediately retry automatically, but this time read normal data instead
of early data!

Fixes #3041

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3077)

ssl/record/rec_layer_s3.c

index e8e9329f6ed395255df2630668d91aa8c7edaf03..b51807c088ef64084e8a73dfeb4513248942f241 100644 (file)
@@ -1496,6 +1496,8 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
      */
     if ((s->rlayer.handshake_fragment_len >= 4)
             && !ossl_statem_get_in_handshake(s)) {
      */
     if ((s->rlayer.handshake_fragment_len >= 4)
             && !ossl_statem_get_in_handshake(s)) {
+        int ined = (s->early_data_state == SSL_EARLY_DATA_READING);
+
         /* We found handshake data, so we're going back into init */
         ossl_statem_set_in_init(s, 1);
 
         /* We found handshake data, so we're going back into init */
         ossl_statem_set_in_init(s, 1);
 
@@ -1507,6 +1509,14 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
             return -1;
         }
 
             return -1;
         }
 
+        /*
+         * If we were actually trying to read early data and we found a
+         * handshake message, then we don't want to continue to try and read
+         * the application data any more. It won't be "early" now.
+         */
+        if (ined)
+            return -1;
+
         if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
             if (SSL3_BUFFER_get_left(rbuf) == 0) {
                 /* no read-ahead left? */
         if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
             if (SSL3_BUFFER_get_left(rbuf) == 0) {
                 /* no read-ahead left? */