Move state machine knowledge out of the record layer
[openssl.git] / ssl / statem / statem.c
index ac78d2dc24a0ee1b51d36a31ab296b4ef6adc7bd..bd7d89a4610d126b2131c05777a3eb2fa5b7fb59 100644 (file)
@@ -105,7 +105,6 @@ void ossl_statem_clear(SSL *s)
  */
 void ossl_statem_set_renegotiate(SSL *s)
 {
-    s->statem.state = MSG_FLOW_RENEGOTIATE;
     s->statem.in_init = 1;
     s->statem.request_state = TLS_ST_SW_HELLO_REQ;
 }
@@ -190,10 +189,10 @@ static info_cb get_callback(SSL *s)
 
 /*
  * The main message flow state machine. We start in the MSG_FLOW_UNINITED or
- * MSG_FLOW_RENEGOTIATE state and finish in MSG_FLOW_FINISHED. Valid states and
+ * MSG_FLOW_FINISHED state and finish in MSG_FLOW_FINISHED. Valid states and
  * transitions are as follows:
  *
- * MSG_FLOW_UNINITED     MSG_FLOW_RENEGOTIATE
+ * MSG_FLOW_UNINITED     MSG_FLOW_FINISHED
  *        |                       |
  *        +-----------------------+
  *        v
@@ -253,15 +252,7 @@ static int state_machine(SSL *s, int server)
 #endif
 
     /* Initialise state machine */
-
-    if (st->state == MSG_FLOW_RENEGOTIATE) {
-        s->renegotiate = 1;
-        if (!server)
-            s->ctx->stats.sess_connect_renegotiate++;
-    }
-
     if (st->state == MSG_FLOW_UNINITED
-            || st->state == MSG_FLOW_RENEGOTIATE
             || st->state == MSG_FLOW_FINISHED) {
         if (st->state == MSG_FLOW_UNINITED) {
             st->hand_state = TLS_ST_BEFORE;
@@ -322,53 +313,14 @@ static int state_machine(SSL *s, int server)
                 goto end;
             }
 
-        if (!SSL_IS_TLS13(s)) {
-            if (!server || st->state != MSG_FLOW_RENEGOTIATE) {
-                if (!ssl3_init_finished_mac(s)) {
-                    ossl_statem_set_error(s);
-                    goto end;
-                }
-            }
-
-            if (server) {
-                if (st->state != MSG_FLOW_RENEGOTIATE) {
-                    s->ctx->stats.sess_accept++;
-                } else if (!s->s3->send_connection_binding &&
-                           !(s->options &
-                             SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
-                    /*
-                     * Server attempting to renegotiate with client that doesn't
-                     * support secure renegotiation.
-                     */
-                    SSLerr(SSL_F_STATE_MACHINE,
-                           SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-                    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-                    ossl_statem_set_error(s);
-                    goto end;
-                } else {
-                    /*
-                     * st->state == MSG_FLOW_RENEGOTIATE, we will just send a
-                     * HelloRequest
-                     */
-                    s->ctx->stats.sess_accept_renegotiate++;
-
-                    s->s3->tmp.cert_request = 0;
-                }
-            } else {
-                s->ctx->stats.sess_connect++;
-
-                /* mark client_random uninitialized */
-                memset(s->s3->client_random, 0, sizeof(s->s3->client_random));
-                s->hit = 0;
-
-                s->s3->tmp.cert_req = 0;
-
-                if (SSL_IS_DTLS(s)) {
-                    st->use_timer = 1;
-                }
+        if (SSL_IS_FIRST_HANDSHAKE(s) || s->renegotiate) {
+            if (!tls_setup_handshake(s)) {
+                ossl_statem_set_error(s);
+                goto end;
             }
 
-            st->read_state_first_init = 1;
+            if (SSL_IS_FIRST_HANDSHAKE(s))
+                st->read_state_first_init = 1;
         }
 
         st->state = MSG_FLOW_WRITING;
@@ -826,7 +778,7 @@ int statem_flush(SSL *s)
 
 /*
  * Called by the record layer to determine whether application data is
- * allowed to be sent in the current handshake state or not.
+ * allowed to be received in the current handshake state or not.
  *
  * Return values are:
  *   1: Yes (application data allowed)
@@ -836,7 +788,7 @@ int ossl_statem_app_data_allowed(SSL *s)
 {
     OSSL_STATEM *st = &s->statem;
 
-    if (st->state == MSG_FLOW_UNINITED || st->state == MSG_FLOW_RENEGOTIATE)
+    if (st->state == MSG_FLOW_UNINITED)
         return 0;
 
     if (!s->s3->in_read_app_data || (s->s3->total_renegotiations == 0))