summaryrefslogtreecommitdiffstats
path: root/ssl/statem/statem_clnt.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-12-05 10:14:35 +0000
committerMatt Caswell <matt@openssl.org>2017-12-14 15:06:37 +0000
commit597c51bc980ba6d7470dd8de747ac12a6c7a442b (patch)
treebfaa1fb62ac77032ed159170cf5df7ab7a31b717 /ssl/statem/statem_clnt.c
parentdb37d32cb89160328b0ba48e3808f601a7b3ebe8 (diff)
Merge HRR into ServerHello
Reviewed-by: Ben Kaduk <kaduk@mit.edu> (Merged from https://github.com/openssl/openssl/pull/4701)
Diffstat (limited to 'ssl/statem/statem_clnt.c')
-rw-r--r--ssl/statem/statem_clnt.c153
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;
}