Abstract away BIO_flush calls in the handshake.

This is the first part to removing the buffer BIO. The eventual end
state is the SSL_PROTOCOL_METHOD is responsible for maintaining one
flight's worth of messages. In TLS, it will just be a buffer containing
the flight's ciphertext. In DTLS, it's the existing structure for
retransmit purposes. There will be hooks:

- add_message (synchronous)
- add_change_cipher_spec (synchronous)
- add_warning_alert (synchronous; needed until we lose SSLv3 client auth
  and TLS 1.3 draft 18; draft 19 will switch end_of_early_data to a
  handshake message)
- write_flight (BIO; flush_flight will be renamed to this)

This also preserves the exact return value of BIO_flush. Eventually all
the BIO_write calls will be hidden behind BIO_flush to, to be consistent
with other BIO-based calls, preserve the return value.

BUG=72

Change-Id: I74cd23759a17356aab3bb475a8ea42bd2cd115c9
Reviewed-on: https://boringssl-review.googlesource.com/13222
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/dtls_method.c b/ssl/dtls_method.c
index 6576686..702b3c0 100644
--- a/ssl/dtls_method.c
+++ b/ssl/dtls_method.c
@@ -99,6 +99,14 @@
   return cipher->algorithm_enc != SSL_eNULL;
 }
 
+static int dtls1_flush_flight(SSL *ssl) {
+  int ret = BIO_flush(ssl->wbio);
+  if (ret <= 0) {
+    ssl->rwstate = SSL_WRITING;
+  }
+  return ret;
+}
+
 static void dtls1_expect_flight(SSL *ssl) { dtls1_start_timer(ssl); }
 
 static void dtls1_received_flight(SSL *ssl) { dtls1_stop_timer(ssl); }
@@ -154,6 +162,7 @@
     dtls1_queue_message,
     dtls1_write_message,
     dtls1_send_change_cipher_spec,
+    dtls1_flush_flight,
     dtls1_expect_flight,
     dtls1_received_flight,
     dtls1_set_read_state,
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index 720c215..388d53b 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -482,9 +482,8 @@
         break;
 
       case SSL3_ST_CW_FLUSH:
-        if (BIO_flush(ssl->wbio) <= 0) {
-          ssl->rwstate = SSL_WRITING;
-          ret = -1;
+        ret = ssl->method->flush_flight(ssl);
+        if (ret <= 0) {
           goto end;
         }
         hs->state = hs->next_state;
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index d510c089..a4396f4 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -451,9 +451,8 @@
         break;
 
       case SSL3_ST_SW_FLUSH:
-        if (BIO_flush(ssl->wbio) <= 0) {
-          ssl->rwstate = SSL_WRITING;
-          ret = -1;
+        ret = ssl->method->flush_flight(ssl);
+        if (ret <= 0) {
           goto end;
         }
 
diff --git a/ssl/internal.h b/ssl/internal.h
index 3ad6c96..e082dda 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1346,6 +1346,9 @@
   int (*write_message)(SSL *ssl);
   /* send_change_cipher_spec sends a ChangeCipherSpec message. */
   int (*send_change_cipher_spec)(SSL *ssl);
+  /* flush_flight flushes the current flight to the transport. It returns one on
+   * success and <= 0 on error. */
+  int (*flush_flight)(SSL *ssl);
   /* expect_flight is called when the handshake expects a flight of messages from
    * the peer. */
   void (*expect_flight)(SSL *ssl);
diff --git a/ssl/tls13_both.c b/ssl/tls13_both.c
index 7347fc4..1425665 100644
--- a/ssl/tls13_both.c
+++ b/ssl/tls13_both.c
@@ -45,9 +45,8 @@
 
       case ssl_hs_flush:
       case ssl_hs_flush_and_read_message: {
-        int ret = BIO_flush(ssl->wbio);
+        int ret = ssl->method->flush_flight(ssl);
         if (ret <= 0) {
-          ssl->rwstate = SSL_WRITING;
           return ret;
         }
         if (hs->wait != ssl_hs_flush_and_read_message) {
diff --git a/ssl/tls_method.c b/ssl/tls_method.c
index 4efed3f..a6584c1 100644
--- a/ssl/tls_method.c
+++ b/ssl/tls_method.c
@@ -100,6 +100,14 @@
 
 static int ssl3_supports_cipher(const SSL_CIPHER *cipher) { return 1; }
 
+static int ssl3_flush_flight(SSL *ssl) {
+  int ret = BIO_flush(ssl->wbio);
+  if (ret <= 0) {
+    ssl->rwstate = SSL_WRITING;
+  }
+  return ret;
+}
+
 static void ssl3_expect_flight(SSL *ssl) {}
 
 static void ssl3_received_flight(SSL *ssl) {}
@@ -150,6 +158,7 @@
     ssl3_queue_message,
     ssl3_write_message,
     ssl3_send_change_cipher_spec,
+    ssl3_flush_flight,
     ssl3_expect_flight,
     ssl3_received_flight,
     ssl3_set_read_state,