diff options
Diffstat (limited to 'ssl/statem/statem_clnt.c')
-rw-r--r-- | ssl/statem/statem_clnt.c | 153 |
1 files changed, 63 insertions, 90 deletions
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 37c198e713..af9e1dcd7d 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -22,7 +22,7 @@ #include <openssl/bn.h> #include <openssl/engine.h> -static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt); +static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt); static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt); static ossl_inline int cert_req_allowed(SSL *s); @@ -206,11 +206,6 @@ int ossl_statem_client_read_transition(SSL *s, int mt) st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST; return 1; } - } else { - if (mt == SSL3_MT_HELLO_RETRY_REQUEST) { - st->hand_state = TLS_ST_CR_HELLO_RETRY_REQUEST; - return 1; - } } break; @@ -224,10 +219,6 @@ int ossl_statem_client_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_CR_SRVR_HELLO; return 1; } - if (mt == SSL3_MT_HELLO_RETRY_REQUEST) { - st->hand_state = TLS_ST_CR_HELLO_RETRY_REQUEST; - return 1; - } break; case TLS_ST_CR_SRVR_HELLO: @@ -506,7 +497,8 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) */ return WRITE_TRAN_FINISHED; - case TLS_ST_CR_HELLO_RETRY_REQUEST: + case TLS_ST_CR_SRVR_HELLO: + /* We only get here in TLSv1.3 */ st->hand_state = TLS_ST_CW_CLNT_HELLO; return WRITE_TRAN_CONTINUE; @@ -912,9 +904,6 @@ size_t ossl_statem_client_max_message_size(SSL *s) case DTLS_ST_CR_HELLO_VERIFY_REQUEST: return HELLO_VERIFY_REQUEST_MAX_LENGTH; - case TLS_ST_CR_HELLO_RETRY_REQUEST: - return HELLO_RETRY_REQUEST_MAX_LENGTH; - case TLS_ST_CR_CERT: return s->max_cert_list; @@ -978,9 +967,6 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) case DTLS_ST_CR_HELLO_VERIFY_REQUEST: return dtls_process_hello_verify(s, pkt); - case TLS_ST_CR_HELLO_RETRY_REQUEST: - return tls_process_hello_retry_request(s, pkt); - case TLS_ST_CR_CERT: return tls_process_server_certificate(s, pkt); @@ -1353,6 +1339,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) PACKET session_id, extpkt; size_t session_id_len; const unsigned char *cipherchars; + int hrr = 0; unsigned int compression; unsigned int sversion; unsigned int context; @@ -1369,10 +1356,22 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) } /* load the server random */ - if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_LENGTH_MISMATCH); - goto err; + if (s->version == TLS1_3_VERSION + && sversion == TLS1_2_VERSION + && PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE + && memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) { + s->hello_retry_request = hrr = 1; + if (!PACKET_forward(pkt, SSL3_RANDOM_SIZE)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, + SSL_R_LENGTH_MISMATCH); + goto err; + } + } else { + if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, + SSL_R_LENGTH_MISMATCH); + goto err; + } } /* Get the session-id. */ @@ -1402,7 +1401,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) } /* TLS extensions */ - if (PACKET_remaining(pkt) == 0) { + if (PACKET_remaining(pkt) == 0 && !hrr) { PACKET_null_init(&extpkt); } else if (!PACKET_as_length_prefixed_2(pkt, &extpkt) || PACKET_remaining(pkt) != 0) { @@ -1411,17 +1410,45 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) goto err; } - if (!tls_collect_extensions(s, &extpkt, - SSL_EXT_TLS1_2_SERVER_HELLO - | SSL_EXT_TLS1_3_SERVER_HELLO, - &extensions, NULL, 1)) { - /* SSLfatal() already called */ - goto err; + if (!hrr) { + if (!tls_collect_extensions(s, &extpkt, + SSL_EXT_TLS1_2_SERVER_HELLO + | SSL_EXT_TLS1_3_SERVER_HELLO, + &extensions, NULL, 1)) { + /* SSLfatal() already called */ + goto err; + } + + if (!ssl_choose_client_version(s, sversion, extensions)) { + /* SSLfatal() already called */ + goto err; + } } - if (!ssl_choose_client_version(s, sversion, extensions)) { - /* SSLfatal() already called */ - goto err; + if (SSL_IS_TLS13(s) || hrr) { + if (compression != 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, + SSL_F_TLS_PROCESS_SERVER_HELLO, + SSL_R_INVALID_COMPRESSION_ALGORITHM); + goto err; + } + + if (session_id_len != s->tmp_session_id_len + || memcmp(PACKET_data(&session_id), s->tmp_session_id, + session_id_len) != 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, + SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_INVALID_SESSION_ID); + goto err; + } + } + + if (hrr) { + if (!set_client_ciphersuite(s, cipherchars)) { + /* SSLfatal() already called */ + goto err; + } + + return tls_process_as_hello_retry_request(s, &extpkt); } /* @@ -1450,21 +1477,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) goto err; } - if (compression != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_INVALID_COMPRESSION_ALGORITHM); - goto err; - } - - if (session_id_len != s->tmp_session_id_len - || memcmp(PACKET_data(&session_id), s->tmp_session_id, - session_id_len) != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_INVALID_SESSION_ID); - goto err; - } - /* This will set s->hit if we are resuming */ if (!tls_parse_extension(s, TLSEXT_IDX_psk, SSL_EXT_TLS1_3_SERVER_HELLO, @@ -1670,28 +1682,10 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt) +static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, + PACKET *extpkt) { - unsigned int sversion; - const unsigned char *cipherchars; RAW_EXTENSION *extensions = NULL; - PACKET extpkt; - - if (!PACKET_get_net_2(pkt, &sversion)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, - SSL_R_LENGTH_MISMATCH); - goto err; - } - - /* TODO(TLS1.3): Remove the TLS1_3_VERSION_DRAFT clause before release */ - if (sversion != TLS1_3_VERSION && sversion != TLS1_3_VERSION_DRAFT) { - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, - SSL_R_WRONG_SSL_VERSION); - goto err; - } - - s->hello_retry_request = 1; /* * If we were sending early_data then the enc_write_ctx is now invalid and @@ -1700,28 +1694,7 @@ static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt) EVP_CIPHER_CTX_free(s->enc_write_ctx); s->enc_write_ctx = NULL; - if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, - SSL_R_LENGTH_MISMATCH); - goto err; - } - - if (!set_client_ciphersuite(s, cipherchars)) { - /* SSLfatal() already called */ - goto err; - } - - if (!PACKET_as_length_prefixed_2(pkt, &extpkt) - /* Must have a non-empty extensions block */ - || PACKET_remaining(&extpkt) == 0 - /* Must be no trailing data after extensions */ - || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, - SSL_R_BAD_LENGTH); - goto err; - } - - if (!tls_collect_extensions(s, &extpkt, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, + if (!tls_collect_extensions(s, extpkt, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, &extensions, NULL, 1) || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, extensions, NULL, 0, 1)) { @@ -1742,8 +1715,8 @@ static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt) * ClientHello will not change */ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, - SSL_R_NO_CHANGE_FOLLOWING_HRR); + SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST, + SSL_R_NO_CHANGE_FOLLOWING_HRR); goto err; } |