Introduce a new early_data state in the state machine
[openssl.git] / ssl / statem / statem_lib.c
index 6261804129f822c3c4bbb1d33f9eec0aac32335c..595d7c13a75cf584328fe6efa3df21f280a9d843 100644 (file)
@@ -503,29 +503,53 @@ int tls_construct_key_update(SSL *s, WPACKET *pkt)
     }
 
     s->key_update = SSL_KEY_UPDATE_NONE;
-
     return 1;
+
  err:
     ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
     return 0;
 }
 
-
 MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt)
 {
+    int al;
     unsigned int updatetype;
 
+    s->key_update_count++;
+    if (s->key_update_count > MAX_KEY_UPDATE_MESSAGES) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_TOO_MANY_KEY_UPDATES);
+        goto err;
+    }
+
     if (!PACKET_get_1(pkt, &updatetype)
             || PACKET_remaining(pkt) != 0
             || (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
                 && updatetype != SSL_KEY_UPDATE_REQUESTED)) {
-        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+        al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_BAD_KEY_UPDATE);
-        ossl_statem_set_error(s);
-        return MSG_PROCESS_ERROR;
+        goto err;
+    }
+
+    /*
+     * If we get a request for us to update our sending keys too then, we need
+     * to additionally send a KeyUpdate message. However that message should
+     * not also request an update (otherwise we get into an infinite loop).
+     */
+    if (updatetype == SSL_KEY_UPDATE_REQUESTED)
+        s->key_update = SSL_KEY_UPDATE_NOT_REQUESTED;
+
+    if (!tls13_update_key(s, 0)) {
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, ERR_R_INTERNAL_ERROR);
+        goto err;
     }
 
     return MSG_PROCESS_FINISHED_READING;
+ err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
 }
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
@@ -630,6 +654,10 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt)
     int al = SSL_AD_INTERNAL_ERROR;
     size_t md_len;
 
+
+    /* This is a real handshake so make sure we clean it up at the end */
+    s->statem.cleanuphand = 1;
+
     /* If this occurs, we have missed a message */
     if (!SSL_IS_TLS13(s) && !s->s3->change_cipher_spec) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -920,6 +948,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs)
             s->d1->next_handshake_write_seq = 0;
             dtls1_clear_received_buffer(s);
         }
+        s->early_data_state = SSL_EARLY_DATA_NONE;
     }
 
     /*
@@ -929,6 +958,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs)
     if (!clearbufs)
         return WORK_FINISHED_CONTINUE;
 
+    ossl_statem_set_in_init(s, 0);
     return WORK_FINISHED_STOP;
 }
 
@@ -1297,8 +1327,6 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method)
         return SSL_R_UNSUPPORTED_PROTOCOL;
     if ((method->flags & SSL_METHOD_NO_SUITEB) != 0 && tls1_suiteb(s))
         return SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE;
-    else if ((method->flags & SSL_METHOD_NO_FIPS) != 0 && FIPS_mode())
-        return SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE;
 
     return 0;
 }
@@ -1656,7 +1684,7 @@ int ssl_choose_client_version(SSL *s, int version)
  * Work out what version we should be using for the initial ClientHello if the
  * version is initially (D)TLS_ANY_VERSION.  We apply any explicit SSL_OP_NO_xxx
  * options, the MinProtocol and MaxProtocol configuration commands, any Suite B
- * or FIPS_mode() constraints and any floor imposed by the security level here,
+ * constraints and any floor imposed by the security level here,
  * so we don't advertise the wrong protocol version to only reject the outcome later.
  *
  * Computing the right floor matters.  If, e.g., TLS 1.0 and 1.2 are enabled,