Only have one ClientHello parser, not three.
Between TLS 1.2, TLS 1.3, and the early callback, we've got a lot of
ClientHello parsers. Unify everything on the early callback's parser. As
a side effect, this means we can parse a ClientHello fairly succinctly
from any function which will let us split up ClientHello states where
appropriate.
Change-Id: I2359b75f80926cc7d827570cf33f93029b39e525
Reviewed-on: https://boringssl-review.googlesource.com/10184
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index a6d26d1..d10d7f5 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -534,74 +534,54 @@
int al = SSL_AD_INTERNAL_ERROR, ret = -1;
const SSL_CIPHER *c;
STACK_OF(SSL_CIPHER) *ciphers = NULL;
- struct ssl_early_callback_ctx early_ctx;
- CBS client_hello;
- uint16_t client_wire_version;
- CBS client_random, session_id, cipher_suites, compression_methods;
SSL_SESSION *session = NULL;
- /* We do this so that we will respond with our native type. If we are TLSv1
- * and we get SSLv3, we will respond with TLSv1, This down switching should
- * be handled by a different method. If we are SSLv3, we will respond with
- * SSLv3, even if prompted with TLSv1. */
- switch (ssl->state) {
- case SSL3_ST_SR_CLNT_HELLO_A: {
- int msg_ret = ssl->method->ssl_get_message(ssl, SSL3_MT_CLIENT_HELLO,
- ssl_hash_message);
- if (msg_ret <= 0) {
- return msg_ret;
- }
-
- ssl->state = SSL3_ST_SR_CLNT_HELLO_B;
+ if (ssl->state == SSL3_ST_SR_CLNT_HELLO_A) {
+ /* The first time around, read the ClientHello. */
+ int msg_ret = ssl->method->ssl_get_message(ssl, SSL3_MT_CLIENT_HELLO,
+ ssl_hash_message);
+ if (msg_ret <= 0) {
+ return msg_ret;
}
- /* fallthrough */
- case SSL3_ST_SR_CLNT_HELLO_B:
- case SSL3_ST_SR_CLNT_HELLO_C:
- if (!ssl_early_callback_init(ssl, &early_ctx, ssl->init_msg,
- ssl->init_num)) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
- goto f_err;
- }
- if (ssl->state == SSL3_ST_SR_CLNT_HELLO_B &&
- ssl->ctx->select_certificate_cb != NULL) {
- ssl->state = SSL3_ST_SR_CLNT_HELLO_C;
- switch (ssl->ctx->select_certificate_cb(&early_ctx)) {
- case 0:
- ssl->rwstate = SSL_CERTIFICATE_SELECTION_PENDING;
- goto err;
-
- case -1:
- /* Connection rejected. */
- al = SSL_AD_ACCESS_DENIED;
- OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
- goto f_err;
-
- default:
- /* fallthrough */;
- }
- }
- ssl->state = SSL3_ST_SR_CLNT_HELLO_C;
- break;
-
- default:
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
- return -1;
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_B;
}
- CBS_init(&client_hello, ssl->init_msg, ssl->init_num);
- if (!CBS_get_u16(&client_hello, &client_wire_version)) {
+ struct ssl_early_callback_ctx client_hello;
+ if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
+ ssl->init_num)) {
al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
- uint16_t client_version = ssl->method->version_from_wire(client_wire_version);
+ if (ssl->state == SSL3_ST_SR_CLNT_HELLO_B) {
+ /* Unlike other callbacks, the early callback is not run a second time if
+ * paused. */
+ ssl->state = SSL3_ST_SR_CLNT_HELLO_C;
- /* use version from inside client hello, not from record header (may differ:
- * see RFC 2246, Appendix E, second paragraph) */
- ssl->client_version = client_wire_version;
+ /* Run the early callback. */
+ if (ssl->ctx->select_certificate_cb != NULL) {
+ switch (ssl->ctx->select_certificate_cb(&client_hello)) {
+ case 0:
+ ssl->rwstate = SSL_CERTIFICATE_SELECTION_PENDING;
+ goto err;
+
+ case -1:
+ /* Connection rejected. */
+ al = SSL_AD_ACCESS_DENIED;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
+ goto f_err;
+
+ default:
+ /* fallthrough */;
+ }
+ }
+ }
+
+ uint16_t client_version =
+ ssl->method->version_from_wire(client_hello.version);
+ ssl->client_version = client_hello.version;
uint16_t min_version, max_version;
if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
@@ -642,30 +622,16 @@
return 1;
}
- if (!CBS_get_bytes(&client_hello, &client_random, SSL3_RANDOM_SIZE) ||
- !CBS_get_u8_length_prefixed(&client_hello, &session_id) ||
- CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto f_err;
- }
-
/* Load the client random. */
- memcpy(ssl->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE);
-
- if (SSL_is_dtls(ssl)) {
- CBS cookie;
-
- if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) ||
- CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto f_err;
- }
+ if (client_hello.random_len != SSL3_RANDOM_SIZE) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
+ memcpy(ssl->s3->client_random, client_hello.random, client_hello.random_len);
int send_new_ticket = 0;
- switch (ssl_get_prev_session(ssl, &session, &send_new_ticket, &early_ctx)) {
+ switch (
+ ssl_get_prev_session(ssl, &session, &send_new_ticket, &client_hello)) {
case ssl_session_success:
break;
case ssl_session_error:
@@ -683,7 +649,7 @@
CBS ems;
int have_extended_master_secret =
ssl->version != SSL3_VERSION &&
- ssl_early_callback_get_extension(&early_ctx, &ems,
+ ssl_early_callback_get_extension(&client_hello, &ems,
TLSEXT_TYPE_extended_master_secret) &&
CBS_len(&ems) == 0;
@@ -725,24 +691,14 @@
}
if (ssl->ctx->dos_protection_cb != NULL &&
- ssl->ctx->dos_protection_cb(&early_ctx) == 0) {
+ ssl->ctx->dos_protection_cb(&client_hello) == 0) {
/* Connection rejected for DOS reasons. */
al = SSL_AD_ACCESS_DENIED;
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
goto f_err;
}
- if (!CBS_get_u16_length_prefixed(&client_hello, &cipher_suites) ||
- CBS_len(&cipher_suites) == 0 ||
- CBS_len(&cipher_suites) % 2 != 0 ||
- !CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
- CBS_len(&compression_methods) == 0) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto f_err;
- }
-
- ciphers = ssl_bytes_to_cipher_list(ssl, &cipher_suites, max_version);
+ ciphers = ssl_parse_client_cipher_list(ssl, &client_hello, max_version);
if (ciphers == NULL) {
goto err;
}
@@ -771,28 +727,19 @@
}
/* Only null compression is supported. */
- if (memchr(CBS_data(&compression_methods), 0,
- CBS_len(&compression_methods)) == NULL) {
+ if (memchr(client_hello.compression_methods, 0,
+ client_hello.compression_methods_len) == NULL) {
al = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMPRESSION_SPECIFIED);
goto f_err;
}
/* TLS extensions. */
- if (ssl->version >= SSL3_VERSION &&
- !ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
+ if (!ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
goto err;
}
- /* There should be nothing left over in the record. */
- if (CBS_len(&client_hello) != 0) {
- /* wrong packet length */
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
- goto f_err;
- }
-
if (have_extended_master_secret != ssl->s3->tmp.extended_master_secret) {
al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_EMS_STATE_INCONSISTENT);
diff --git a/ssl/internal.h b/ssl/internal.h
index f64dc62..77759e4 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -958,6 +958,20 @@
size_t secret_len);
+/* ClientHello functions. */
+
+int ssl_early_callback_init(SSL *ssl, struct ssl_early_callback_ctx *ctx,
+ const uint8_t *in, size_t in_len);
+
+int ssl_early_callback_get_extension(const struct ssl_early_callback_ctx *ctx,
+ CBS *out, uint16_t extension_type);
+
+STACK_OF(SSL_CIPHER) *
+ ssl_parse_client_cipher_list(SSL *ssl,
+ const struct ssl_early_callback_ctx *ctx,
+ uint16_t max_version);
+
+
/* Underdocumented functions.
*
* Functions below here haven't been touched up and may be underdocumented. */
@@ -1239,8 +1253,6 @@
OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session,
int include_ticket);
-STACK_OF(SSL_CIPHER) *
- ssl_bytes_to_cipher_list(SSL *ssl, const CBS *cbs, uint16_t max_version);
void ssl_cipher_preference_list_free(
struct ssl_cipher_preference_list_st *cipher_list);
struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *ssl);
@@ -1370,12 +1382,6 @@
int tls1_generate_master_secret(SSL *ssl, uint8_t *out, const uint8_t *premaster,
size_t premaster_len);
-int ssl_early_callback_init(SSL *ssl, struct ssl_early_callback_ctx *ctx,
- const uint8_t *in, size_t in_len);
-
-int ssl_early_callback_get_extension(const struct ssl_early_callback_ctx *ctx,
- CBS *out, uint16_t extension_type);
-
/* tls1_get_grouplist sets |*out_group_ids| and |*out_group_ids_len| to the
* list of allowed group IDs. If |get_peer_groups| is non-zero, return the
* peer's group list. Otherwise, return the preferred list. */
@@ -1412,7 +1418,8 @@
int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len);
int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out);
-int ssl_parse_clienthello_tlsext(SSL *ssl, CBS *cbs);
+int ssl_parse_clienthello_tlsext(
+ SSL *ssl, const struct ssl_early_callback_ctx *client_hello);
int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs);
#define tlsext_tick_md EVP_sha256
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 6a2dae8..04477e5 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1630,21 +1630,15 @@
}
STACK_OF(SSL_CIPHER) *
- ssl_bytes_to_cipher_list(SSL *ssl, const CBS *cbs, uint16_t max_version) {
- CBS cipher_suites = *cbs;
- const SSL_CIPHER *c;
- STACK_OF(SSL_CIPHER) *sk;
+ ssl_parse_client_cipher_list(SSL *ssl,
+ const struct ssl_early_callback_ctx *ctx,
+ uint16_t max_version) {
+ CBS cipher_suites;
+ CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
- if (ssl->s3) {
- ssl->s3->send_connection_binding = 0;
- }
+ ssl->s3->send_connection_binding = 0;
- if (CBS_len(&cipher_suites) % 2 != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
- return NULL;
- }
-
- sk = sk_SSL_CIPHER_new_null();
+ STACK_OF(SSL_CIPHER) *sk = sk_SSL_CIPHER_new_null();
if (sk == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1654,7 +1648,7 @@
uint16_t cipher_suite;
if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
goto err;
}
@@ -1680,7 +1674,7 @@
continue;
}
- c = SSL_get_cipher_by_value(cipher_suite);
+ const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite);
if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 695f081..64b2dac 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -209,43 +209,39 @@
ctx->client_hello = in;
ctx->client_hello_len = in_len;
- CBS client_hello, session_id, cipher_suites, compression_methods, extensions;
+ CBS client_hello, random, session_id;
CBS_init(&client_hello, ctx->client_hello, ctx->client_hello_len);
-
- if (/* Skip client version. */
- !CBS_skip(&client_hello, 2) ||
- /* Skip client nonce. */
- !CBS_skip(&client_hello, 32) ||
- /* Extract session_id. */
- !CBS_get_u8_length_prefixed(&client_hello, &session_id)) {
+ if (!CBS_get_u16(&client_hello, &ctx->version) ||
+ !CBS_get_bytes(&client_hello, &random, SSL3_RANDOM_SIZE) ||
+ !CBS_get_u8_length_prefixed(&client_hello, &session_id) ||
+ CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
return 0;
}
+ ctx->random = CBS_data(&random);
+ ctx->random_len = CBS_len(&random);
ctx->session_id = CBS_data(&session_id);
ctx->session_id_len = CBS_len(&session_id);
/* Skip past DTLS cookie */
if (SSL_is_dtls(ctx->ssl)) {
CBS cookie;
-
- if (!CBS_get_u8_length_prefixed(&client_hello, &cookie)) {
+ if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) ||
+ CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) {
return 0;
}
}
- /* Extract cipher_suites. */
+ CBS cipher_suites, compression_methods;
if (!CBS_get_u16_length_prefixed(&client_hello, &cipher_suites) ||
- CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0) {
- return 0;
- }
- ctx->cipher_suites = CBS_data(&cipher_suites);
- ctx->cipher_suites_len = CBS_len(&cipher_suites);
-
- /* Extract compression_methods. */
- if (!CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
+ CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0 ||
+ !CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
CBS_len(&compression_methods) < 1) {
return 0;
}
+
+ ctx->cipher_suites = CBS_data(&cipher_suites);
+ ctx->cipher_suites_len = CBS_len(&cipher_suites);
ctx->compression_methods = CBS_data(&compression_methods);
ctx->compression_methods_len = CBS_len(&compression_methods);
@@ -258,11 +254,13 @@
}
/* Extract extensions and check it is valid. */
+ CBS extensions;
if (!CBS_get_u16_length_prefixed(&client_hello, &extensions) ||
!tls1_check_duplicate_extensions(&extensions) ||
CBS_len(&client_hello) != 0) {
return 0;
}
+
ctx->extensions = CBS_data(&extensions);
ctx->extensions_len = CBS_len(&extensions);
@@ -2512,7 +2510,9 @@
return 0;
}
-static int ssl_scan_clienthello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
+static int ssl_scan_clienthello_tlsext(
+ SSL *ssl, const struct ssl_early_callback_ctx *client_hello,
+ int *out_alert) {
size_t i;
for (i = 0; i < kNumExtensions; i++) {
if (kExtensions[i].init != NULL) {
@@ -2527,53 +2527,44 @@
* sent as an SCSV. */
assert(kExtensions[0].value == TLSEXT_TYPE_renegotiate);
- /* There may be no extensions. */
- if (CBS_len(cbs) != 0) {
- /* Decode the extensions block and check it is valid. */
- CBS extensions;
- if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
- !tls1_check_duplicate_extensions(&extensions)) {
+ CBS extensions;
+ CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
+ while (CBS_len(&extensions) != 0) {
+ uint16_t type;
+ CBS extension;
+
+ /* Decode the next extension. */
+ if (!CBS_get_u16(&extensions, &type) ||
+ !CBS_get_u16_length_prefixed(&extensions, &extension)) {
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
- while (CBS_len(&extensions) != 0) {
- uint16_t type;
- CBS extension;
+ /* RFC 5746 made the existence of extensions in SSL 3.0 somewhat
+ * ambiguous. Ignore all but the renegotiation_info extension. */
+ if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) {
+ continue;
+ }
- /* Decode the next extension. */
- if (!CBS_get_u16(&extensions, &type) ||
- !CBS_get_u16_length_prefixed(&extensions, &extension)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ unsigned ext_index;
+ const struct tls_extension *const ext =
+ tls_extension_find(&ext_index, type);
- /* RFC 5746 made the existence of extensions in SSL 3.0 somewhat
- * ambiguous. Ignore all but the renegotiation_info extension. */
- if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) {
- continue;
- }
-
- unsigned ext_index;
- const struct tls_extension *const ext =
- tls_extension_find(&ext_index, type);
-
- if (ext == NULL) {
- if (!custom_ext_parse_clienthello(ssl, out_alert, type, &extension)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
- return 0;
- }
- continue;
- }
-
- ssl->s3->tmp.extensions.received |= (1u << ext_index);
- uint8_t alert = SSL_AD_DECODE_ERROR;
- if (!ext->parse_clienthello(ssl, &alert, &extension)) {
- *out_alert = alert;
+ if (ext == NULL) {
+ if (!custom_ext_parse_clienthello(ssl, out_alert, type, &extension)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
- ERR_add_error_dataf("extension: %u", (unsigned)type);
return 0;
}
+ continue;
+ }
+
+ ssl->s3->tmp.extensions.received |= (1u << ext_index);
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!ext->parse_clienthello(ssl, &alert, &extension)) {
+ *out_alert = alert;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)type);
+ return 0;
}
}
@@ -2594,9 +2585,10 @@
return 1;
}
-int ssl_parse_clienthello_tlsext(SSL *ssl, CBS *cbs) {
+int ssl_parse_clienthello_tlsext(
+ SSL *ssl, const struct ssl_early_callback_ctx *client_hello) {
int alert = -1;
- if (ssl_scan_clienthello_tlsext(ssl, cbs, &alert) <= 0) {
+ if (ssl_scan_clienthello_tlsext(ssl, client_hello, &alert) <= 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c
index 1ece104..96ceb79 100644
--- a/ssl/tls13_server.c
+++ b/ssl/tls13_server.c
@@ -105,36 +105,22 @@
return ssl_hs_error;
}
- struct ssl_early_callback_ctx early_ctx;
- if (!ssl_early_callback_init(ssl, &early_ctx, ssl->init_msg,
+ struct ssl_early_callback_ctx client_hello;
+ if (!ssl_early_callback_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;
}
- CBS cbs, client_random, session_id, cipher_suites, compression_methods;
- uint16_t client_wire_version;
- CBS_init(&cbs, ssl->init_msg, ssl->init_num);
- if (!CBS_get_u16(&cbs, &client_wire_version) ||
- !CBS_get_bytes(&cbs, &client_random, SSL3_RANDOM_SIZE) ||
- !CBS_get_u8_length_prefixed(&cbs, &session_id) ||
- CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- return ssl_hs_error;
- }
-
- uint16_t min_version, max_version;
- if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
- }
-
assert(ssl->s3->have_version);
/* Load the client random. */
- memcpy(ssl->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE);
+ if (client_hello.random_len != SSL3_RANDOM_SIZE) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ memcpy(ssl->s3->client_random, client_hello.random, client_hello.random_len);
SSL_set_session(ssl, NULL);
if (!ssl_get_new_session(ssl, 1 /* server */)) {
@@ -143,44 +129,27 @@
}
if (ssl->ctx->dos_protection_cb != NULL &&
- ssl->ctx->dos_protection_cb(&early_ctx) == 0) {
+ ssl->ctx->dos_protection_cb(&client_hello) == 0) {
/* Connection rejected for DOS reasons. */
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ACCESS_DENIED);
return ssl_hs_error;
}
- if (!CBS_get_u16_length_prefixed(&cbs, &cipher_suites) ||
- CBS_len(&cipher_suites) == 0 ||
- CBS_len(&cipher_suites) % 2 != 0 ||
- !CBS_get_u8_length_prefixed(&cbs, &compression_methods) ||
- CBS_len(&compression_methods) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- return ssl_hs_error;
- }
-
/* TLS 1.3 requires the peer only advertise the null compression. */
- if (CBS_len(&compression_methods) != 1 ||
- CBS_data(&compression_methods)[0] != 0) {
+ if (client_hello.compression_methods_len != 1 ||
+ client_hello.compression_methods[0] != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
/* TLS extensions. */
- if (!ssl_parse_clienthello_tlsext(ssl, &cbs)) {
+ if (!ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
return ssl_hs_error;
}
- /* There should be nothing left over in the message. */
- if (CBS_len(&cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- return ssl_hs_error;
- }
-
/* Let cert callback update server certificates if required.
*
* TODO(davidben): Can this get run earlier? */
@@ -197,8 +166,14 @@
}
}
+ uint16_t min_version, max_version;
+ if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+
STACK_OF(SSL_CIPHER) *ciphers =
- ssl_bytes_to_cipher_list(ssl, &cipher_suites, max_version);
+ ssl_parse_client_cipher_list(ssl, &client_hello, max_version);
if (ciphers == NULL) {
return ssl_hs_error;
}
@@ -232,7 +207,7 @@
/* Resolve ECDHE and incorporate it into the secret. */
int need_retry;
- if (!resolve_ecdhe_secret(ssl, &need_retry, &early_ctx)) {
+ if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
if (need_retry) {
hs->state = state_send_hello_retry_request;
return ssl_hs_ok;
@@ -276,8 +251,8 @@
return ssl_hs_error;
}
- struct ssl_early_callback_ctx early_ctx;
- if (!ssl_early_callback_init(ssl, &early_ctx, ssl->init_msg,
+ struct ssl_early_callback_ctx client_hello;
+ if (!ssl_early_callback_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);
@@ -285,7 +260,7 @@
}
int need_retry;
- if (!resolve_ecdhe_secret(ssl, &need_retry, &early_ctx)) {
+ if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
if (need_retry) {
/* Only send one HelloRetryRequest. */
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);