Proxy: send whole SSL records through the handshaker.

In split handshake tests, it is already the case that the handshaker
must signal the proxy when it wants to read more data.  But there was
not a lot of specificity about exactly how much data would be read.

The case of rejecting early data sent with a second ClientHello,
following a HelloRetryRequest,[1] requires this to be nailed down, in
order that the handshaker should not process the early data.

This commit changes the handshaker to read exactly one SSL record and
then stop, when it is asked to read.  The pattern of I/O operations
remains undefined.

[1] See SkipEarlyData-SecondClientHelloEarlyData-TLS13-Split.

Change-Id: I30f58e57fc5ebff3f7c7ef8482cc629e42fef6a4
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/39524
Commit-Queue: Matt Braithwaite <mab@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/test/handshake_util.cc b/ssl/test/handshake_util.cc
index 5265bd9..f3f725d 100644
--- a/ssl/test/handshake_util.cc
+++ b/ssl/test/handshake_util.cc
@@ -242,24 +242,55 @@
         return false;
     }
 
-    char readbuf[64];
-    if (async) {
-      AsyncBioAllowRead(socket, 1);
-    }
-    int read = BIO_read(socket, readbuf, sizeof(readbuf));
-    if (read < 1) {
-      fprintf(stderr, "BIO_read failed\n");
+    auto proxy_data = [&](uint8_t *out, size_t len) -> bool {
+      if (async) {
+        AsyncBioAllowRead(socket, len);
+      }
+
+      while (len > 0) {
+        int bytes_read = BIO_read(socket, out, len);
+        if (bytes_read < 1) {
+          fprintf(stderr, "BIO_read failed\n");
+          return false;
+        }
+
+        ssize_t bytes_written = write_eintr(rfd, out, bytes_read);
+        if (bytes_written == -1) {
+          perror("write");
+          return false;
+        }
+        if (bytes_written != bytes_read) {
+          fprintf(stderr, "short write (%zu of %d bytes)\n", bytes_written,
+                  bytes_read);
+          return false;
+        }
+
+        len -= bytes_read;
+        out += bytes_read;
+      }
+      return true;
+    };
+
+    // Process one SSL record at a time.  That way, we don't send the handshaker
+    // anything it doesn't want to process, e.g. early data.
+    uint8_t header[SSL3_RT_HEADER_LENGTH];
+    if (!proxy_data(header, sizeof(header))) {
       return false;
     }
-    ssize_t written = write_eintr(rfd, readbuf, read);
-    if (written == -1) {
-      perror("write");
-      return false;
+    if (header[1] != 3) {
+       fprintf(stderr, "bad header\n");
+       return false;
     }
-    if (written != read) {
-      fprintf(stderr, "short write (%zu of %d bytes)\n", written, read);
-      return false;
+    size_t remaining = (header[3] << 8) + header[4];
+    while (remaining > 0) {
+      uint8_t readbuf[64];
+      size_t len = remaining > sizeof(readbuf) ? sizeof(readbuf) : remaining;
+      if (!proxy_data(readbuf, len)) {
+        return false;
+      }
+      remaining -= len;
     }
+
     // The handshaker blocks on the control channel, so we have to signal
     // it that the data have been written.
     msg = kControlMsgWriteCompleted;