Remove the rest of write_message.

The TLS 1.2 state machine now looks actually much closer to the TLS 1.3
one on the write side. Although the write states still have a BIO-style
return, they don't actually send anything anymore. Only the BIO flush
state does. Reads are still integrated into the states themselves
though, so I haven't made it match TLS 1.3 yet.

BUG=72

Change-Id: I7708162efca13cd335723efa5080718a5f2808ab
Reviewed-on: https://boringssl-review.googlesource.com/13228
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index e75b70d..256b2c5 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -309,7 +309,6 @@
 #define SSL3_ST_VERIFY_SERVER_CERT (0x102 | SSL_ST_CONNECT)
 /* write to server */
 #define SSL3_ST_CW_CLNT_HELLO_A (0x110 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CLNT_HELLO_B (0x111 | SSL_ST_CONNECT)
 /* read from server */
 #define SSL3_ST_CR_SRVR_HELLO_A (0x120 | SSL_ST_CONNECT)
 #define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126 | SSL_ST_CONNECT)
@@ -320,19 +319,13 @@
 #define SSL3_ST_CR_SRVR_DONE_A (0x160 | SSL_ST_CONNECT)
 /* write to server */
 #define SSL3_ST_CW_CERT_A (0x170 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CERT_B (0x171 | SSL_ST_CONNECT)
 #define SSL3_ST_CW_KEY_EXCH_A (0x180 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_KEY_EXCH_B (0x181 | SSL_ST_CONNECT)
 #define SSL3_ST_CW_CERT_VRFY_A (0x190 | SSL_ST_CONNECT)
 #define SSL3_ST_CW_CERT_VRFY_B (0x191 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CERT_VRFY_C (0x192 | SSL_ST_CONNECT)
 #define SSL3_ST_CW_CHANGE (0x1A0 | SSL_ST_CONNECT)
 #define SSL3_ST_CW_NEXT_PROTO_A (0x200 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_NEXT_PROTO_B (0x201 | SSL_ST_CONNECT)
 #define SSL3_ST_CW_CHANNEL_ID_A (0x220 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CHANNEL_ID_B (0x221 | SSL_ST_CONNECT)
 #define SSL3_ST_CW_FINISHED_A (0x1B0 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_FINISHED_B (0x1B1 | SSL_ST_CONNECT)
 /* read from server */
 #define SSL3_ST_CR_CHANGE (0x1C0 | SSL_ST_CONNECT)
 #define SSL3_ST_CR_FINISHED_A (0x1D0 | SSL_ST_CONNECT)
@@ -357,16 +350,11 @@
 #define SSL3_ST_SW_HELLO_REQ_B (0x121 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_HELLO_REQ_C (0x122 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_SRVR_HELLO_A (0x130 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SRVR_HELLO_B (0x131 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_CERT_A (0x140 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_CERT_B (0x141 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_KEY_EXCH_A (0x150 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_KEY_EXCH_B (0x151 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_KEY_EXCH_C (0x152 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_CERT_REQ_A (0x160 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_CERT_REQ_B (0x161 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_SRVR_DONE_A (0x170 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SRVR_DONE_B (0x171 | SSL_ST_ACCEPT)
 /* read from client */
 #define SSL3_ST_SR_CERT_A (0x180 | SSL_ST_ACCEPT)
 #define SSL3_ST_SR_KEY_EXCH_A (0x190 | SSL_ST_ACCEPT)
@@ -380,13 +368,8 @@
 /* write to client */
 #define SSL3_ST_SW_CHANGE (0x1D0 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_FINISHED_A (0x1E0 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_FINISHED_B (0x1E1 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_SESSION_TICKET_A (0x1F0 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1 | SSL_ST_ACCEPT)
 #define SSL3_ST_SW_CERT_STATUS_A (0x200 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_CERT_STATUS_B (0x201 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221 | SSL_ST_ACCEPT)
 
 #define SSL3_MT_HELLO_REQUEST 0
 #define SSL3_MT_CLIENT_HELLO 1
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index bbb6b32..9fad2d0 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -583,11 +583,6 @@
   return add_outgoing(ssl, 0 /* handshake */, data, len);
 }
 
-int dtls1_write_message(SSL *ssl) {
-  /* The message is written in |dtls1_flush_flight|. */
-  return 1;
-}
-
 int dtls1_add_change_cipher_spec(SSL *ssl) {
   return add_outgoing(ssl, 1 /* ChangeCipherSpec */, NULL, 0);
 }
diff --git a/ssl/dtls_method.c b/ssl/dtls_method.c
index e7cd21e..7a35b39 100644
--- a/ssl/dtls_method.c
+++ b/ssl/dtls_method.c
@@ -159,7 +159,6 @@
     dtls1_received_flight,
     dtls1_set_read_state,
     dtls1_set_write_state,
-    dtls1_write_message,
 };
 
 const SSL_METHOD *DTLS_method(void) {
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index 29b59d4..c3d3572 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -210,7 +210,6 @@
         break;
 
       case SSL3_ST_CW_CLNT_HELLO_A:
-      case SSL3_ST_CW_CLNT_HELLO_B:
         ret = ssl3_send_client_hello(hs);
         if (ret <= 0) {
           goto end;
@@ -320,7 +319,6 @@
         break;
 
       case SSL3_ST_CW_CERT_A:
-      case SSL3_ST_CW_CERT_B:
         if (hs->cert_request) {
           ret = ssl3_send_client_certificate(hs);
           if (ret <= 0) {
@@ -333,7 +331,6 @@
         break;
 
       case SSL3_ST_CW_KEY_EXCH_A:
-      case SSL3_ST_CW_KEY_EXCH_B:
         ret = ssl3_send_client_key_exchange(hs);
         if (ret <= 0) {
           goto end;
@@ -343,7 +340,6 @@
 
       case SSL3_ST_CW_CERT_VRFY_A:
       case SSL3_ST_CW_CERT_VRFY_B:
-      case SSL3_ST_CW_CERT_VRFY_C:
         if (hs->cert_request && ssl_has_certificate(ssl)) {
           ret = ssl3_send_cert_verify(hs);
           if (ret <= 0) {
@@ -366,7 +362,6 @@
         break;
 
       case SSL3_ST_CW_NEXT_PROTO_A:
-      case SSL3_ST_CW_NEXT_PROTO_B:
         if (hs->next_proto_neg_seen) {
           ret = ssl3_send_next_proto(hs);
           if (ret <= 0) {
@@ -379,7 +374,6 @@
         break;
 
       case SSL3_ST_CW_CHANNEL_ID_A:
-      case SSL3_ST_CW_CHANNEL_ID_B:
         if (ssl->s3->tlsext_channel_id_valid) {
           ret = ssl3_send_channel_id(hs);
           if (ret <= 0) {
@@ -392,9 +386,7 @@
         break;
 
       case SSL3_ST_CW_FINISHED_A:
-      case SSL3_ST_CW_FINISHED_B:
-        ret = ssl3_send_finished(hs, SSL3_ST_CW_FINISHED_A,
-                                 SSL3_ST_CW_FINISHED_B);
+        ret = ssl3_send_finished(hs);
         if (ret <= 0) {
           goto end;
         }
@@ -706,10 +698,6 @@
 
 static int ssl3_send_client_hello(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_CW_CLNT_HELLO_B) {
-    return ssl->method->write_message(ssl);
-  }
-
   /* The handshake buffer is reset on every ClientHello. Notably, in DTLS, we
    * may send multiple ClientHellos if we receive HelloVerifyRequest. */
   if (!ssl3_init_handshake_buffer(ssl)) {
@@ -763,8 +751,7 @@
     return -1;
   }
 
-  hs->state = SSL3_ST_CW_CLNT_HELLO_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 static int dtls1_get_hello_verify(SSL_HANDSHAKE *hs) {
@@ -1430,11 +1417,6 @@
 
 static int ssl3_send_client_certificate(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_CW_CERT_B) {
-    return ssl->method->write_message(ssl);
-  }
-  assert(hs->state == SSL3_ST_CW_CERT_A);
-
   /* Call cert_cb to update the certificate. */
   if (ssl->cert->cert_cb) {
     int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
@@ -1467,8 +1449,7 @@
       !ssl3_output_cert_chain(ssl)) {
     return -1;
   }
-  hs->state = SSL3_ST_CW_CERT_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned),
@@ -1476,11 +1457,6 @@
 
 static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_CW_KEY_EXCH_B) {
-    return ssl->method->write_message(ssl);
-  }
-  assert(hs->state == SSL3_ST_CW_KEY_EXCH_A);
-
   uint8_t *pms = NULL;
   size_t pms_len = 0;
   CBB cbb, body;
@@ -1637,7 +1613,6 @@
   if (!ssl_add_message_cbb(ssl, &cbb)) {
     goto err;
   }
-  hs->state = SSL3_ST_CW_KEY_EXCH_B;
 
   ssl->s3->new_session->master_key_length =
       tls1_generate_master_secret(ssl, ssl->s3->new_session->master_key, pms,
@@ -1650,7 +1625,7 @@
   OPENSSL_cleanse(pms, pms_len);
   OPENSSL_free(pms);
 
-  return ssl->method->write_message(ssl);
+  return 1;
 
 err:
   CBB_cleanup(&cbb);
@@ -1663,10 +1638,6 @@
 
 static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_CW_CERT_VRFY_C) {
-    return ssl->method->write_message(ssl);
-  }
-
   assert(ssl_has_private_key(ssl));
 
   CBB cbb, body, child;
@@ -1756,8 +1727,7 @@
     goto err;
   }
 
-  hs->state = SSL3_ST_CW_CERT_VRFY_C;
-  return ssl->method->write_message(ssl);
+  return 1;
 
 err:
   CBB_cleanup(&cbb);
@@ -1766,12 +1736,6 @@
 
 static int ssl3_send_next_proto(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_CW_NEXT_PROTO_B) {
-    return ssl->method->write_message(ssl);
-  }
-
-  assert(hs->state == SSL3_ST_CW_NEXT_PROTO_A);
-
   static const uint8_t kZero[32] = {0};
   size_t padding_len = 32 - ((ssl->s3->next_proto_negotiated_len + 2) % 32);
 
@@ -1788,18 +1752,11 @@
     return -1;
   }
 
-  hs->state = SSL3_ST_CW_NEXT_PROTO_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 static int ssl3_send_channel_id(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_CW_CHANNEL_ID_B) {
-    return ssl->method->write_message(ssl);
-  }
-
-  assert(hs->state == SSL3_ST_CW_CHANNEL_ID_A);
-
   if (!ssl_do_channel_id_callback(ssl)) {
     return -1;
   }
@@ -1818,8 +1775,7 @@
     return -1;
   }
 
-  hs->state = SSL3_ST_CW_CHANNEL_ID_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 static int ssl3_get_new_session_ticket(SSL_HANDSHAKE *hs) {
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index 00b374c..33ffa7e 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -232,7 +232,6 @@
         break;
 
       case SSL3_ST_SW_SRVR_HELLO_A:
-      case SSL3_ST_SW_SRVR_HELLO_B:
         ret = ssl3_send_server_hello(hs);
         if (ret <= 0) {
           goto end;
@@ -245,7 +244,6 @@
         break;
 
       case SSL3_ST_SW_CERT_A:
-      case SSL3_ST_SW_CERT_B:
         if (ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
           ret = ssl3_send_server_certificate(hs);
           if (ret <= 0) {
@@ -258,7 +256,6 @@
         break;
 
       case SSL3_ST_SW_CERT_STATUS_A:
-      case SSL3_ST_SW_CERT_STATUS_B:
         if (hs->certificate_status_expected) {
           ret = ssl3_send_certificate_status(hs);
           if (ret <= 0) {
@@ -272,7 +269,6 @@
 
       case SSL3_ST_SW_KEY_EXCH_A:
       case SSL3_ST_SW_KEY_EXCH_B:
-      case SSL3_ST_SW_KEY_EXCH_C:
         alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
 
         /* PSK ciphers send ServerKeyExchange if there is an identity hint. */
@@ -290,7 +286,6 @@
         break;
 
       case SSL3_ST_SW_CERT_REQ_A:
-      case SSL3_ST_SW_CERT_REQ_B:
         if (hs->cert_request) {
           ret = ssl3_send_certificate_request(hs);
           if (ret <= 0) {
@@ -303,7 +298,6 @@
         break;
 
       case SSL3_ST_SW_SRVR_DONE_A:
-      case SSL3_ST_SW_SRVR_DONE_B:
         ret = ssl3_send_server_hello_done(hs);
         if (ret <= 0) {
           goto end;
@@ -403,7 +397,6 @@
         break;
 
       case SSL3_ST_SW_SESSION_TICKET_A:
-      case SSL3_ST_SW_SESSION_TICKET_B:
         if (hs->ticket_expected) {
           ret = ssl3_send_new_session_ticket(hs);
           if (ret <= 0) {
@@ -426,9 +419,7 @@
         break;
 
       case SSL3_ST_SW_FINISHED_A:
-      case SSL3_ST_SW_FINISHED_B:
-        ret = ssl3_send_finished(hs, SSL3_ST_SW_FINISHED_A,
-                                 SSL3_ST_SW_FINISHED_B);
+        ret = ssl3_send_finished(hs);
         if (ret <= 0) {
           goto end;
         }
@@ -1039,11 +1030,6 @@
 
 static int ssl3_send_server_hello(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_SW_SRVR_HELLO_B) {
-    return ssl->method->write_message(ssl);
-  }
-
-  assert(hs->state == SSL3_ST_SW_SRVR_HELLO_A);
 
   /* We only accept ChannelIDs on connections with ECDHE in order to avoid a
    * known attack while we fix ChannelID itself. */
@@ -1094,34 +1080,24 @@
     return -1;
   }
 
-  hs->state = SSL3_ST_SW_SRVR_HELLO_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_SW_CERT_B) {
-    return ssl->method->write_message(ssl);
-  }
-
   if (!ssl_has_certificate(ssl)) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
-    return 0;
+    return -1;
   }
 
   if (!ssl3_output_cert_chain(ssl)) {
-    return 0;
+    return -1;
   }
-  hs->state = SSL3_ST_SW_CERT_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 static int ssl3_send_certificate_status(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_SW_CERT_STATUS_B) {
-    return ssl->method->write_message(ssl);
-  }
-
   CBB cbb, body, ocsp_response;
   if (!ssl->method->init_message(ssl, &cbb, &body,
                                  SSL3_MT_CERTIFICATE_STATUS) ||
@@ -1135,16 +1111,11 @@
     return -1;
   }
 
-  hs->state = SSL3_ST_SW_CERT_STATUS_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_SW_KEY_EXCH_C) {
-    return ssl->method->write_message(ssl);
-  }
-
   CBB cbb, child;
   CBB_zero(&cbb);
 
@@ -1312,8 +1283,7 @@
   hs->server_params = NULL;
   hs->server_params_len = 0;
 
-  hs->state = SSL3_ST_SW_KEY_EXCH_C;
-  return ssl->method->write_message(ssl);
+  return 1;
 
 err:
   CBB_cleanup(&cbb);
@@ -1360,10 +1330,6 @@
 
 static int ssl3_send_certificate_request(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_SW_CERT_REQ_B) {
-    return ssl->method->write_message(ssl);
-  }
-
   CBB cbb, body, cert_types, sigalgs_cbb;
   if (!ssl->method->init_message(ssl, &cbb, &body,
                                  SSL3_MT_CERTIFICATE_REQUEST) ||
@@ -1391,8 +1357,7 @@
     goto err;
   }
 
-  hs->state = SSL3_ST_SW_CERT_REQ_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 
 err:
   OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1402,10 +1367,6 @@
 
 static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_SW_SRVR_DONE_B) {
-    return ssl->method->write_message(ssl);
-  }
-
   CBB cbb, body;
   if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO_DONE) ||
       !ssl_add_message_cbb(ssl, &cbb)) {
@@ -1414,8 +1375,7 @@
     return -1;
   }
 
-  hs->state = SSL3_ST_SW_SRVR_DONE_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 static int ssl3_get_client_certificate(SSL_HANDSHAKE *hs) {
@@ -1929,10 +1889,6 @@
 
 static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == SSL3_ST_SW_SESSION_TICKET_B) {
-    return ssl->method->write_message(ssl);
-  }
-
   const SSL_SESSION *session;
   SSL_SESSION *session_copy = NULL;
   if (ssl->session == NULL) {
@@ -1966,6 +1922,5 @@
     return -1;
   }
 
-  hs->state = SSL3_ST_SW_SESSION_TICKET_B;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
diff --git a/ssl/internal.h b/ssl/internal.h
index 157e3c0..66dc37a 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1359,8 +1359,6 @@
    * ownership of |aead_ctx|. It returns one on success and zero if changing the
    * write state is forbidden at this point. */
   int (*set_write_state)(SSL *ssl, SSL_AEAD_CTX *aead_ctx);
-  /* write_message returns one. */
-  int (*write_message)(SSL *ssl);
 };
 
 /* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit
@@ -1769,7 +1767,7 @@
 int ssl3_cert_verify_hash(SSL *ssl, const EVP_MD **out_md, uint8_t *out,
                           size_t *out_len, uint16_t signature_algorithm);
 
-int ssl3_send_finished(SSL_HANDSHAKE *hs, int a, int b);
+int ssl3_send_finished(SSL_HANDSHAKE *hs);
 int ssl3_dispatch_alert(SSL *ssl);
 int ssl3_read_app_data(SSL *ssl, int *out_got_handshake, uint8_t *buf, int len,
                        int peek);
@@ -1790,7 +1788,6 @@
 int ssl3_add_message(SSL *ssl, uint8_t *msg, size_t len);
 int ssl3_add_change_cipher_spec(SSL *ssl);
 int ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc);
-int ssl3_write_message(SSL *ssl);
 int ssl3_flush_flight(SSL *ssl);
 
 int dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
@@ -1799,7 +1796,6 @@
 int dtls1_add_message(SSL *ssl, uint8_t *msg, size_t len);
 int dtls1_add_change_cipher_spec(SSL *ssl);
 int dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc);
-int dtls1_write_message(SSL *ssl);
 int dtls1_flush_flight(SSL *ssl);
 
 /* ssl_add_message_cbb finishes the handshake message in |cbb| and adds it to
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 133cd2d..627ef63 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -295,8 +295,6 @@
   return 1;
 }
 
-int ssl3_write_message(SSL *ssl) { return 1; }
-
 int ssl3_flush_flight(SSL *ssl) {
   if (ssl->s3->pending_flight == NULL) {
     return 1;
@@ -342,12 +340,8 @@
   return 1;
 }
 
-int ssl3_send_finished(SSL_HANDSHAKE *hs, int a, int b) {
+int ssl3_send_finished(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (hs->state == b) {
-    return ssl->method->write_message(ssl);
-  }
-
   uint8_t finished[EVP_MAX_MD_SIZE];
   size_t finished_len =
       ssl->s3->enc_method->final_finish_mac(ssl, ssl->server, finished);
@@ -388,8 +382,7 @@
     return -1;
   }
 
-  hs->state = b;
-  return ssl->method->write_message(ssl);
+  return 1;
 }
 
 int ssl3_get_finished(SSL_HANDSHAKE *hs) {
diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c
index d657788..09a43d1 100644
--- a/ssl/ssl_stat.c
+++ b/ssl/ssl_stat.c
@@ -104,9 +104,6 @@
     case SSL3_ST_CW_CLNT_HELLO_A:
       return "SSLv3 write client hello A";
 
-    case SSL3_ST_CW_CLNT_HELLO_B:
-      return "SSLv3 write client hello B";
-
     case SSL3_ST_CR_SRVR_HELLO_A:
       return "SSLv3 read server hello A";
 
@@ -128,15 +125,9 @@
     case SSL3_ST_CW_CERT_A:
       return "SSLv3 write client certificate A";
 
-    case SSL3_ST_CW_CERT_B:
-      return "SSLv3 write client certificate B";
-
     case SSL3_ST_CW_KEY_EXCH_A:
       return "SSLv3 write client key exchange A";
 
-    case SSL3_ST_CW_KEY_EXCH_B:
-      return "SSLv3 write client key exchange B";
-
     case SSL3_ST_CW_CERT_VRFY_A:
       return "SSLv3 write certificate verify A";
 
@@ -151,10 +142,6 @@
     case SSL3_ST_SW_FINISHED_A:
       return "SSLv3 write finished A";
 
-    case SSL3_ST_CW_FINISHED_B:
-    case SSL3_ST_SW_FINISHED_B:
-      return "SSLv3 write finished B";
-
     case SSL3_ST_CR_CHANGE:
     case SSL3_ST_SR_CHANGE:
       return "SSLv3 read change cipher spec";
@@ -188,39 +175,21 @@
     case SSL3_ST_SW_SRVR_HELLO_A:
       return "SSLv3 write server hello A";
 
-    case SSL3_ST_SW_SRVR_HELLO_B:
-      return "SSLv3 write server hello B";
-
     case SSL3_ST_SW_CERT_A:
       return "SSLv3 write certificate A";
 
-    case SSL3_ST_SW_CERT_B:
-      return "SSLv3 write certificate B";
-
     case SSL3_ST_SW_KEY_EXCH_A:
       return "SSLv3 write key exchange A";
 
-    case SSL3_ST_SW_KEY_EXCH_B:
-      return "SSLv3 write key exchange B";
-
     case SSL3_ST_SW_CERT_REQ_A:
       return "SSLv3 write certificate request A";
 
-    case SSL3_ST_SW_CERT_REQ_B:
-      return "SSLv3 write certificate request B";
-
     case SSL3_ST_SW_SESSION_TICKET_A:
       return "SSLv3 write session ticket A";
 
-    case SSL3_ST_SW_SESSION_TICKET_B:
-      return "SSLv3 write session ticket B";
-
     case SSL3_ST_SW_SRVR_DONE_A:
       return "SSLv3 write server done A";
 
-    case SSL3_ST_SW_SRVR_DONE_B:
-      return "SSLv3 write server done B";
-
     case SSL3_ST_SR_CERT_A:
       return "SSLv3 read client certificate A";
 
@@ -261,9 +230,6 @@
     case SSL3_ST_CW_CLNT_HELLO_A:
       return "3WCH_A";
 
-    case SSL3_ST_CW_CLNT_HELLO_B:
-      return "3WCH_B";
-
     case SSL3_ST_CR_SRVR_HELLO_A:
       return "3RSH_A";
 
@@ -282,15 +248,9 @@
     case SSL3_ST_CW_CERT_A:
       return "3WCC_A";
 
-    case SSL3_ST_CW_CERT_B:
-      return "3WCC_B";
-
     case SSL3_ST_CW_KEY_EXCH_A:
       return "3WCKEA";
 
-    case SSL3_ST_CW_KEY_EXCH_B:
-      return "3WCKEB";
-
     case SSL3_ST_CW_CERT_VRFY_A:
       return "3WCV_A";
 
@@ -305,10 +265,6 @@
     case SSL3_ST_CW_FINISHED_A:
       return "3WFINA";
 
-    case SSL3_ST_SW_FINISHED_B:
-    case SSL3_ST_CW_FINISHED_B:
-      return "3WFINB";
-
     case SSL3_ST_CR_CHANGE:
     case SSL3_ST_SR_CHANGE:
       return "3RCCS_";
@@ -338,15 +294,9 @@
     case SSL3_ST_SW_SRVR_HELLO_A:
       return "3WSH_A";
 
-    case SSL3_ST_SW_SRVR_HELLO_B:
-      return "3WSH_B";
-
     case SSL3_ST_SW_CERT_A:
       return "3WSC_A";
 
-    case SSL3_ST_SW_CERT_B:
-      return "3WSC_B";
-
     case SSL3_ST_SW_KEY_EXCH_A:
       return "3WSKEA";
 
@@ -356,15 +306,9 @@
     case SSL3_ST_SW_CERT_REQ_A:
       return "3WCR_A";
 
-    case SSL3_ST_SW_CERT_REQ_B:
-      return "3WCR_B";
-
     case SSL3_ST_SW_SRVR_DONE_A:
       return "3WSD_A";
 
-    case SSL3_ST_SW_SRVR_DONE_B:
-      return "3WSD_B";
-
     case SSL3_ST_SR_CERT_A:
       return "3RCC_A";
 
diff --git a/ssl/tls_method.c b/ssl/tls_method.c
index 21f9e2a..70683e4 100644
--- a/ssl/tls_method.c
+++ b/ssl/tls_method.c
@@ -155,7 +155,6 @@
     ssl3_received_flight,
     ssl3_set_read_state,
     ssl3_set_write_state,
-    ssl3_write_message,
 };
 
 const SSL_METHOD *TLS_method(void) {