]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Convert ssl3_get_record to tls_read_record
authorMatt Caswell <matt@openssl.org>
Tue, 12 Apr 2022 13:50:28 +0000 (14:50 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 18 Aug 2022 15:38:12 +0000 (16:38 +0100)
We move the old ssl3_get_record function to conform with the new record
layer design.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18132)

crypto/err/openssl.txt
include/openssl/sslerr.h
ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/record/record_local.h
ssl/record/recordmethod.h
ssl/record/ssl3_record.c
ssl/record/tlsrecord.c
ssl/ssl_err.c
ssl/statem/statem_lib.c
test/sslapitest.c

index 9ab7c0fdd4808ed6a83d30e2119ee5e4c0f1a322..b9f0f88f4fefb10a2cf3ffa02f5aeeeb33847a27 100644 (file)
@@ -1377,6 +1377,7 @@ SSL_R_INVALID_CT_VALIDATION_TYPE:212:invalid ct validation type
 SSL_R_INVALID_KEY_UPDATE_TYPE:120:invalid key update type
 SSL_R_INVALID_MAX_EARLY_DATA:174:invalid max early data
 SSL_R_INVALID_NULL_CMD_NAME:385:invalid null cmd name
+SSL_R_INVALID_RECORD:317:invalid record
 SSL_R_INVALID_SEQUENCE_NUMBER:402:invalid sequence number
 SSL_R_INVALID_SERVERINFO_DATA:388:invalid serverinfo data
 SSL_R_INVALID_SESSION_ID:999:invalid session id
@@ -1458,6 +1459,7 @@ SSL_R_PSK_NO_CLIENT_CB:224:psk no client cb
 SSL_R_PSK_NO_SERVER_CB:225:psk no server cb
 SSL_R_READ_BIO_NOT_SET:211:read bio not set
 SSL_R_READ_TIMEOUT_EXPIRED:312:read timeout expired
+SSL_R_RECORDS_NOT_RELEASED:321:records not released
 SSL_R_RECORD_LAYER_FAILURE:313:record layer failure
 SSL_R_RECORD_LENGTH_MISMATCH:213:record length mismatch
 SSL_R_RECORD_TOO_SMALL:298:record too small
index e984fe375e3052c92c1b3250d10c82b3bdcb7615..01a79ee48be653184bdcf7442e772ad4f644ad18 100644 (file)
 # define SSL_R_INVALID_KEY_UPDATE_TYPE                    120
 # define SSL_R_INVALID_MAX_EARLY_DATA                     174
 # define SSL_R_INVALID_NULL_CMD_NAME                      385
+# define SSL_R_INVALID_RECORD                             317
 # define SSL_R_INVALID_SEQUENCE_NUMBER                    402
 # define SSL_R_INVALID_SERVERINFO_DATA                    388
 # define SSL_R_INVALID_SESSION_ID                         999
 # define SSL_R_PSK_NO_SERVER_CB                           225
 # define SSL_R_READ_BIO_NOT_SET                           211
 # define SSL_R_READ_TIMEOUT_EXPIRED                       312
+# define SSL_R_RECORDS_NOT_RELEASED                       321
 # define SSL_R_RECORD_LAYER_FAILURE                       313
 # define SSL_R_RECORD_LENGTH_MISMATCH                     213
 # define SSL_R_RECORD_TOO_SMALL                           298
index d7791cf93536c3fb27fdb0f888f6966b2716d68f..d4a92e540e8268f574584c1d3e1ca34b4a9ba994 100644 (file)
@@ -77,19 +77,36 @@ void RECORD_LAYER_release(RECORD_LAYER *rl)
 /* 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;
+    /*
+     * TODO(RECLAYER): Temporarily do it the old way until DTLS is converted to
+     * the new record layer code
+     */
+    if (SSL_CONNECTION_IS_DTLS(rl->s))
+        return SSL3_BUFFER_get_left(&rl->rbuf) != 0;
+
+    return rl->s->rrlmethod->unprocessed_read_pending(rl->s->rrl);
 }
 
 /* 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;
+    /*
+     * TODO(RECLAYER): Temporarily do it the old way until DTLS is converted to
+     * the new record layer code
+     */
+    if (SSL_CONNECTION_IS_DTLS(rl->s)) {
+        const SSL3_RECORD *rr = rl->rrec;
+
+        size_t curr_rec = 0, num_recs = RECORD_LAYER_get_numrpipes(rl);
 
-    while (curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]))
-        curr_rec++;
+        while (curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]))
+            curr_rec++;
 
-    return curr_rec < num_recs;
+        return curr_rec < num_recs;
+    }
+
+    return (rl->curr_rec < rl->num_recs)
+           || rl->s->rrlmethod->processed_read_pending(rl->s->rrl);
 }
 
 int RECORD_LAYER_write_pending(const RECORD_LAYER *rl)
@@ -119,7 +136,10 @@ size_t ssl3_pending(const SSL *s)
     if (sc->rlayer.rstate == SSL_ST_READ_BODY)
         return 0;
 
-    /* Take into account DTLS buffered app data */
+    /*
+     * TODO(RECLAYER): We need to do it the old way temporary for DTLS until
+     * that is converted to use the new record layer code
+     */
     if (SSL_CONNECTION_IS_DTLS(sc)) {
         DTLS1_RECORD_DATA *rdata;
         pitem *item, *iter;
@@ -129,13 +149,19 @@ size_t ssl3_pending(const SSL *s)
             rdata = item->data;
             num += rdata->rrec.length;
         }
-    }
 
-    for (i = 0; i < RECORD_LAYER_get_numrpipes(&sc->rlayer); i++) {
-        if (SSL3_RECORD_get_type(&sc->rlayer.rrec[i])
-            != SSL3_RT_APPLICATION_DATA)
-            return num;
-        num += SSL3_RECORD_get_length(&sc->rlayer.rrec[i]);
+        for (i = 0; i < RECORD_LAYER_get_numrpipes(&sc->rlayer); i++) {
+            if (SSL3_RECORD_get_type(&sc->rlayer.rrec[i])
+                != SSL3_RT_APPLICATION_DATA)
+                return 0;
+            num += SSL3_RECORD_get_length(&sc->rlayer.rrec[i]);
+        }
+    } else {
+        for (i = 0; i <sc->rlayer.num_recs; i++) {
+            if (sc->rlayer.tlsrecs[i].type != SSL3_RT_APPLICATION_DATA)
+                return 0;
+            num += sc->rlayer.tlsrecs[i].length;
+        }
     }
 
     return num;
@@ -1098,6 +1124,51 @@ int ssl3_write_pending(SSL_CONNECTION *s, int type, const unsigned char *buf,
     }
 }
 
+int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int ret, char *file,
+                                  int line)
+{
+    SSL *ssl = SSL_CONNECTION_GET_SSL(s);
+
+    if (ret == OSSL_RECORD_RETURN_RETRY) {
+        s->rwstate = SSL_READING;
+        ret = -1;
+    } else {
+        s->rwstate = SSL_NOTHING;
+        if (ret == OSSL_RECORD_RETURN_EOF) {
+            if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) {
+                SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+                s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY;
+            } else {
+                ERR_new();
+                ERR_set_debug(file, line, 0);
+                ossl_statem_fatal(s, SSL_AD_DECODE_ERROR,
+                                  SSL_R_UNEXPECTED_EOF_WHILE_READING, NULL);
+            }
+        } else if (ret == OSSL_RECORD_RETURN_FATAL) {
+            ERR_new();
+            ERR_set_debug(file, line, 0);
+            ossl_statem_fatal(s, s->rrlmethod->get_alert_code(s->rrl),
+                              SSL_R_RECORD_LAYER_FAILURE, NULL);
+        }
+        /*
+         * The record layer distinguishes the cases of EOF, non-fatal
+         * err and retry. Upper layers do not.
+         * If we got a retry or success then *ret is already correct,
+         * otherwise we need to convert the return value.
+         */
+        /*
+         * TODO(RECLAYER): What does a non fatal err that isn't a retry even
+         * mean???
+         */
+        if (ret == OSSL_RECORD_RETURN_NON_FATAL_ERR || ret == OSSL_RECORD_RETURN_EOF)
+            ret = 0;
+        else if (ret < OSSL_RECORD_RETURN_NON_FATAL_ERR)
+            ret = -1;
+    }
+
+    return ret;
+}
+
 /*-
  * Return up to 'len' payload bytes received in 'type' records.
  * 'type' is one of the following:
@@ -1131,29 +1202,18 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
                     size_t len, int peek, size_t *readbytes)
 {
     int i, j, ret;
-    size_t n, curr_rec, num_recs, totalbytes;
-    SSL3_RECORD *rr;
-    SSL3_BUFFER *rbuf;
+    size_t n, curr_rec, totalbytes;
+    TLS_RECORD *rr;
     void (*cb) (const SSL *ssl, int type2, int val) = NULL;
     int is_tls13;
     SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
 
     is_tls13 = SSL_CONNECTION_IS_TLS13(s);
 
-    rbuf = s->rrlmethod->get0_rbuf(s->rrl);
-
-    if (!SSL3_BUFFER_is_initialised(rbuf)) {
-        /* Not initialized yet */
-        if (!ssl3_setup_read_buffer(s)) {
-            /* SSLfatal() already called */
-            return -1;
-        }
-    }
-
-    if ((type && (type != SSL3_RT_APPLICATION_DATA)
-         && (type != SSL3_RT_HANDSHAKE)) || (peek
-                                             && (type !=
-                                                 SSL3_RT_APPLICATION_DATA))) {
+    if ((type != 0
+            && (type != SSL3_RT_APPLICATION_DATA)
+            && (type != SSL3_RT_HANDSHAKE))
+        || (peek && (type != SSL3_RT_APPLICATION_DATA))) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         return -1;
     }
@@ -1207,35 +1267,27 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
      * rr[i].off,     - offset into 'data' for next read
      * rr[i].length,  - number of bytes.
      */
-    rr = s->rlayer.rrec;
-    num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer);
+    /* get new records if necessary */
+    if (s->rlayer.curr_rec >= s->rlayer.num_recs) {
+        s->rlayer.curr_rec = s->rlayer.num_recs = 0;
+        do {
+            rr = &s->rlayer.tlsrecs[s->rlayer.num_recs];
 
-    do {
-        /* get new records if necessary */
-        if (num_recs == 0) {
-            ret = ssl3_get_record(s);
+            ret = HANDLE_RLAYER_RETURN(s,
+                    s->rrlmethod->read_record(s->rrl, &rr->rechandle,
+                                              &rr->version, &rr->type,
+                                              &rr->data, &rr->length,
+                                              NULL, NULL, s));
             if (ret <= 0) {
                 /* SSLfatal() already called if appropriate */
                 return ret;
             }
-            num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer);
-            if (num_recs == 0) {
-                /* Shouldn't happen */
-                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-                return -1;
-            }
-        }
-        /* Skip over any records we have already read */
-        for (curr_rec = 0;
-             curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]);
-             curr_rec++) ;
-        if (curr_rec == num_recs) {
-            RECORD_LAYER_set_numrpipes(&s->rlayer, 0);
-            num_recs = 0;
-            curr_rec = 0;
-        }
-    } while (num_recs == 0);
-    rr = &rr[curr_rec];
+            rr->off = 0;
+            s->rlayer.num_recs++;
+        } while (s->rrlmethod->processed_read_pending(s->rrl)
+                 && s->rlayer.num_recs < SSL_MAX_PIPELINES);
+    }
+    rr = &s->rlayer.tlsrecs[s->rlayer.curr_rec];
 
     if (s->rlayer.handshake_fragment_len > 0
             && SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE
@@ -1249,15 +1301,14 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
      * Reset the count of consecutive warning alerts if we've got a non-empty
      * record that isn't an alert.
      */
-    if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
-            && SSL3_RECORD_get_length(rr) != 0)
+    if (rr->type != SSL3_RT_ALERT && rr->length != 0)
         s->rlayer.alert_count = 0;
 
     /* we now have a packet which can be read and processed */
 
     if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec,
                                   * reset by ssl3_get_finished */
-        && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
+        && (rr->type != SSL3_RT_HANDSHAKE)) {
         SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
                  SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
         return -1;
@@ -1268,13 +1319,13 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
      * 'peek' mode)
      */
     if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
-        SSL3_RECORD_set_length(rr, 0);
+        s->rlayer.curr_rec++;
         s->rwstate = SSL_NOTHING;
         return 0;
     }
 
-    if (type == SSL3_RECORD_get_type(rr)
-        || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+    if (type == rr->type
+        || (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC
             && type == SSL3_RT_HANDSHAKE && recvd_type != NULL
             && !is_tls13)) {
         /*
@@ -1293,30 +1344,33 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
         }
 
         if (type == SSL3_RT_HANDSHAKE
-            && SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+            && rr->type == SSL3_RT_CHANGE_CIPHER_SPEC
             && s->rlayer.handshake_fragment_len > 0) {
             SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_CCS_RECEIVED_EARLY);
             return -1;
         }
 
         if (recvd_type != NULL)
-            *recvd_type = SSL3_RECORD_get_type(rr);
+            *recvd_type = rr->type;
 
         if (len == 0) {
             /*
-             * Mark a zero length record as read. This ensures multiple calls to
+             * Skip a zero length record. This ensures multiple calls to
              * SSL_read() with a zero length buffer will eventually cause
              * SSL_pending() to report data as being available.
              */
-            if (SSL3_RECORD_get_length(rr) == 0)
-                SSL3_RECORD_set_read(rr);
+            if (rr->length == 0) {
+                s->rrlmethod->release_record(s->rrl, rr->rechandle);
+                s->rlayer.curr_rec++;
+            }
             return 0;
         }
 
         totalbytes = 0;
+        curr_rec = s->rlayer.curr_rec;
         do {
-            if (len - totalbytes > SSL3_RECORD_get_length(rr))
-                n = SSL3_RECORD_get_length(rr);
+            if (len - totalbytes > rr->length)
+                n = rr->length;
             else
                 n = len - totalbytes;
 
@@ -1324,35 +1378,44 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
             buf += n;
             if (peek) {
                 /* Mark any zero length record as consumed CVE-2016-6305 */
-                if (SSL3_RECORD_get_length(rr) == 0)
-                    SSL3_RECORD_set_read(rr);
+                if (rr->length == 0) {
+                    s->rrlmethod->release_record(s->rrl, rr->rechandle);
+                    s->rlayer.curr_rec++;
+                }
             } else {
                 if (s->options & SSL_OP_CLEANSE_PLAINTEXT)
                     OPENSSL_cleanse(&(rr->data[rr->off]), n);
-                SSL3_RECORD_sub_length(rr, n);
-                SSL3_RECORD_add_off(rr, n);
-                if (SSL3_RECORD_get_length(rr) == 0) {
+                rr->length -= n;
+                rr->off += n;
+                if (rr->length == 0) {
+                    /* TODO(RECLAYER): What to do with this? Is it needed? */
+                    #if 0
                     s->rlayer.rstate = SSL_ST_READ_HEADER;
-                    SSL3_RECORD_set_off(rr, 0);
-                    SSL3_RECORD_set_read(rr);
+                    #endif
+                    s->rrlmethod->release_record(s->rrl, rr->rechandle);
+                    s->rlayer.curr_rec++;
                 }
             }
-            if (SSL3_RECORD_get_length(rr) == 0
-                || (peek && n == SSL3_RECORD_get_length(rr))) {
-                curr_rec++;
+            if (rr->length == 0
+                || (peek && n == rr->length)) {
                 rr++;
+                curr_rec++;
             }
             totalbytes += n;
-        } while (type == SSL3_RT_APPLICATION_DATA && curr_rec < num_recs
-                 && totalbytes < len);
+        } while (type == SSL3_RT_APPLICATION_DATA
+                    && curr_rec < s->rlayer.num_recs
+                    && totalbytes < len);
         if (totalbytes == 0) {
             /* We must have read empty records. Get more data */
             goto start;
         }
-        if (!peek && curr_rec == num_recs
+        /* TODO(RECLAYER): FIX ME */
+#if 0
+        if (!peek && curr_rec == s->rlayer.num_recs
             && (s->mode & SSL_MODE_RELEASE_BUFFERS)
             && SSL3_BUFFER_get_left(rbuf) == 0)
             ssl3_release_read_buffer(s);
+#endif
         *readbytes = totalbytes;
         return 1;
     }
@@ -1366,7 +1429,7 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
     /*
      * Lets just double check that we've not got an SSLv2 record
      */
-    if (rr->rec_version == SSL2_VERSION) {
+    if (rr->version == SSL2_VERSION) {
         /*
          * Should never happen. ssl3_get_record() should only give us an SSLv2
          * record back if this is the first packet and we are looking for an
@@ -1385,7 +1448,7 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
          * with. We shouldn't be receiving anything other than a ClientHello
          * if we are a server.
          */
-        s->version = rr->rec_version;
+        s->version = rr->version;
         SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
         return -1;
     }
@@ -1395,13 +1458,13 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
      * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
      */
 
-    if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
+    if (rr->type == SSL3_RT_ALERT) {
         unsigned int alert_level, alert_descr;
-        unsigned char *alert_bytes = SSL3_RECORD_get_data(rr)
-                                     + SSL3_RECORD_get_off(rr);
+        unsigned char *alert_bytes = rr->data
+                                     + rr->off;
         PACKET alert;
 
-        if (!PACKET_buf_init(&alert, alert_bytes, SSL3_RECORD_get_length(rr))
+        if (!PACKET_buf_init(&alert, alert_bytes, rr->length)
                 || !PACKET_get_1(&alert, &alert_level)
                 || !PACKET_get_1(&alert, &alert_descr)
                 || PACKET_remaining(&alert) != 0) {
@@ -1423,10 +1486,11 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
             cb(ssl, SSL_CB_READ_ALERT, j);
         }
 
-        if (alert_level == SSL3_AL_WARNING
+        if ((!is_tls13 && alert_level == SSL3_AL_WARNING)
                 || (is_tls13 && alert_descr == SSL_AD_USER_CANCELLED)) {
             s->s3.warn_alert = alert_descr;
-            SSL3_RECORD_set_read(rr);
+            s->rrlmethod->release_record(s->rrl, rr->rechandle);
+            s->rlayer.curr_rec++;
 
             s->rlayer.alert_count++;
             if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
@@ -1453,7 +1517,8 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
                           SSL_AD_REASON_OFFSET + alert_descr,
                           "SSL alert number %d", alert_descr);
             s->shutdown |= SSL_RECEIVED_SHUTDOWN;
-            SSL3_RECORD_set_read(rr);
+            s->rrlmethod->release_record(s->rrl, rr->rechandle);
+            s->rlayer.curr_rec++;
             SSL_CTX_remove_session(s->session_ctx, s->session);
             return 0;
         } else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
@@ -1477,7 +1542,7 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
     }
 
     if ((s->shutdown & SSL_SENT_SHUTDOWN) != 0) {
-        if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
+        if (rr->type == SSL3_RT_HANDSHAKE) {
             BIO *rbio;
 
             /*
@@ -1488,8 +1553,8 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
              * sent close_notify.
              */
             if (!SSL_CONNECTION_IS_TLS13(s)) {
-                SSL3_RECORD_set_length(rr, 0);
-                SSL3_RECORD_set_read(rr);
+                s->rrlmethod->release_record(s->rrl, rr->rechandle);
+                s->rlayer.curr_rec++;
 
                 if ((s->mode & SSL_MODE_AUTO_RETRY) != 0)
                     goto start;
@@ -1508,8 +1573,8 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
              * above.
              * No alert sent because we already sent close_notify
              */
-            SSL3_RECORD_set_length(rr, 0);
-            SSL3_RECORD_set_read(rr);
+            s->rrlmethod->release_record(s->rrl, rr->rechandle);
+            s->rlayer.curr_rec++;
             SSLfatal(s, SSL_AD_NO_ALERT,
                      SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY);
             return -1;
@@ -1522,29 +1587,30 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
      * "SHUTDOWN" code above to avoid filling the fragment storage with data
      * that we're just going to discard.
      */
-    if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
+    if (rr->type == SSL3_RT_HANDSHAKE) {
         size_t dest_maxlen = sizeof(s->rlayer.handshake_fragment);
         unsigned char *dest = s->rlayer.handshake_fragment;
         size_t *dest_len = &s->rlayer.handshake_fragment_len;
 
         n = dest_maxlen - *dest_len; /* available space in 'dest' */
-        if (SSL3_RECORD_get_length(rr) < n)
-            n = SSL3_RECORD_get_length(rr); /* available bytes */
+        if (rr->length < n)
+            n = rr->length; /* available bytes */
 
         /* now move 'n' bytes: */
-        memcpy(dest + *dest_len,
-               SSL3_RECORD_get_data(rr) + SSL3_RECORD_get_off(rr), n);
-        SSL3_RECORD_add_off(rr, n);
-        SSL3_RECORD_sub_length(rr, n);
+        memcpy(dest + *dest_len, rr->data + rr->off, n);
+        rr->off += n;
+        rr->length -= n;
         *dest_len += n;
-        if (SSL3_RECORD_get_length(rr) == 0)
-            SSL3_RECORD_set_read(rr);
+        if (rr->length == 0) {
+            s->rrlmethod->release_record(s->rrl, rr->rechandle);
+            s->rlayer.curr_rec++;
+        }
 
         if (*dest_len < dest_maxlen)
             goto start;     /* fragment was too small */
     }
 
-    if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
+    if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
         SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_CCS_RECEIVED_EARLY);
         return -1;
     }
@@ -1577,8 +1643,7 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
             return -1;
 
         if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
-            if (SSL3_BUFFER_get_left(rbuf) == 0) {
-                /* no read-ahead left? */
+            if (!RECORD_LAYER_read_pending(&s->rlayer)) {
                 BIO *bio;
                 /*
                  * In the case where we try to read application data, but we
@@ -1596,7 +1661,7 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
         goto start;
     }
 
-    switch (SSL3_RECORD_get_type(rr)) {
+    switch (rr->type) {
     default:
         /*
          * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but
@@ -1643,7 +1708,8 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
                 /* SSLfatal() already called */
                 return -1;
             }
-            SSL3_RECORD_set_read(rr);
+            s->rrlmethod->release_record(s->rrl, rr->rechandle);
+            s->rlayer.curr_rec++;
             goto start;
         } else {
             SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD);
@@ -1669,7 +1735,9 @@ void ssl3_record_sequence_update(unsigned char *seq)
  */
 int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl)
 {
-    return SSL3_RECORD_is_sslv2_record(&rl->rrec[0]);
+    if (SSL_CONNECTION_IS_DTLS(rl->s))
+        return 0;
+    return rl->tlsrecs[0].version == SSL2_VERSION;
 }
 
 /*
index 0027a7dba295ebc6166e1006001fcacecba7111b..84c2a55582dff1d55bc1eadfbed92c49222d4823 100644 (file)
@@ -72,6 +72,18 @@ typedef struct ssl3_record_st {
     unsigned char seq_num[SEQ_NUM_SIZE];
 } SSL3_RECORD;
 
+typedef struct tls_record_st {
+    void *rechandle;
+    int version;
+    int type;
+    /* The data buffer containing bytes from the record */
+    unsigned char *data;
+    /* Number of remaining to be read in the data buffer */
+    size_t length;
+    /* Offset into the data buffer where to start reading */
+    size_t off;
+} TLS_RECORD;
+
 typedef struct dtls1_bitmap_st {
     /* Track 32 packets on 32-bit systems and 64 - on 64-bit systems */
     unsigned long map;
@@ -171,6 +183,16 @@ typedef struct record_layer_st {
     /* Count of the number of consecutive warning alerts received */
     unsigned int alert_count;
     DTLS_RECORD_LAYER *d;
+
+    /* TODO(RECLAYER): Tidy me up. New fields for record management */
+
+    /* How many records we have read from the record layer */
+    size_t num_recs;
+    /* The next record from the record layer that we need to process */
+    size_t curr_rec;
+    /* Record layer data to be processed */
+    TLS_RECORD tlsrecs[SSL_MAX_PIPELINES];
+
 } RECORD_LAYER;
 
 /*****************************************************************************
@@ -250,3 +272,10 @@ int do_dtls1_write(SSL_CONNECTION *s, int type, const unsigned char *buf,
 void dtls1_reset_seq_numbers(SSL_CONNECTION *s, int rw);
 int dtls_buffer_listen_record(SSL_CONNECTION *s, size_t len, unsigned char *seq,
                               size_t off);
+
+
+# define HANDLE_RLAYER_RETURN(s, ret) \
+    ossl_tls_handle_rlayer_return(s, ret, OPENSSL_FILE, OPENSSL_LINE)
+
+int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int ret, char *file,
+                                  int line);
index 7d92c973ec4549f60f48c7fc1adaefdcbda8cfd1..397cba617d518ab8370d6135e57f763520dbc386 100644 (file)
@@ -103,7 +103,6 @@ int ssl3_release_write_buffer(SSL_CONNECTION *s);
 void SSL3_RECORD_clear(SSL3_RECORD *r, size_t);
 void SSL3_RECORD_release(SSL3_RECORD *r, size_t num_recs);
 void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num);
-int ssl3_get_record(SSL_CONNECTION *s);
 __owur int ssl3_do_compress(SSL_CONNECTION *ssl, SSL3_RECORD *wr);
 __owur int ssl3_do_uncompress(SSL_CONNECTION *ssl, SSL3_RECORD *rr);
 __owur int ssl3_cbc_remove_padding_and_mac(size_t *reclen,
index da5739f8e7414e488e257fcdf0545473f779ccf8..5a54dba550eb8a670e1543b5d523a1296dcd6c0d 100644 (file)
@@ -235,13 +235,14 @@ struct ossl_record_method_st {
      */
     int (*read_record)(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion,
                       int *type, unsigned char **data, size_t *datalen,
-                      uint16_t *epoch, unsigned char *seq_num);
+                      uint16_t *epoch, unsigned char *seq_num,
+                      /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s);
     /*
      * Release a buffer associated with a record previously read with
      * read_record. Records are guaranteed to be released in the order that they
      * are read.
      */
-    void (*release_record)(OSSL_RECORD_LAYER *rl, void *rechandle);
+    int (*release_record)(OSSL_RECORD_LAYER *rl, void *rechandle);
 
     /*
      * In the event that a fatal error is returned from the functions above then
index 0225a85b90e206cc2e0b40b51b10fa2e4e293ec1..b7ec2144eb5a07f70d32532360da42b24cf20609 100644 (file)
@@ -63,45 +63,6 @@ void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num)
     memcpy(r->seq_num, seq_num, SEQ_NUM_SIZE);
 }
 
-/*
- * Peeks ahead into "read_ahead" data to see if we have a whole record waiting
- * for us in the buffer.
- */
-static int ssl3_record_app_data_waiting(SSL_CONNECTION *s)
-{
-    SSL3_BUFFER *rbuf;
-    size_t left, len;
-    unsigned char *p;
-
-    rbuf = s->rrlmethod->get0_rbuf(s->rrl);
-
-    p = SSL3_BUFFER_get_buf(rbuf);
-    if (p == NULL)
-        return 0;
-
-    left = SSL3_BUFFER_get_left(rbuf);
-
-    if (left < SSL3_RT_HEADER_LENGTH)
-        return 0;
-
-    p += SSL3_BUFFER_get_offset(rbuf);
-
-    /*
-     * We only check the type and record length, we will sanity check version
-     * etc later
-     */
-    if (*p != SSL3_RT_APPLICATION_DATA)
-        return 0;
-
-    p += 3;
-    n2s(p, len);
-
-    if (left < SSL3_RT_HEADER_LENGTH + len)
-        return 0;
-
-    return 1;
-}
-
 int ossl_early_data_count_ok(SSL_CONNECTION *s, size_t length,
                              size_t overhead, int send)
 {
@@ -149,710 +110,6 @@ int ossl_early_data_count_ok(SSL_CONNECTION *s, size_t length,
     return 1;
 }
 
-static int tls_handle_rlayer_return(SSL_CONNECTION *s, int ret, char *file,
-                                    int line)
-{
-    SSL *ssl = SSL_CONNECTION_GET_SSL(s);
-
-    if (ret == OSSL_RECORD_RETURN_RETRY) {
-        s->rwstate = SSL_READING;
-        ret = -1;
-    } else {
-        s->rwstate = SSL_NOTHING;
-        if (ret == OSSL_RECORD_RETURN_EOF) {
-            if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) {
-                SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
-                s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY;
-            } else {
-                ERR_new();
-                ERR_set_debug(file, line, 0);
-                ossl_statem_fatal(s, SSL_AD_DECODE_ERROR,
-                                  SSL_R_UNEXPECTED_EOF_WHILE_READING, NULL);
-            }
-        } else if (ret == OSSL_RECORD_RETURN_FATAL) {
-            ERR_new();
-            ERR_set_debug(file, line, 0);
-            ossl_statem_fatal(s, s->rrlmethod->get_alert_code(s->rrl),
-                              SSL_R_RECORD_LAYER_FAILURE, NULL);
-        }
-        /*
-         * The record layer distinguishes the cases of EOF, non-fatal
-         * err and retry. Upper layers do not.
-         * If we got a retry or success then *ret is already correct,
-         * otherwise we need to convert the return value.
-         */
-        /*
-         * TODO(RECLAYER): What does a non fatal err that isn't a retry even
-         * mean???
-         */
-        if (ret == OSSL_RECORD_RETURN_NON_FATAL_ERR || ret == OSSL_RECORD_RETURN_EOF)
-            ret = 0;
-        else if (ret < OSSL_RECORD_RETURN_NON_FATAL_ERR)
-            ret = -1;
-    }
-
-    return ret;
-}
-
-# define HANDLE_RLAYER_RETURN(s, ret) \
-    tls_handle_rlayer_return(s, ret, OPENSSL_FILE, OPENSSL_LINE)
-
-/*
- * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that
- * will be processed per call to ssl3_get_record. Without this limit an
- * attacker could send empty records at a faster rate than we can process and
- * cause ssl3_get_record to loop forever.
- */
-#define MAX_EMPTY_RECORDS 32
-
-#define SSL2_RT_HEADER_LENGTH   2
-/*-
- * Call this to get new input records.
- * It will return <= 0 if more data is needed, normally due to an error
- * or non-blocking IO.
- * When it finishes, |numrpipes| records have been decoded. For each record 'i':
- * rr[i].type    - is the type of record
- * rr[i].data,   - data
- * rr[i].length, - number of bytes
- * Multiple records will only be returned if the record types are all
- * SSL3_RT_APPLICATION_DATA. The number of records returned will always be <=
- * |max_pipelines|
- */
-/* used only by ssl3_read_bytes */
-int ssl3_get_record(SSL_CONNECTION *s)
-{
-    int enc_err, rret;
-    int i;
-    size_t more, n;
-    SSL3_RECORD *rr, *thisrr;
-    SSL3_BUFFER *rbuf;
-    SSL_SESSION *sess;
-    unsigned char *p;
-    unsigned char md[EVP_MAX_MD_SIZE];
-    unsigned int version;
-    size_t mac_size = 0;
-    int imac_size;
-    size_t num_recs = 0, max_recs, j;
-    PACKET pkt, sslv2pkt;
-    int using_ktls;
-    SSL_MAC_BUF *macbufs = NULL;
-    int ret = -1;
-    SSL *ssl = SSL_CONNECTION_GET_SSL(s);
-
-    rr = RECORD_LAYER_get_rrec(&s->rlayer);
-    rbuf = s->rrlmethod->get0_rbuf(s->rrl);
-
-    max_recs = s->max_pipelines;
-    if (max_recs == 0)
-        max_recs = 1;
-    sess = s->session;
-
-    /*
-     * KTLS reads full records. If there is any data left,
-     * then it is from before enabling ktls.
-     */
-    using_ktls = BIO_get_ktls_recv(s->rbio) && SSL3_BUFFER_get_left(rbuf) == 0;
-
-    do {
-        thisrr = &rr[num_recs];
-
-        /* check if we have the header */
-        if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
-            (s->rrlmethod->get_packet_length(s->rrl) < SSL3_RT_HEADER_LENGTH)) {
-            size_t sslv2len;
-            unsigned int type;
-
-            rret = HANDLE_RLAYER_RETURN(s,
-                s->rrlmethod->read_n(s->rrl, SSL3_RT_HEADER_LENGTH,
-                                     SSL3_BUFFER_get_len(rbuf), 0,
-                                     num_recs == 0 ? 1 : 0, &n));
-
-            if (rret <= 0) {
-#ifndef OPENSSL_NO_KTLS
-                if (!using_ktls || rret == 0)
-                    return rret;     /* error or non-blocking */
-                switch (errno) {
-                case EBADMSG:
-                    SSLfatal(s, SSL_AD_BAD_RECORD_MAC,
-                             SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
-                    break;
-                case EMSGSIZE:
-                    SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
-                             SSL_R_PACKET_LENGTH_TOO_LONG);
-                    break;
-                case EINVAL:
-                    SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
-                             SSL_R_WRONG_VERSION_NUMBER);
-                    break;
-                default:
-                    break;
-                }
-#endif
-                return rret;
-            }
-            RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
-
-            p = s->rrlmethod->get0_packet(s->rrl);
-            if (!PACKET_buf_init(&pkt, p,
-                                 s->rrlmethod->get_packet_length(s->rrl))) {
-                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-                return -1;
-            }
-            sslv2pkt = pkt;
-            if (!PACKET_get_net_2_len(&sslv2pkt, &sslv2len)
-                    || !PACKET_get_1(&sslv2pkt, &type)) {
-                SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR);
-                return -1;
-            }
-            /*
-             * The first record received by the server may be a V2ClientHello.
-             */
-            if (s->server && RECORD_LAYER_is_first_record(&s->rlayer)
-                    && (sslv2len & 0x8000) != 0
-                    && (type == SSL2_MT_CLIENT_HELLO)) {
-                /*
-                 *  SSLv2 style record
-                 *
-                 * |num_recs| here will actually always be 0 because
-                 * |num_recs > 0| only ever occurs when we are processing
-                 * multiple app data records - which we know isn't the case here
-                 * because it is an SSLv2ClientHello. We keep it using
-                 * |num_recs| for the sake of consistency
-                 */
-                thisrr->type = SSL3_RT_HANDSHAKE;
-                thisrr->rec_version = SSL2_VERSION;
-
-                thisrr->length = sslv2len & 0x7fff;
-
-                if (thisrr->length > SSL3_BUFFER_get_len(rbuf)
-                    - SSL2_RT_HEADER_LENGTH) {
-                    SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
-                             SSL_R_PACKET_LENGTH_TOO_LONG);
-                    return -1;
-                }
-
-                if (thisrr->length < MIN_SSL2_RECORD_LEN) {
-                    SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
-                    return -1;
-                }
-            } else {
-                /* SSLv3+ style record */
-
-                /* Pull apart the header into the SSL3_RECORD */
-                if (!PACKET_get_1(&pkt, &type)
-                        || !PACKET_get_net_2(&pkt, &version)
-                        || !PACKET_get_net_2_len(&pkt, &thisrr->length)) {
-                    if (s->msg_callback)
-                        s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, ssl,
-                                        s->msg_callback_arg);
-                    SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR);
-                    return -1;
-                }
-                thisrr->type = type;
-                thisrr->rec_version = version;
-
-                if (s->msg_callback)
-                    s->msg_callback(0, version, SSL3_RT_HEADER, p, 5, ssl,
-                                    s->msg_callback_arg);
-
-                /*
-                 * Lets check version. In TLSv1.3 we only check this field
-                 * when encryption is occurring (see later check). For the
-                 * ServerHello after an HRR we haven't actually selected TLSv1.3
-                 * yet, but we still treat it as TLSv1.3, so we must check for
-                 * that explicitly
-                 */
-                if (!s->first_packet && !SSL_CONNECTION_IS_TLS13(s)
-                        && s->hello_retry_request != SSL_HRR_PENDING
-                        && version != (unsigned int)s->version) {
-                    if ((s->version & 0xFF00) == (version & 0xFF00)
-                        && !s->enc_write_ctx && !s->write_hash) {
-                        if (thisrr->type == SSL3_RT_ALERT) {
-                            /*
-                             * The record is using an incorrect version number,
-                             * but what we've got appears to be an alert. We
-                             * haven't read the body yet to check whether its a
-                             * fatal or not - but chances are it is. We probably
-                             * shouldn't send a fatal alert back. We'll just
-                             * end.
-                             */
-                            SSLfatal(s, SSL_AD_NO_ALERT,
-                                     SSL_R_WRONG_VERSION_NUMBER);
-                            return -1;
-                        }
-                        /*
-                         * Send back error using their minor version number :-)
-                         */
-                        s->version = (unsigned short)version;
-                    }
-                    SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
-                             SSL_R_WRONG_VERSION_NUMBER);
-                    return -1;
-                }
-
-                if ((version >> 8) != SSL3_VERSION_MAJOR) {
-                    if (RECORD_LAYER_is_first_record(&s->rlayer)) {
-                        /* Go back to start of packet, look at the five bytes
-                         * that we have. */
-                        p = s->rrlmethod->get0_packet(s->rrl);
-                        if (HAS_PREFIX((char *)p, "GET ") ||
-                            HAS_PREFIX((char *)p, "POST ") ||
-                            HAS_PREFIX((char *)p, "HEAD ") ||
-                            HAS_PREFIX((char *)p, "PUT ")) {
-                            SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST);
-                            return -1;
-                        } else if (HAS_PREFIX((char *)p, "CONNE")) {
-                            SSLfatal(s, SSL_AD_NO_ALERT,
-                                     SSL_R_HTTPS_PROXY_REQUEST);
-                            return -1;
-                        }
-
-                        /* Doesn't look like TLS - don't send an alert */
-                        SSLfatal(s, SSL_AD_NO_ALERT,
-                                 SSL_R_WRONG_VERSION_NUMBER);
-                        return -1;
-                    } else {
-                        SSLfatal(s, SSL_AD_PROTOCOL_VERSION,
-                                 SSL_R_WRONG_VERSION_NUMBER);
-                        return -1;
-                    }
-                }
-
-                if (SSL_CONNECTION_IS_TLS13(s)
-                        && s->enc_read_ctx != NULL
-                        && !using_ktls) {
-                    if (thisrr->type != SSL3_RT_APPLICATION_DATA
-                            && (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
-                                || !SSL_IS_FIRST_HANDSHAKE(s))
-                            && (thisrr->type != SSL3_RT_ALERT
-                                || s->statem.enc_read_state
-                                   != ENC_READ_STATE_ALLOW_PLAIN_ALERTS)) {
-                        SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
-                                 SSL_R_BAD_RECORD_TYPE);
-                        return -1;
-                    }
-                    if (thisrr->rec_version != TLS1_2_VERSION) {
-                        SSLfatal(s, SSL_AD_DECODE_ERROR,
-                                 SSL_R_WRONG_VERSION_NUMBER);
-                        return -1;
-                    }
-                }
-
-                if (thisrr->length >
-                    SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
-                    SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
-                             SSL_R_PACKET_LENGTH_TOO_LONG);
-                    return -1;
-                }
-            }
-
-            /* now s->rlayer.rstate == SSL_ST_READ_BODY */
-        }
-
-        if (SSL_CONNECTION_IS_TLS13(s)) {
-            size_t len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH;
-
-            /* KTLS strips the inner record type. */
-            if (using_ktls)
-                len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
-
-            if (thisrr->length > len) {
-                SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
-                         SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
-                return -1;
-            }
-        } else {
-            size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
-
-#ifndef OPENSSL_NO_COMP
-            /*
-             * If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH
-             * does not include the compression overhead anyway.
-             */
-            if (s->expand == NULL)
-                len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
-#endif
-
-            /* KTLS may use all of the buffer */
-            if (using_ktls)
-                len = SSL3_BUFFER_get_left(rbuf);
-
-            if (thisrr->length > len) {
-                SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
-                         SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
-                return -1;
-            }
-        }
-
-        /*
-         * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
-         * Calculate how much more data we need to read for the rest of the
-         * record
-         */
-        if (thisrr->rec_version == SSL2_VERSION) {
-            more = thisrr->length + SSL2_RT_HEADER_LENGTH
-                - SSL3_RT_HEADER_LENGTH;
-        } else {
-            more = thisrr->length;
-        }
-
-        if (more > 0) {
-            /* now s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH */
-
-            rret = HANDLE_RLAYER_RETURN(s,
-                s->rrlmethod->read_n(s->rrl, more, more, 1, 0, &n));
-            if (rret <= 0)
-                return rret;     /* error or non-blocking io */
-        }
-
-        /* set state for later operations */
-        RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
-
-        /*
-         * At this point, s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH
-         * + thisrr->length, or s->rlayer.packet_length == SSL2_RT_HEADER_LENGTH
-         * + thisrr->length and we have that many bytes in s->rlayer.packet
-         */
-        if (thisrr->rec_version == SSL2_VERSION) {
-            thisrr->input =
-                &(s->rrlmethod->get0_packet(s->rrl)[SSL2_RT_HEADER_LENGTH]);
-        } else {
-            thisrr->input =
-                &(s->rrlmethod->get0_packet(s->rrl)[SSL3_RT_HEADER_LENGTH]);
-        }
-
-        /*
-         * ok, we can now read from 's->rlayer.packet' data into 'thisrr'.
-         * thisrr->input points at thisrr->length bytes, which need to be copied
-         * into thisrr->data by either the decryption or by the decompression.
-         * When the data is 'copied' into the thisrr->data buffer,
-         * thisrr->input will be updated to point at the new buffer
-         */
-
-        /*
-         * We now have - encrypted [ MAC [ compressed [ plain ] ] ]
-         * thisrr->length bytes of encrypted compressed stuff.
-         */
-
-        /* decrypt in place in 'thisrr->input' */
-        thisrr->data = thisrr->input;
-        thisrr->orig_len = thisrr->length;
-
-        /* Mark this record as not read by upper layers yet */
-        thisrr->read = 0;
-
-        num_recs++;
-
-        /* we have pulled in a full packet so zero things */
-        s->rrlmethod->reset_packet_length(s->rrl);
-        RECORD_LAYER_clear_first_record(&s->rlayer);
-    } while (num_recs < max_recs
-             && thisrr->type == SSL3_RT_APPLICATION_DATA
-             && SSL_USE_EXPLICIT_IV(s)
-             && s->enc_read_ctx != NULL
-             && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx))
-                 & EVP_CIPH_FLAG_PIPELINE) != 0
-             && ssl3_record_app_data_waiting(s));
-
-    if (num_recs == 1
-            && thisrr->type == SSL3_RT_CHANGE_CIPHER_SPEC
-            && (SSL_CONNECTION_IS_TLS13(s)
-                || s->hello_retry_request != SSL_HRR_NONE)
-            && SSL_IS_FIRST_HANDSHAKE(s)) {
-        /*
-         * CCS messages must be exactly 1 byte long, containing the value 0x01
-         */
-        if (thisrr->length != 1 || thisrr->data[0] != 0x01) {
-            SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
-                     SSL_R_INVALID_CCS_MESSAGE);
-            return -1;
-        }
-        /*
-         * CCS messages are ignored in TLSv1.3. We treat it like an empty
-         * handshake record
-         */
-        thisrr->type = SSL3_RT_HANDSHAKE;
-        RECORD_LAYER_inc_empty_record_count(&s->rlayer);
-        if (RECORD_LAYER_get_empty_record_count(&s->rlayer)
-            > MAX_EMPTY_RECORDS) {
-            SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
-                     SSL_R_UNEXPECTED_CCS_MESSAGE);
-            return -1;
-        }
-        thisrr->read = 1;
-        RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
-
-        return 1;
-    }
-
-    if (using_ktls)
-        goto skip_decryption;
-
-    if (s->read_hash != NULL) {
-        const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(s->read_hash);
-
-        if (tmpmd != NULL) {
-            imac_size = EVP_MD_get_size(tmpmd);
-            if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) {
-                    SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
-                    return -1;
-            }
-            mac_size = (size_t)imac_size;
-        }
-    }
-
-    /*
-     * If in encrypt-then-mac mode calculate mac from encrypted record. All
-     * the details below are public so no timing details can leak.
-     */
-    if (SSL_READ_ETM(s) && s->read_hash) {
-        unsigned char *mac;
-
-        for (j = 0; j < num_recs; j++) {
-            thisrr = &rr[j];
-
-            if (thisrr->length < mac_size) {
-                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
-                return -1;
-            }
-            thisrr->length -= mac_size;
-            mac = thisrr->data + thisrr->length;
-            i = ssl->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ );
-            if (i == 0 || CRYPTO_memcmp(md, mac, mac_size) != 0) {
-                SSLfatal(s, SSL_AD_BAD_RECORD_MAC,
-                         SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
-                return -1;
-            }
-        }
-        /*
-         * We've handled the mac now - there is no MAC inside the encrypted
-         * record
-         */
-        mac_size = 0;
-    }
-
-    if (mac_size > 0) {
-        macbufs = OPENSSL_zalloc(sizeof(*macbufs) * num_recs);
-        if (macbufs == NULL) {
-            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
-            return -1;
-        }
-    }
-
-    enc_err = ssl->method->ssl3_enc->enc(s, rr, num_recs, 0, macbufs, mac_size);
-
-    /*-
-     * enc_err is:
-     *    0: if the record is publicly invalid, or an internal error, or AEAD
-     *       decryption failed, or ETM decryption failed.
-     *    1: Success or MTE decryption failed (MAC will be randomised)
-     */
-    if (enc_err == 0) {
-        if (ossl_statem_in_error(s)) {
-            /* SSLfatal() already got called */
-            goto end;
-        }
-        if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
-            /*
-             * Valid early_data that we cannot decrypt will fail here. We treat
-             * it like an empty record.
-             */
-
-            thisrr = &rr[0];
-
-            if (!ossl_early_data_count_ok(s, thisrr->length,
-                                          EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) {
-                /* SSLfatal() already called */
-                goto end;
-            }
-
-            thisrr->length = 0;
-            thisrr->read = 1;
-            RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
-            RECORD_LAYER_reset_read_sequence(&s->rlayer);
-            ret = 1;
-            goto end;
-        }
-        SSLfatal(s, SSL_AD_BAD_RECORD_MAC,
-                 SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
-        goto end;
-    }
-    OSSL_TRACE_BEGIN(TLS) {
-        BIO_printf(trc_out, "dec %lu\n", (unsigned long)rr[0].length);
-        BIO_dump_indent(trc_out, rr[0].data, rr[0].length, 4);
-    } OSSL_TRACE_END(TLS);
-
-    /* r->length is now the compressed data plus mac */
-    if ((sess != NULL)
-            && (s->enc_read_ctx != NULL)
-            && (!SSL_READ_ETM(s) && EVP_MD_CTX_get0_md(s->read_hash) != NULL)) {
-        /* s->read_hash != NULL => mac_size != -1 */
-
-        for (j = 0; j < num_recs; j++) {
-            SSL_MAC_BUF *thismb = &macbufs[j];
-            thisrr = &rr[j];
-
-            i = ssl->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ );
-            if (i == 0 || thismb == NULL || thismb->mac == NULL
-                || CRYPTO_memcmp(md, thismb->mac, (size_t)mac_size) != 0)
-                enc_err = 0;
-            if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
-                enc_err = 0;
-        }
-    }
-
-    if (enc_err == 0) {
-        if (ossl_statem_in_error(s)) {
-            /* We already called SSLfatal() */
-            goto end;
-        }
-        /*
-         * A separate 'decryption_failed' alert was introduced with TLS 1.0,
-         * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
-         * failure is directly visible from the ciphertext anyway, we should
-         * not reveal which kind of error occurred -- this might become
-         * visible to an attacker (e.g. via a logfile)
-         */
-        SSLfatal(s, SSL_AD_BAD_RECORD_MAC,
-                 SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
-        goto end;
-    }
-
- skip_decryption:
-
-    for (j = 0; j < num_recs; j++) {
-        thisrr = &rr[j];
-
-        /* thisrr->length is now just compressed */
-        if (s->expand != NULL) {
-            if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
-                SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
-                         SSL_R_COMPRESSED_LENGTH_TOO_LONG);
-                goto end;
-            }
-            if (!ssl3_do_uncompress(s, thisrr)) {
-                SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE,
-                         SSL_R_BAD_DECOMPRESSION);
-                goto end;
-            }
-        }
-
-        if (SSL_CONNECTION_IS_TLS13(s)
-                && s->enc_read_ctx != NULL
-                && thisrr->type != SSL3_RT_ALERT) {
-            /*
-             * The following logic are irrelevant in KTLS: the kernel provides
-             * unprotected record and thus record type represent the actual
-             * content type, and padding is already removed and thisrr->type and
-             * thisrr->length should have the correct values.
-             */
-            if (!using_ktls) {
-                size_t end;
-
-                if (thisrr->length == 0
-                        || thisrr->type != SSL3_RT_APPLICATION_DATA) {
-                    SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
-                    goto end;
-                }
-
-                /* Strip trailing padding */
-                for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0;
-                     end--)
-                    continue;
-
-                thisrr->length = end;
-                thisrr->type = thisrr->data[end];
-            }
-            if (thisrr->type != SSL3_RT_APPLICATION_DATA
-                    && thisrr->type != SSL3_RT_ALERT
-                    && thisrr->type != SSL3_RT_HANDSHAKE) {
-                SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
-                goto end;
-            }
-            if (s->msg_callback)
-                s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE,
-                                &thisrr->type, 1, ssl, s->msg_callback_arg);
-        }
-
-        /*
-         * TLSv1.3 alert and handshake records are required to be non-zero in
-         * length.
-         */
-        if (SSL_CONNECTION_IS_TLS13(s)
-                && (thisrr->type == SSL3_RT_HANDSHAKE
-                    || thisrr->type == SSL3_RT_ALERT)
-                && thisrr->length == 0) {
-            SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_LENGTH);
-            goto end;
-        }
-
-        /*
-         * Usually thisrr->length is the length of a single record, but when
-         * KTLS handles the decryption, thisrr->length may be larger than
-         * SSL3_RT_MAX_PLAIN_LENGTH because the kernel may have coalesced
-         * multiple records.
-         * Therefore we have to rely on KTLS to check the plaintext length
-         * limit in the kernel.
-         */
-        if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH && !using_ktls) {
-            SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
-            goto end;
-        }
-
-        /*
-         * Check if the received packet overflows the current
-         * Max Fragment Length setting.
-         * Note: USE_MAX_FRAGMENT_LENGTH_EXT and KTLS are mutually exclusive.
-         */
-        if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)
-                && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) {
-            SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
-            goto end;
-        }
-
-        thisrr->off = 0;
-        /*-
-         * So at this point the following is true
-         * thisrr->type   is the type of record
-         * thisrr->length == number of bytes in record
-         * thisrr->off    == offset to first valid byte
-         * thisrr->data   == where to take bytes from, increment after use :-).
-         */
-
-        /* just read a 0 length packet */
-        if (thisrr->length == 0) {
-            RECORD_LAYER_inc_empty_record_count(&s->rlayer);
-            if (RECORD_LAYER_get_empty_record_count(&s->rlayer)
-                > MAX_EMPTY_RECORDS) {
-                SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_RECORD_TOO_SMALL);
-                goto end;
-            }
-        } else {
-            RECORD_LAYER_reset_empty_record_count(&s->rlayer);
-        }
-    }
-
-    if (s->early_data_state == SSL_EARLY_DATA_READING) {
-        thisrr = &rr[0];
-        if (thisrr->type == SSL3_RT_APPLICATION_DATA
-                && !ossl_early_data_count_ok(s, thisrr->length, 0, 0)) {
-            /* SSLfatal already called */
-            goto end;
-        }
-    }
-
-    RECORD_LAYER_set_numrpipes(&s->rlayer, num_recs);
-    ret = 1;
- end:
-    if (macbufs != NULL) {
-        for (j = 0; j < num_recs; j++) {
-            if (macbufs[j].alloced)
-                OPENSSL_free(macbufs[j].mac);
-        }
-        OPENSSL_free(macbufs);
-    }
-    return ret;
-}
 
 int ssl3_do_uncompress(SSL_CONNECTION *sc, SSL3_RECORD *rr)
 {
index c262eefd19977a8ae6dfb0e790f257785ed21f64..7e0a1c9d4304627af1f57e0fc7c2c2460a94d6ea 100644 (file)
@@ -12,8 +12,9 @@
 #include <openssl/err.h>
 #include <openssl/core_names.h>
 #include "internal/e_os.h"
-#include "record.h"
-#include "recordmethod.h"
+#include "internal/packet.h"
+#include "../ssl_local.h"
+#include "record_local.h"
 
 struct ossl_record_layer_st
 {
@@ -32,6 +33,23 @@ struct ossl_record_layer_st
 
     /* read IO goes into here */
     SSL3_BUFFER rbuf;
+    /* each decoded record goes in here */
+    SSL3_RECORD rrec[SSL_MAX_PIPELINES];
+
+    /* How many records have we got available in the rrec bufer */
+    size_t num_recs;
+
+    /* The record number in the rrec buffer that can be read next */
+    size_t curr_rec;
+
+    /* The number of records that have been released via tls_release_record */
+    size_t num_released;
+
+    /* Set to true if this is the first record in a connection */
+    unsigned int is_first_record;
+
+    /* where we are when reading */
+    int rstate;
 
     /* used internally to point at a raw packet */
     unsigned char *packet;
@@ -136,6 +154,11 @@ static int rlayer_release_read_buffer(OSSL_RECORD_LAYER *rl)
     return 1;
 }
 
+static void tls_reset_packet_length(OSSL_RECORD_LAYER *rl)
+{
+    rl->packet_length = 0;
+}
+
 /*
  * Return values are as per SSL_read()
  */
@@ -311,6 +334,759 @@ static int tls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
     return OSSL_RECORD_RETURN_SUCCESS;
 }
 
+/*
+ * Peeks ahead into "read_ahead" data to see if we have a whole record waiting
+ * for us in the buffer.
+ */
+static int tls_record_app_data_waiting(OSSL_RECORD_LAYER *rl)
+{
+    SSL3_BUFFER *rbuf;
+    size_t left, len;
+    unsigned char *p;
+
+    rbuf = &rl->rbuf;
+
+    p = SSL3_BUFFER_get_buf(rbuf);
+    if (p == NULL)
+        return 0;
+
+    left = SSL3_BUFFER_get_left(rbuf);
+
+    if (left < SSL3_RT_HEADER_LENGTH)
+        return 0;
+
+    p += SSL3_BUFFER_get_offset(rbuf);
+
+    /*
+     * We only check the type and record length, we will sanity check version
+     * etc later
+     */
+    if (*p != SSL3_RT_APPLICATION_DATA)
+        return 0;
+
+    p += 3;
+    n2s(p, len);
+
+    if (left < SSL3_RT_HEADER_LENGTH + len)
+        return 0;
+
+    return 1;
+}
+
+/*
+ * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that
+ * will be processed per call to ssl3_get_record. Without this limit an
+ * attacker could send empty records at a faster rate than we can process and
+ * cause ssl3_get_record to loop forever.
+ */
+#define MAX_EMPTY_RECORDS 32
+
+#define SSL2_RT_HEADER_LENGTH   2
+
+/*-
+ * Call this to buffer new input records in rl->rrec.
+ * It will return a OSSL_RECORD_RETURN_* value.
+ * When it finishes successfully (OSSL_RECORD_RETURN_SUCCESS), |rl->num_recs|
+ * records have been decoded. For each record 'i':
+ * rrec[i].type    - is the type of record
+ * rrec[i].data,   - data
+ * rrec[i].length, - number of bytes
+ * Multiple records will only be returned if the record types are all
+ * SSL3_RT_APPLICATION_DATA. The number of records returned will always be <=
+ * |max_pipelines|
+ */
+static int tls_get_more_records(OSSL_RECORD_LAYER *rl, 
+                                /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
+{
+    int enc_err, rret;
+    int i;
+    size_t more, n;
+    SSL3_RECORD *rr, *thisrr;
+    SSL3_BUFFER *rbuf;
+    SSL_SESSION *sess;
+    unsigned char *p;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    unsigned int version;
+    size_t mac_size = 0;
+    int imac_size;
+    size_t num_recs = 0, max_recs, j;
+    PACKET pkt, sslv2pkt;
+    int using_ktls;
+    SSL_MAC_BUF *macbufs = NULL;
+    int ret = OSSL_RECORD_RETURN_FATAL;
+    SSL *ssl = SSL_CONNECTION_GET_SSL(s);
+
+    rr = rl->rrec;
+    rbuf = &rl->rbuf;
+
+    max_recs = s->max_pipelines;
+    if (max_recs == 0)
+        max_recs = 1;
+    sess = s->session;
+
+    /*
+     * KTLS reads full records. If there is any data left,
+     * then it is from before enabling ktls.
+     */
+    using_ktls = BIO_get_ktls_recv(rl->bio) && SSL3_BUFFER_get_left(rbuf) == 0;
+
+    do {
+        thisrr = &rr[num_recs];
+
+        /* check if we have the header */
+        if ((rl->rstate != SSL_ST_READ_BODY) ||
+            (rl->packet_length < SSL3_RT_HEADER_LENGTH)) {
+            size_t sslv2len;
+            unsigned int type;
+
+            rret = tls_read_n(rl, SSL3_RT_HEADER_LENGTH,
+                              SSL3_BUFFER_get_len(rbuf), 0,
+                              num_recs == 0 ? 1 : 0, &n);
+
+            if (rret < OSSL_RECORD_RETURN_SUCCESS) {
+#ifndef OPENSSL_NO_KTLS
+                if (!BIO_get_ktls_recv(rl->bio) || rret == 0)
+                    return rret;     /* error or non-blocking */
+                switch (errno) {
+                case EBADMSG:
+                    RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
+                                SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+                    break;
+                case EMSGSIZE:
+                    RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
+                                SSL_R_PACKET_LENGTH_TOO_LONG);
+                    break;
+                case EINVAL:
+                    RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
+                                SSL_R_WRONG_VERSION_NUMBER);
+                    break;
+                default:
+                    break;
+                }
+#endif
+                return rret;
+            }
+            rl->rstate = SSL_ST_READ_BODY;
+
+            p = rl->packet;
+            if (!PACKET_buf_init(&pkt, p, rl->packet_length)) {
+                RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+                return OSSL_RECORD_RETURN_FATAL;
+            }
+            sslv2pkt = pkt;
+            if (!PACKET_get_net_2_len(&sslv2pkt, &sslv2len)
+                    || !PACKET_get_1(&sslv2pkt, &type)) {
+                RLAYERfatal(rl, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR);
+                return OSSL_RECORD_RETURN_FATAL;
+            }
+            /*
+             * The first record received by the server may be a V2ClientHello.
+             */
+            if (rl->role == OSSL_RECORD_ROLE_SERVER
+                    && rl->is_first_record
+                    && (sslv2len & 0x8000) != 0
+                    && (type == SSL2_MT_CLIENT_HELLO)) {
+                /*
+                 *  SSLv2 style record
+                 *
+                 * |num_recs| here will actually always be 0 because
+                 * |num_recs > 0| only ever occurs when we are processing
+                 * multiple app data records - which we know isn't the case here
+                 * because it is an SSLv2ClientHello. We keep it using
+                 * |num_recs| for the sake of consistency
+                 */
+                thisrr->type = SSL3_RT_HANDSHAKE;
+                thisrr->rec_version = SSL2_VERSION;
+
+                thisrr->length = sslv2len & 0x7fff;
+
+                if (thisrr->length > SSL3_BUFFER_get_len(rbuf)
+                    - SSL2_RT_HEADER_LENGTH) {
+                    RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
+                                SSL_R_PACKET_LENGTH_TOO_LONG);
+                    return OSSL_RECORD_RETURN_FATAL;
+                }
+
+                if (thisrr->length < MIN_SSL2_RECORD_LEN) {
+                    RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
+                    return OSSL_RECORD_RETURN_FATAL;
+                }
+            } else {
+                /* SSLv3+ style record */
+
+                /* Pull apart the header into the SSL3_RECORD */
+                if (!PACKET_get_1(&pkt, &type)
+                        || !PACKET_get_net_2(&pkt, &version)
+                        || !PACKET_get_net_2_len(&pkt, &thisrr->length)) {
+                    if (s->msg_callback)
+                        s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, ssl,
+                                        s->msg_callback_arg);
+                    RLAYERfatal(rl, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR);
+                    return OSSL_RECORD_RETURN_FATAL;
+                }
+                thisrr->type = type;
+                thisrr->rec_version = version;
+
+                if (s->msg_callback)
+                    s->msg_callback(0, version, SSL3_RT_HEADER, p, 5, ssl,
+                                    s->msg_callback_arg);
+
+                /*
+                 * Lets check version. In TLSv1.3 we only check this field
+                 * when encryption is occurring (see later check). For the
+                 * ServerHello after an HRR we haven't actually selected TLSv1.3
+                 * yet, but we still treat it as TLSv1.3, so we must check for
+                 * that explicitly
+                 */
+                if (!s->first_packet && !SSL_CONNECTION_IS_TLS13(s)
+                        && s->hello_retry_request != SSL_HRR_PENDING
+                        && version != (unsigned int)s->version) {
+                    if ((s->version & 0xFF00) == (version & 0xFF00)
+                        && !s->enc_write_ctx && !s->write_hash) {
+                        if (thisrr->type == SSL3_RT_ALERT) {
+                            /*
+                             * The record is using an incorrect version number,
+                             * but what we've got appears to be an alert. We
+                             * haven't read the body yet to check whether its a
+                             * fatal or not - but chances are it is. We probably
+                             * shouldn't send a fatal alert back. We'll just
+                             * end.
+                             */
+                            RLAYERfatal(rl, SSL_AD_NO_ALERT,
+                                        SSL_R_WRONG_VERSION_NUMBER);
+                            return -1;
+                        }
+                        /*
+                         * Send back error using their minor version number :-)
+                         */
+                        s->version = (unsigned short)version;
+                    }
+                    RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
+                                SSL_R_WRONG_VERSION_NUMBER);
+                    return OSSL_RECORD_RETURN_FATAL;
+                }
+
+                if ((version >> 8) != SSL3_VERSION_MAJOR) {
+                    if (rl->is_first_record) {
+                        /* Go back to start of packet, look at the five bytes
+                         * that we have. */
+                        p = rl->packet;
+                        if (HAS_PREFIX((char *)p, "GET ") ||
+                            HAS_PREFIX((char *)p, "POST ") ||
+                            HAS_PREFIX((char *)p, "HEAD ") ||
+                            HAS_PREFIX((char *)p, "PUT ")) {
+                            RLAYERfatal(rl, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST);
+                            return OSSL_RECORD_RETURN_FATAL;
+                        } else if (HAS_PREFIX((char *)p, "CONNE")) {
+                            RLAYERfatal(rl, SSL_AD_NO_ALERT,
+                                        SSL_R_HTTPS_PROXY_REQUEST);
+                            return OSSL_RECORD_RETURN_FATAL;
+                        }
+
+                        /* Doesn't look like TLS - don't send an alert */
+                        RLAYERfatal(rl, SSL_AD_NO_ALERT,
+                                    SSL_R_WRONG_VERSION_NUMBER);
+                        return OSSL_RECORD_RETURN_FATAL;
+                    } else {
+                        RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION,
+                                    SSL_R_WRONG_VERSION_NUMBER);
+                        return OSSL_RECORD_RETURN_FATAL;
+                    }
+                }
+
+                if (SSL_CONNECTION_IS_TLS13(s)
+                        && s->enc_read_ctx != NULL
+                        && !using_ktls) {
+                    if (thisrr->type != SSL3_RT_APPLICATION_DATA
+                            && (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
+                                || !SSL_IS_FIRST_HANDSHAKE(s))
+                            && (thisrr->type != SSL3_RT_ALERT
+                                || s->statem.enc_read_state
+                                   != ENC_READ_STATE_ALLOW_PLAIN_ALERTS)) {
+                        RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
+                                    SSL_R_BAD_RECORD_TYPE);
+                        return OSSL_RECORD_RETURN_FATAL;
+                    }
+                    if (thisrr->rec_version != TLS1_2_VERSION) {
+                        RLAYERfatal(rl, SSL_AD_DECODE_ERROR,
+                                    SSL_R_WRONG_VERSION_NUMBER);
+                        return OSSL_RECORD_RETURN_FATAL;
+                    }
+                }
+
+                if (thisrr->length >
+                    SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
+                    RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
+                                SSL_R_PACKET_LENGTH_TOO_LONG);
+                    return OSSL_RECORD_RETURN_FATAL;
+                }
+            }
+
+            /* now rl->rstate == SSL_ST_READ_BODY */
+        }
+
+        if (SSL_CONNECTION_IS_TLS13(s)) {
+            size_t len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH;
+
+            /* KTLS strips the inner record type. */
+            if (using_ktls)
+                len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
+
+            if (thisrr->length > len) {
+                RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
+                            SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+                return OSSL_RECORD_RETURN_FATAL;
+            }
+        } else {
+            size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
+
+#ifndef OPENSSL_NO_COMP
+            /*
+             * If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH
+             * does not include the compression overhead anyway.
+             */
+            if (s->expand == NULL)
+                len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+
+            /* KTLS may use all of the buffer */
+            if (using_ktls)
+                len = SSL3_BUFFER_get_left(rbuf);
+
+            if (thisrr->length > len) {
+                RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
+                            SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+                return OSSL_RECORD_RETURN_FATAL;
+            }
+        }
+
+        /*
+         * rl->rstate == SSL_ST_READ_BODY, get and decode the data. Calculate
+         * how much more data we need to read for the rest of the record
+         */
+        if (thisrr->rec_version == SSL2_VERSION) {
+            more = thisrr->length + SSL2_RT_HEADER_LENGTH
+                - SSL3_RT_HEADER_LENGTH;
+        } else {
+            more = thisrr->length;
+        }
+
+        if (more > 0) {
+            /* now rl->packet_length == SSL3_RT_HEADER_LENGTH */
+
+            rret = tls_read_n(rl, more, more, 1, 0, &n);
+            if (rret < OSSL_RECORD_RETURN_SUCCESS)
+                return rret;     /* error or non-blocking io */
+        }
+
+        /* set state for later operations */
+        rl->rstate = SSL_ST_READ_HEADER;
+
+        /*
+         * At this point, rl->packet_length == SSL3_RT_HEADER_LENGTH
+         * + thisrr->length, or rl->packet_length == SSL2_RT_HEADER_LENGTH
+         * + thisrr->length and we have that many bytes in rl->packet
+         */
+        if (thisrr->rec_version == SSL2_VERSION)
+            thisrr->input = &(rl->packet[SSL2_RT_HEADER_LENGTH]);
+        else
+            thisrr->input = &(rl->packet[SSL3_RT_HEADER_LENGTH]);
+
+        /*
+         * ok, we can now read from 'rl->packet' data into 'thisrr'.
+         * thisrr->input points at thisrr->length bytes, which need to be copied
+         * into thisrr->data by either the decryption or by the decompression.
+         * When the data is 'copied' into the thisrr->data buffer,
+         * thisrr->input will be updated to point at the new buffer
+         */
+
+        /*
+         * We now have - encrypted [ MAC [ compressed [ plain ] ] ]
+         * thisrr->length bytes of encrypted compressed stuff.
+         */
+
+        /* decrypt in place in 'thisrr->input' */
+        thisrr->data = thisrr->input;
+        thisrr->orig_len = thisrr->length;
+
+        /* Mark this record as not read by upper layers yet */
+        thisrr->read = 0;
+
+        num_recs++;
+
+        /* we have pulled in a full packet so zero things */
+        tls_reset_packet_length(rl);
+        rl->is_first_record = 0;
+    } while (num_recs < max_recs
+             && thisrr->type == SSL3_RT_APPLICATION_DATA
+             && SSL_USE_EXPLICIT_IV(s)
+             && s->enc_read_ctx != NULL
+             && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx))
+                 & EVP_CIPH_FLAG_PIPELINE) != 0
+             && tls_record_app_data_waiting(rl));
+
+    if (num_recs == 1
+            && thisrr->type == SSL3_RT_CHANGE_CIPHER_SPEC
+            && (SSL_CONNECTION_IS_TLS13(s) || s->hello_retry_request != SSL_HRR_NONE)
+            && SSL_IS_FIRST_HANDSHAKE(s)) {
+        /*
+         * CCS messages must be exactly 1 byte long, containing the value 0x01
+         */
+        if (thisrr->length != 1 || thisrr->data[0] != 0x01) {
+            RLAYERfatal(rl, SSL_AD_ILLEGAL_PARAMETER,
+                        SSL_R_INVALID_CCS_MESSAGE);
+            return OSSL_RECORD_RETURN_FATAL;
+        }
+        /*
+         * CCS messages are ignored in TLSv1.3. We treat it like an empty
+         * handshake record
+         */
+        thisrr->type = SSL3_RT_HANDSHAKE;
+        RECORD_LAYER_inc_empty_record_count(&s->rlayer);
+        if (RECORD_LAYER_get_empty_record_count(&s->rlayer) > MAX_EMPTY_RECORDS) {
+            RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
+                        SSL_R_UNEXPECTED_CCS_MESSAGE);
+            return OSSL_RECORD_RETURN_FATAL;
+        }
+        thisrr->read = 1;
+        rl->num_recs = 0;
+        rl->curr_rec = 0;
+        rl->num_released = 0;
+
+        return OSSL_RECORD_RETURN_SUCCESS;
+    }
+
+    if (using_ktls)
+        goto skip_decryption;
+
+    if (s->read_hash != NULL) {
+        const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(s->read_hash);
+
+        if (tmpmd != NULL) {
+            imac_size = EVP_MD_get_size(tmpmd);
+            if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) {
+                    RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
+                    return OSSL_RECORD_RETURN_FATAL;
+            }
+            mac_size = (size_t)imac_size;
+        }
+    }
+
+    /*
+     * If in encrypt-then-mac mode calculate mac from encrypted record. All
+     * the details below are public so no timing details can leak.
+     */
+    if (SSL_READ_ETM(s) && s->read_hash) {
+        unsigned char *mac;
+
+        for (j = 0; j < num_recs; j++) {
+            thisrr = &rr[j];
+
+            if (thisrr->length < mac_size) {
+                RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
+                return OSSL_RECORD_RETURN_FATAL;
+            }
+            thisrr->length -= mac_size;
+            mac = thisrr->data + thisrr->length;
+            i = ssl->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ );
+            if (i == 0 || CRYPTO_memcmp(md, mac, mac_size) != 0) {
+                RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
+                            SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+                return OSSL_RECORD_RETURN_FATAL;
+            }
+        }
+        /*
+         * We've handled the mac now - there is no MAC inside the encrypted
+         * record
+         */
+        mac_size = 0;
+    }
+
+    if (mac_size > 0) {
+        macbufs = OPENSSL_zalloc(sizeof(*macbufs) * num_recs);
+        if (macbufs == NULL) {
+            RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+            return OSSL_RECORD_RETURN_FATAL;
+        }
+    }
+
+    enc_err = ssl->method->ssl3_enc->enc(s, rr, num_recs, 0, macbufs, mac_size);
+
+    /*-
+     * enc_err is:
+     *    0: if the record is publicly invalid, or an internal error, or AEAD
+     *       decryption failed, or ETM decryption failed.
+     *    1: Success or MTE decryption failed (MAC will be randomised)
+     */
+    if (enc_err == 0) {
+        if (ossl_statem_in_error(s)) {
+            /* SSLfatal() already got called */
+            goto end;
+        }
+        if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
+            /*
+             * Valid early_data that we cannot decrypt will fail here. We treat
+             * it like an empty record.
+             */
+
+            thisrr = &rr[0];
+
+            if (!ossl_early_data_count_ok(s, thisrr->length,
+                                     EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) {
+                /* SSLfatal() already called */
+                goto end;
+            }
+
+            thisrr->length = 0;
+            thisrr->read = 1;
+            rl->num_recs = 0;
+            rl->curr_rec = 0;
+            rl->num_released = 0;
+            RECORD_LAYER_reset_read_sequence(&s->rlayer);
+            ret = 1;
+            goto end;
+        }
+        RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
+                    SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+        goto end;
+    }
+    OSSL_TRACE_BEGIN(TLS) {
+        BIO_printf(trc_out, "dec %lu\n", (unsigned long)rr[0].length);
+        BIO_dump_indent(trc_out, rr[0].data, rr[0].length, 4);
+    } OSSL_TRACE_END(TLS);
+
+    /* r->length is now the compressed data plus mac */
+    if ((sess != NULL)
+            && (s->enc_read_ctx != NULL)
+            && (!SSL_READ_ETM(s) && EVP_MD_CTX_get0_md(s->read_hash) != NULL)) {
+        /* s->read_hash != NULL => mac_size != -1 */
+
+        for (j = 0; j < num_recs; j++) {
+            SSL_MAC_BUF *thismb = &macbufs[j];
+            thisrr = &rr[j];
+
+            i = ssl->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ );
+            if (i == 0 || thismb == NULL || thismb->mac == NULL
+                || CRYPTO_memcmp(md, thismb->mac, (size_t)mac_size) != 0)
+                enc_err = 0;
+            if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
+                enc_err = 0;
+        }
+    }
+
+    if (enc_err == 0) {
+        if (ossl_statem_in_error(s)) {
+            /* We already called SSLfatal() */
+            goto end;
+        }
+        /*
+         * A separate 'decryption_failed' alert was introduced with TLS 1.0,
+         * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
+         * failure is directly visible from the ciphertext anyway, we should
+         * not reveal which kind of error occurred -- this might become
+         * visible to an attacker (e.g. via a logfile)
+         */
+        RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
+                    SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+        goto end;
+    }
+
+ skip_decryption:
+
+    for (j = 0; j < num_recs; j++) {
+        thisrr = &rr[j];
+
+        /* thisrr->length is now just compressed */
+        if (s->expand != NULL) {
+            if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
+                RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
+                            SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+                goto end;
+            }
+            if (!ssl3_do_uncompress(s, thisrr)) {
+                RLAYERfatal(rl, SSL_AD_DECOMPRESSION_FAILURE,
+                            SSL_R_BAD_DECOMPRESSION);
+                goto end;
+            }
+        }
+
+        if (SSL_CONNECTION_IS_TLS13(s)
+                && s->enc_read_ctx != NULL
+                && thisrr->type != SSL3_RT_ALERT) {
+            /*
+             * The following logic are irrelevant in KTLS: the kernel provides
+             * unprotected record and thus record type represent the actual
+             * content type, and padding is already removed and thisrr->type and
+             * thisrr->length should have the correct values.
+             */
+            if (!using_ktls) {
+                size_t end;
+
+                if (thisrr->length == 0
+                        || thisrr->type != SSL3_RT_APPLICATION_DATA) {
+                    RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
+                                SSL_R_BAD_RECORD_TYPE);
+                    goto end;
+                }
+
+                /* Strip trailing padding */
+                for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0;
+                     end--)
+                    continue;
+
+                thisrr->length = end;
+                thisrr->type = thisrr->data[end];
+            }
+            if (thisrr->type != SSL3_RT_APPLICATION_DATA
+                    && thisrr->type != SSL3_RT_ALERT
+                    && thisrr->type != SSL3_RT_HANDSHAKE) {
+                RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE);
+                goto end;
+            }
+            if (s->msg_callback)
+                s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE,
+                                &thisrr->type, 1, ssl, s->msg_callback_arg);
+        }
+
+        /*
+         * TLSv1.3 alert and handshake records are required to be non-zero in
+         * length.
+         */
+        if (SSL_CONNECTION_IS_TLS13(s)
+                && (thisrr->type == SSL3_RT_HANDSHAKE
+                    || thisrr->type == SSL3_RT_ALERT)
+                && thisrr->length == 0) {
+            RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_LENGTH);
+            goto end;
+        }
+
+        /*
+         * Usually thisrr->length is the length of a single record, but when
+         * KTLS handles the decryption, thisrr->length may be larger than
+         * SSL3_RT_MAX_PLAIN_LENGTH because the kernel may have coalesced
+         * multiple records.
+         * Therefore we have to rely on KTLS to check the plaintext length
+         * limit in the kernel.
+         */
+        if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH && !using_ktls) {
+            RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
+            goto end;
+        }
+
+        /*
+         * Check if the received packet overflows the current
+         * Max Fragment Length setting.
+         * Note: USE_MAX_FRAGMENT_LENGTH_EXT and KTLS are mutually exclusive.
+         */
+        if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)
+                && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) {
+            RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
+            goto end;
+        }
+
+        thisrr->off = 0;
+        /*-
+         * So at this point the following is true
+         * thisrr->type   is the type of record
+         * thisrr->length == number of bytes in record
+         * thisrr->off    == offset to first valid byte
+         * thisrr->data   == where to take bytes from, increment after use :-).
+         */
+
+        /* just read a 0 length packet */
+        if (thisrr->length == 0) {
+            RECORD_LAYER_inc_empty_record_count(&s->rlayer);
+            if (RECORD_LAYER_get_empty_record_count(&s->rlayer)
+                > MAX_EMPTY_RECORDS) {
+                RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_RECORD_TOO_SMALL);
+                goto end;
+            }
+        } else {
+            RECORD_LAYER_reset_empty_record_count(&s->rlayer);
+        }
+    }
+
+    if (s->early_data_state == SSL_EARLY_DATA_READING) {
+        thisrr = &rr[0];
+        if (thisrr->type == SSL3_RT_APPLICATION_DATA
+                && !ossl_early_data_count_ok(s, thisrr->length, 0, 0)) {
+            /* SSLfatal already called */
+            goto end;
+        }
+    }
+
+    rl->num_recs = num_recs;
+    rl->curr_rec = 0;
+    rl->num_released = 0;
+    ret = OSSL_RECORD_RETURN_SUCCESS;
+ end:
+    if (macbufs != NULL) {
+        for (j = 0; j < num_recs; j++) {
+            if (macbufs[j].alloced)
+                OPENSSL_free(macbufs[j].mac);
+        }
+        OPENSSL_free(macbufs);
+    }
+    return ret;
+}
+
+static int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle,
+                           int *rversion, int *type, unsigned char **data,
+                           size_t *datalen, uint16_t *epoch,
+                           unsigned char *seq_num,
+                           /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
+{
+    SSL3_RECORD *rec;
+
+    /*
+     * tls_get_more_records() can return success without actually reading
+     * anything useful (i.e. if empty records are read). We loop here until
+     * we have something useful. tls_get_more_records() will eventually fail if
+     * too many sequential empty records are read.
+     */
+    while (rl->curr_rec >= rl->num_recs) {
+        int ret;
+
+        if (rl->num_released != rl->num_recs) {
+            RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_RECORDS_NOT_RELEASED);
+            return OSSL_RECORD_RETURN_FATAL;
+        }
+
+        ret = tls_get_more_records(rl, s);
+
+        if (ret != OSSL_RECORD_RETURN_SUCCESS)
+            return ret;
+    }
+
+    /*
+     * We have now got rl->num_recs records buffered in rl->rrec. rl->curr_rec
+     * points to the next one to read.
+     */
+    rec = &rl->rrec[rl->curr_rec++];
+
+    *rechandle = rec;
+    *rversion = rec->rec_version;
+    *type = rec->type;
+    *data = rec->data;
+    *datalen = rec->length;
+
+    return OSSL_RECORD_RETURN_SUCCESS;
+}
+
+static int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
+{
+    if (!ossl_assert(rl->num_released < rl->curr_rec)
+            || !ossl_assert(rechandle == &rl->rrec[rl->num_released])) {
+        /* Should not happen */
+        RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_INVALID_RECORD);
+        return OSSL_RECORD_RETURN_FATAL;
+    }
+
+    rl->num_released++;
+
+    return OSSL_RECORD_RETURN_SUCCESS;
+}
+
 static OSSL_RECORD_LAYER *tls_new_record_layer(int vers, int role, int direction,
                                                int level, unsigned char *secret,
                                                size_t secretlen, SSL_CIPHER *c,
@@ -354,6 +1130,10 @@ static OSSL_RECORD_LAYER *tls_new_record_layer(int vers, int role, int direction
     rl->version = vers;
     rl->role = role;
     rl->direction = direction;
+
+    if (level == 0)
+        rl->is_first_record = 1;
+
     if (!tls_set1_bio(rl, transport))
         goto err;
 
@@ -397,12 +1177,12 @@ static int tls_reset(OSSL_RECORD_LAYER *rl)
 
 static int tls_unprocessed_read_pending(OSSL_RECORD_LAYER *rl)
 {
-    return 0;
+    return SSL3_BUFFER_get_left(&rl->rbuf) != 0;;
 }
 
 static int tls_processed_read_pending(OSSL_RECORD_LAYER *rl)
 {
-    return 0;
+    return rl->curr_rec < rl->num_recs;
 }
 
 static size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl)
@@ -438,18 +1218,6 @@ static int tls_retry_write_records(OSSL_RECORD_LAYER *rl, size_t allowance,
     return 0;
 }
 
-static int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle,
-                           int *rversion, int *type, unsigned char **data,
-                           size_t *datalen, uint16_t *epoch,
-                           unsigned char *seq_num)
-{
-    return 0;
-}
-
-static void tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
-{
-    return;
-}
 
 static int tls_get_alert_code(OSSL_RECORD_LAYER *rl)
 {
@@ -488,11 +1256,6 @@ static size_t tls_get_packet_length(OSSL_RECORD_LAYER *rl)
     return rl->packet_length;
 }
 
-static void tls_reset_packet_length(OSSL_RECORD_LAYER *rl)
-{
-    rl->packet_length = 0;
-}
-
 const OSSL_RECORD_METHOD ossl_tls_record_method = {
     tls_new_record_layer,
     tls_free,
index a202cf92991573b6fdde2d07d9276e983be5d586..8910b819522921015b20610f98e51d3dfea3673f 100644 (file)
@@ -216,6 +216,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
     "invalid max early data"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_NULL_CMD_NAME),
     "invalid null cmd name"},
+    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_RECORD), "invalid record"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SEQUENCE_NUMBER),
     "invalid sequence number"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SERVERINFO_DATA),
@@ -344,6 +345,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_BIO_NOT_SET), "read bio not set"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_TIMEOUT_EXPIRED),
     "read timeout expired"},
+    {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORDS_NOT_RELEASED),
+    "records not released"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LAYER_FAILURE),
     "record layer failure"},
     {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LENGTH_MISMATCH),
index 93100cc74362c736e2bb7c37b85266f2be7bf85a..70d194ff815f01f1aada6b2c50c08b812f7bebdb 100644 (file)
@@ -1263,8 +1263,7 @@ int tls_get_message_header(SSL_CONNECTION *s, int *mt)
          * Total message size is the remaining record bytes to read
          * plus the SSL3_HM_HEADER_LENGTH bytes that we already read
          */
-        l = RECORD_LAYER_get_rrec_length(&s->rlayer)
-            + SSL3_HM_HEADER_LENGTH;
+        l = s->rlayer.tlsrecs[0].length + SSL3_HM_HEADER_LENGTH;
         s->s3.tmp.message_size = l;
 
         s->init_msg = s->init_buf->data;
index 00e9ba39ae2cb5d102321d6ddd489c4bba4361c0..e06d8825562ab3ae725a2c3ec9c95053f9777b09 100644 (file)
@@ -1541,7 +1541,6 @@ static int execute_cleanse_plaintext(const SSL_METHOD *smeth,
     SSL_CTX *cctx = NULL, *sctx = NULL;
     SSL *clientssl = NULL, *serverssl = NULL;
     int testresult = 0;
-    SSL3_RECORD *rr;
     void *zbuf;
     SSL_CONNECTION *serversc;
 
@@ -1606,10 +1605,24 @@ static int execute_cleanse_plaintext(const SSL_METHOD *smeth,
      */
     if (!TEST_ptr(serversc = SSL_CONNECTION_FROM_SSL_ONLY(serverssl)))
         goto end;
-    rr = serversc->rlayer.rrec;
-    zbuf = &rr->data[rr->off];
-    if (!TEST_int_eq(rr->length, sizeof(cbuf)))
-        goto end;
+
+    /*
+     * TODO(RECLAYER): This is temporary until DTLS is converted to use the new
+     * record layer code.
+     */
+    if (!SSL_is_dtls(serverssl)) {
+        TLS_RECORD *rr = serversc->rlayer.tlsrecs;
+
+        zbuf = &rr->data[rr->off];
+        if (!TEST_int_eq(rr->length, sizeof(cbuf)))
+            goto end;
+    } else {
+        SSL3_RECORD *rr = serversc->rlayer.rrec;
+
+        zbuf = &rr->data[rr->off];
+        if (!TEST_int_eq(rr->length, sizeof(cbuf)))
+            goto end;
+    }
 
     /*
      * After SSL_peek() the plaintext must still be stored in the