Simplify the ChangeCipherSpec logic.

It's the same between TLS and SSL 3.0. There's also no need for the
do_change_cipher_spec wrapper (it no longer needs checks to ensure it
isn't called at a bad place). Finally fold the setup_key_block call into
change_cipher_spec.

Change-Id: I7917f48e1a322f5fbafcf1dfb8ad53f66565c314
Reviewed-on: https://boringssl-review.googlesource.com/6834
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 4e73bc2..2837c2e 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -368,9 +368,7 @@
         ssl->state = SSL3_ST_CW_FINISHED_A;
         ssl->init_num = 0;
 
-        if (!ssl->enc_method->setup_key_block(ssl) ||
-            !ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
           ret = -1;
           goto end;
         }
@@ -430,7 +428,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_READ)) {
           ret = -1;
           goto end;
         }
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 4f2d5ec..6e30cae 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -355,7 +355,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_READ)) {
           ret = -1;
           goto end;
         }
@@ -393,11 +393,6 @@
 
       case SSL3_ST_SW_CHANGE_A:
       case SSL3_ST_SW_CHANGE_B:
-        if (!ssl->enc_method->setup_key_block(ssl)) {
-          ret = -1;
-          goto end;
-        }
-
         ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A,
                                             SSL3_ST_SW_CHANGE_B);
 
@@ -408,8 +403,7 @@
         ssl->state = SSL3_ST_SW_FINISHED_A;
         ssl->init_num = 0;
 
-        if (!ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
           ret = -1;
           goto end;
         }
diff --git a/ssl/internal.h b/ssl/internal.h
index 1096cb7..110a5ba 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -854,9 +854,7 @@
 struct ssl3_enc_method {
   int (*prf)(SSL *, uint8_t *, size_t, const uint8_t *, size_t, const char *,
              size_t, const uint8_t *, size_t, const uint8_t *, size_t);
-  int (*setup_key_block)(SSL *);
   int (*generate_master_secret)(SSL *, uint8_t *, const uint8_t *, size_t);
-  int (*change_cipher_state)(SSL *, int);
   int (*final_finish_mac)(SSL *, const char *, int, uint8_t *);
   int (*cert_verify_mac)(SSL *, int, uint8_t *);
   const char *client_finished_label;
@@ -1087,8 +1085,6 @@
 int ssl3_accept(SSL *ssl);
 int ssl3_connect(SSL *ssl);
 
-int ssl3_do_change_cipher_spec(SSL *ssl);
-
 int ssl3_set_handshake_header(SSL *ssl, int htype, unsigned long len);
 int ssl3_handshake_write(SSL *ssl);
 
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 0fca13c..7ff0a15 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -388,9 +388,7 @@
         }
         ssl->init_num = 0;
 
-        if (!ssl->enc_method->setup_key_block(ssl) ||
-            !ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
           ret = -1;
           goto end;
         }
@@ -486,7 +484,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_CLIENT_READ)) {
           ret = -1;
           goto end;
         }
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 64f9f8c..a84227d 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -165,9 +165,7 @@
 
 const SSL3_ENC_METHOD SSLv3_enc_data = {
     ssl3_prf,
-    tls1_setup_key_block,
     tls1_generate_master_secret,
-    tls1_change_cipher_state,
     ssl3_final_finish_mac,
     ssl3_cert_verify_mac,
     SSL3_MD_CLIENT_FINISHED_CONST, 4,
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index e9c9be5..b4cc725 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -637,34 +637,6 @@
   return -1;
 }
 
-int ssl3_do_change_cipher_spec(SSL *ssl) {
-  int i;
-
-  if (ssl->state & SSL_ST_ACCEPT) {
-    i = SSL3_CHANGE_CIPHER_SERVER_READ;
-  } else {
-    i = SSL3_CHANGE_CIPHER_CLIENT_READ;
-  }
-
-  if (ssl->s3->tmp.key_block == NULL) {
-    if (ssl->session == NULL || ssl->session->master_key_length == 0) {
-      /* might happen if dtls1_read_bytes() calls this */
-      OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
-      return 0;
-    }
-
-    if (!ssl->enc_method->setup_key_block(ssl)) {
-      return 0;
-    }
-  }
-
-  if (!ssl->enc_method->change_cipher_state(ssl, i)) {
-    return 0;
-  }
-
-  return 1;
-}
-
 int ssl3_send_alert(SSL *ssl, int level, int desc) {
   /* Map tls/ssl alert value to correct one */
   desc = ssl->enc_method->alert_value(desc);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 489f585..8f1899d 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -425,7 +425,7 @@
           goto end;
         }
 
-        if (!ssl3_do_change_cipher_spec(ssl)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_READ)) {
           ret = -1;
           goto end;
         }
@@ -502,11 +502,6 @@
 
       case SSL3_ST_SW_CHANGE_A:
       case SSL3_ST_SW_CHANGE_B:
-        if (!ssl->enc_method->setup_key_block(ssl)) {
-          ret = -1;
-          goto end;
-        }
-
         ret = ssl3_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A,
                                            SSL3_ST_SW_CHANGE_B);
         if (ret <= 0) {
@@ -515,8 +510,7 @@
         ssl->state = SSL3_ST_SW_FINISHED_A;
         ssl->init_num = 0;
 
-        if (!ssl->enc_method->change_cipher_state(
-                ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+        if (!tls1_change_cipher_state(ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
           ret = -1;
           goto end;
         }
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 7dd6f0e..8c4b6d8 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -269,6 +269,11 @@
 }
 
 int tls1_change_cipher_state(SSL *ssl, int which) {
+  /* Ensure the key block is set up. */
+  if (!tls1_setup_key_block(ssl)) {
+    return 0;
+  }
+
   /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
    * need to update the read cipherspec. Otherwise we have just written one. */
   const char is_read = (which & SSL3_CC_READ) != 0;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index d12ec5b..25d9916 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -132,9 +132,7 @@
 
 const SSL3_ENC_METHOD TLSv1_enc_data = {
     tls1_prf,
-    tls1_setup_key_block,
     tls1_generate_master_secret,
-    tls1_change_cipher_state,
     tls1_final_finish_mac,
     tls1_cert_verify_mac,
     TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
@@ -146,9 +144,7 @@
 
 const SSL3_ENC_METHOD TLSv1_1_enc_data = {
     tls1_prf,
-    tls1_setup_key_block,
     tls1_generate_master_secret,
-    tls1_change_cipher_state,
     tls1_final_finish_mac,
     tls1_cert_verify_mac,
     TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
@@ -160,9 +156,7 @@
 
 const SSL3_ENC_METHOD TLSv1_2_enc_data = {
     tls1_prf,
-    tls1_setup_key_block,
     tls1_generate_master_secret,
-    tls1_change_cipher_state,
     tls1_final_finish_mac,
     tls1_cert_verify_mac,
     TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,