Don't call ssl3_read_message from ssl3_read_app_data.

With this change, it should now always be the case that rr->length is
zero on entry to ssl3_read_message. This will let us detach everything
but application data from rr. This pushes some init_buf invariants down
into tls_open_record so we don't need to maintain them everywhere.

Change-Id: I206747434e0a9603eea7d19664734fd16fa2de8e
Reviewed-on: https://boringssl-review.googlesource.com/21524
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc
index 12597a6..2a28859 100644
--- a/ssl/tls_record.cc
+++ b/ssl/tls_record.cc
@@ -192,6 +192,12 @@
                                                  size_t *out_consumed,
                                                  uint8_t *out_alert,
                                                  Span<uint8_t> in) {
+  // If there is an unprocessed handshake message or we are already buffering
+  // too much, stop before decrypting another handshake record.
+  if (!tls_can_accept_handshake_data(ssl, out_alert)) {
+    return ssl_open_record_error;
+  }
+
   CBS cbs = CBS(in);
 
   // Decode the record header.
@@ -321,6 +327,14 @@
     return ssl_process_alert(ssl, out_alert, *out);
   }
 
+  // Handshake messages may not interleave with any other record type.
+  if (type != SSL3_RT_HANDSHAKE &&
+      tls_has_unprocessed_handshake_data(ssl)) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
+    *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
+    return ssl_open_record_error;
+  }
+
   ssl->s3->warning_alert_count = 0;
 
   *out_type = type;