Lift the handshake driving in write_bytes up to SSL_write.

This removes one use of in_handshake and consolidates some DTLS and TLS
code.

Change-Id: Ibbdd38360a983dabfb7b18c7bd59cb5e316b2adb
Reviewed-on: https://boringssl-review.googlesource.com/7435
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 3d1631b..ad67902 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -458,39 +458,24 @@
 }
 
 int dtls1_write_app_data(SSL *ssl, const void *buf_, int len) {
-  int i;
-
-  if (SSL_in_init(ssl) && !ssl->in_handshake) {
-    i = ssl->handshake_func(ssl);
-    if (i < 0) {
-      return i;
-    }
-    if (i == 0) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
-      return -1;
-    }
-  }
+  assert(!SSL_in_init(ssl));
 
   if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG);
     return -1;
   }
 
-  i = dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len,
-                        dtls1_use_current_epoch);
-  return i;
+  return dtls1_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf_, len,
+                           dtls1_use_current_epoch);
 }
 
 /* Call this to write data in records of type 'type' It will return <= 0 if not
  * all data has been sent or non-blocking IO. */
 int dtls1_write_bytes(SSL *ssl, int type, const void *buf, int len,
                       enum dtls1_use_epoch_t use_epoch) {
-  int i;
-
   assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
   ssl->rwstate = SSL_NOTHING;
-  i = do_dtls1_write(ssl, type, buf, len, use_epoch);
-  return i;
+  return do_dtls1_write(ssl, type, buf, len, use_epoch);
 }
 
 static int do_dtls1_write(SSL *ssl, int type, const uint8_t *buf,
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 4ce6603..90f0d44 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -182,6 +182,8 @@
 }
 
 int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
+  assert(!SSL_in_init(ssl) || SSL_in_false_start(ssl));
+
   return ssl3_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len);
 }
 
@@ -196,17 +198,6 @@
   tot = ssl->s3->wnum;
   ssl->s3->wnum = 0;
 
-  if (!ssl->in_handshake && SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
-    int ret = ssl->handshake_func(ssl);
-    if (ret < 0) {
-      return ret;
-    }
-    if (ret == 0) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
-      return -1;
-    }
-  }
-
   /* Ensure that if we end up with a smaller value of data to write out than
    * the the original len from a write which didn't complete for non-blocking
    * I/O and also somehow ended up avoiding the check for this in
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index d1ea2fe..f9ce9db 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -628,6 +628,19 @@
   }
 
   ERR_clear_system_error();
+
+  /* If necessary, complete the handshake implicitly. */
+  if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
+    int ret = SSL_do_handshake(ssl);
+    if (ret < 0) {
+      return ret;
+    }
+    if (ret == 0) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
+      return -1;
+    }
+  }
+
   return ssl->method->ssl_write_app_data(ssl, buf, num);
 }