static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) { return ssl_hs_error; } SSL_CLIENT_HELLO client_hello; if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg, ssl->init_num)) { OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } int need_retry; if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) { if (need_retry) { /* Only send one HelloRetryRequest. */ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); } return ssl_hs_error; } if (!ssl_hash_current_message(ssl)) { return ssl_hs_error; } ssl->method->received_flight(ssl); hs->tls13_state = state_send_server_hello; return ssl_hs_ok; }
static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED) || /* If early data was accepted, we've already computed the client Finished * and derived the resumption secret. */ !tls13_process_finished(hs, ssl->early_data_accepted) || /* evp_aead_seal keys have already been switched. */ !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0, hs->hash_len)) { return ssl_hs_error; } ssl->method->received_flight(ssl); if (!ssl->early_data_accepted) { if (!ssl_hash_current_message(hs) || !tls13_derive_resumption_secret(hs)) { return ssl_hs_error; } /* We send post-handshake tickets as part of the handshake in 1-RTT. */ hs->tls13_state = state_send_new_session_ticket; return ssl_hs_ok; } hs->tls13_state = state_done; return ssl_hs_ok; }
static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) { if (!hs->ssl->s3->tlsext_channel_id_valid) { hs->tls13_state = state_process_client_finished; return ssl_hs_ok; } if (!ssl_check_message_type(hs->ssl, SSL3_MT_CHANNEL_ID) || !tls1_verify_channel_id(hs) || !ssl_hash_current_message(hs)) { return ssl_hs_error; } hs->tls13_state = state_process_client_finished; return ssl_hs_read_message; }
static enum ssl_hs_wait_t do_process_client_certificate_verify( SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; if (ssl->s3->new_session->x509_peer == NULL) { /* Skip this state. */ hs->tls13_state = state_process_channel_id; return ssl_hs_ok; } if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) || !tls13_process_certificate_verify(hs) || !ssl_hash_current_message(ssl)) { return ssl_hs_error; } hs->tls13_state = state_process_channel_id; return ssl_hs_read_message; }
static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED) || !tls13_process_finished(hs) || !ssl_hash_current_message(ssl) || /* evp_aead_seal keys have already been switched. */ !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0, hs->hash_len) || !tls13_derive_resumption_secret(hs)) { return ssl_hs_error; } ssl->method->received_flight(ssl); /* Rebase the session timestamp so that it is measured from ticket * issuance. */ ssl_session_rebase_time(ssl, ssl->s3->new_session); hs->tls13_state = state_send_new_session_ticket; return ssl_hs_ok; }
static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; if (!hs->cert_request) { /* OpenSSL returns X509_V_OK when no certificates are requested. This is * classed by them as a bug, but it's assumed by at least NGINX. */ ssl->s3->new_session->verify_result = X509_V_OK; /* Skip this state. */ hs->tls13_state = state_process_channel_id; return ssl_hs_ok; } const int allow_anonymous = (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0; if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE) || !tls13_process_certificate(hs, allow_anonymous) || !ssl_hash_current_message(ssl)) { return ssl_hs_error; } hs->tls13_state = state_process_client_certificate_verify; return ssl_hs_read_message; }