Move extensions bitmasks into SSL_HANDSHAKE.
Change-Id: I3ab30a44b7f90ef1159e022cd17b7f50ffe27a93 Reviewed-on: https://boringssl-review.googlesource.com/11522 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
committed by
Adam Langley
parent
a048678cd6
commit
f5d2cd0808
@@ -4337,27 +4337,6 @@ typedef struct ssl3_state_st {
|
||||
|
||||
int reuse_message;
|
||||
|
||||
union {
|
||||
/* sent is a bitset where the bits correspond to elements of kExtensions
|
||||
* in t1_lib.c. Each bit is set if that extension was sent in a
|
||||
* ClientHello. It's not used by servers. */
|
||||
uint32_t sent;
|
||||
/* received is a bitset, like |sent|, but is used by servers to record
|
||||
* which extensions were received from a client. */
|
||||
uint32_t received;
|
||||
} extensions;
|
||||
|
||||
union {
|
||||
/* sent is a bitset where the bits correspond to elements of
|
||||
* |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
|
||||
* extension was sent in a ClientHello. It's not used by servers. */
|
||||
uint16_t sent;
|
||||
/* received is a bitset, like |sent|, but is used by servers to record
|
||||
* which custom extensions were received from a client. The bits here
|
||||
* correspond to |server_custom_extensions|. */
|
||||
uint16_t received;
|
||||
} custom_extensions;
|
||||
|
||||
uint8_t *key_block;
|
||||
uint8_t key_block_length;
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ static int custom_ext_add_hello(SSL *ssl, CBB *extensions) {
|
||||
const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
|
||||
|
||||
if (ssl->server &&
|
||||
!(ssl->s3->tmp.custom_extensions.received & (1u << i))) {
|
||||
!(ssl->s3->hs->custom_extensions.received & (1u << i))) {
|
||||
/* Servers cannot echo extensions that the client didn't send. */
|
||||
continue;
|
||||
}
|
||||
@@ -102,8 +102,8 @@ static int custom_ext_add_hello(SSL *ssl, CBB *extensions) {
|
||||
}
|
||||
|
||||
if (!ssl->server) {
|
||||
assert((ssl->s3->tmp.custom_extensions.sent & (1u << i)) == 0);
|
||||
ssl->s3->tmp.custom_extensions.sent |= (1u << i);
|
||||
assert((ssl->s3->hs->custom_extensions.sent & (1u << i)) == 0);
|
||||
ssl->s3->hs->custom_extensions.sent |= (1u << i);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -134,7 +134,7 @@ int custom_ext_parse_serverhello(SSL *ssl, int *out_alert, uint16_t value,
|
||||
if (/* Unknown extensions are not allowed in a ServerHello. */
|
||||
ext == NULL ||
|
||||
/* Also, if we didn't send the extension, that's also unacceptable. */
|
||||
!(ssl->s3->tmp.custom_extensions.sent & (1u << index))) {
|
||||
!(ssl->s3->hs->custom_extensions.sent & (1u << index))) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
|
||||
ERR_add_error_dataf("extension: %u", (unsigned)value);
|
||||
*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
|
||||
@@ -162,8 +162,8 @@ int custom_ext_parse_clienthello(SSL *ssl, int *out_alert, uint16_t value,
|
||||
return 1;
|
||||
}
|
||||
|
||||
assert((ssl->s3->tmp.custom_extensions.received & (1u << index)) == 0);
|
||||
ssl->s3->tmp.custom_extensions.received |= (1u << index);
|
||||
assert((ssl->s3->hs->custom_extensions.received & (1u << index)) == 0);
|
||||
ssl->s3->hs->custom_extensions.received |= (1u << index);
|
||||
|
||||
if (ext->parse_callback &&
|
||||
!ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
|
||||
@@ -184,7 +184,7 @@ int custom_ext_add_serverhello(SSL *ssl, CBB *extensions) {
|
||||
* can be set on an |SSL_CTX|. It's determined by the size of the bitset used
|
||||
* to track when an extension has been sent. */
|
||||
#define MAX_NUM_CUSTOM_EXTENSIONS \
|
||||
(sizeof(((struct ssl3_state_st *)NULL)->tmp.custom_extensions.sent) * 8)
|
||||
(sizeof(((SSL_HANDSHAKE *)NULL)->custom_extensions.sent) * 8)
|
||||
|
||||
static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack,
|
||||
unsigned extension_value,
|
||||
|
||||
@@ -898,6 +898,27 @@ struct ssl_handshake_st {
|
||||
uint8_t secret[EVP_MAX_MD_SIZE];
|
||||
uint8_t traffic_secret_0[EVP_MAX_MD_SIZE];
|
||||
|
||||
union {
|
||||
/* sent is a bitset where the bits correspond to elements of kExtensions
|
||||
* in t1_lib.c. Each bit is set if that extension was sent in a
|
||||
* ClientHello. It's not used by servers. */
|
||||
uint32_t sent;
|
||||
/* received is a bitset, like |sent|, but is used by servers to record
|
||||
* which extensions were received from a client. */
|
||||
uint32_t received;
|
||||
} extensions;
|
||||
|
||||
union {
|
||||
/* sent is a bitset where the bits correspond to elements of
|
||||
* |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
|
||||
* extension was sent in a ClientHello. It's not used by servers. */
|
||||
uint16_t sent;
|
||||
/* received is a bitset, like |sent|, but is used by servers to record
|
||||
* which custom extensions were received from a client. The bits here
|
||||
* correspond to |server_custom_extensions|. */
|
||||
uint16_t received;
|
||||
} custom_extensions;
|
||||
|
||||
/* ecdh_ctx is the active client ECDH offer in TLS 1.3. */
|
||||
SSL_ECDH_CTX ecdh_ctx;
|
||||
|
||||
|
||||
+14
-15
@@ -2604,12 +2604,11 @@ static const struct tls_extension kExtensions[] = {
|
||||
#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
|
||||
|
||||
OPENSSL_COMPILE_ASSERT(kNumExtensions <=
|
||||
sizeof(((SSL *)NULL)->s3->tmp.extensions.sent) * 8,
|
||||
sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8,
|
||||
too_many_extensions_for_sent_bitset);
|
||||
OPENSSL_COMPILE_ASSERT(kNumExtensions <=
|
||||
sizeof(((SSL *)NULL)->s3->tmp.extensions.received) *
|
||||
8,
|
||||
too_many_extensions_for_received_bitset);
|
||||
OPENSSL_COMPILE_ASSERT(
|
||||
kNumExtensions <= sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8,
|
||||
too_many_extensions_for_received_bitset);
|
||||
|
||||
static const struct tls_extension *tls_extension_find(uint32_t *out_index,
|
||||
uint16_t value) {
|
||||
@@ -2642,8 +2641,8 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ssl->s3->tmp.extensions.sent = 0;
|
||||
ssl->s3->tmp.custom_extensions.sent = 0;
|
||||
ssl->s3->hs->extensions.sent = 0;
|
||||
ssl->s3->hs->custom_extensions.sent = 0;
|
||||
|
||||
for (size_t i = 0; i < kNumExtensions; i++) {
|
||||
if (kExtensions[i].init != NULL) {
|
||||
@@ -2670,7 +2669,7 @@ int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
|
||||
}
|
||||
|
||||
if (CBB_len(&extensions) != len_before) {
|
||||
ssl->s3->tmp.extensions.sent |= (1u << i);
|
||||
ssl->s3->hs->extensions.sent |= (1u << i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2745,7 +2744,7 @@ int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) {
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < kNumExtensions; i++) {
|
||||
if (!(ssl->s3->tmp.extensions.received & (1u << i))) {
|
||||
if (!(ssl->s3->hs->extensions.received & (1u << i))) {
|
||||
/* Don't send extensions that were not received. */
|
||||
continue;
|
||||
}
|
||||
@@ -2783,8 +2782,8 @@ static int ssl_scan_clienthello_tlsext(
|
||||
}
|
||||
}
|
||||
|
||||
ssl->s3->tmp.extensions.received = 0;
|
||||
ssl->s3->tmp.custom_extensions.received = 0;
|
||||
ssl->s3->hs->extensions.received = 0;
|
||||
ssl->s3->hs->custom_extensions.received = 0;
|
||||
|
||||
CBS extensions;
|
||||
CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
|
||||
@@ -2817,7 +2816,7 @@ static int ssl_scan_clienthello_tlsext(
|
||||
continue;
|
||||
}
|
||||
|
||||
ssl->s3->tmp.extensions.received |= (1u << ext_index);
|
||||
ssl->s3->hs->extensions.received |= (1u << ext_index);
|
||||
uint8_t alert = SSL_AD_DECODE_ERROR;
|
||||
if (!ext->parse_clienthello(ssl, &alert, &extension)) {
|
||||
*out_alert = alert;
|
||||
@@ -2828,7 +2827,7 @@ static int ssl_scan_clienthello_tlsext(
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kNumExtensions; i++) {
|
||||
if (ssl->s3->tmp.extensions.received & (1u << i)) {
|
||||
if (ssl->s3->hs->extensions.received & (1u << i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2842,7 +2841,7 @@ static int ssl_scan_clienthello_tlsext(
|
||||
CBS_init(&fake_contents, kFakeRenegotiateExtension,
|
||||
sizeof(kFakeRenegotiateExtension));
|
||||
contents = &fake_contents;
|
||||
ssl->s3->tmp.extensions.received |= (1u << i);
|
||||
ssl->s3->hs->extensions.received |= (1u << i);
|
||||
}
|
||||
|
||||
/* Extension wasn't observed so call the callback with a NULL
|
||||
@@ -2914,7 +2913,7 @@ static int ssl_scan_serverhello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(ssl->s3->tmp.extensions.sent & (1u << ext_index)) &&
|
||||
if (!(ssl->s3->hs->extensions.sent & (1u << ext_index)) &&
|
||||
type != TLSEXT_TYPE_renegotiate) {
|
||||
/* If the extension was never sent then it is illegal, except for the
|
||||
* renegotiation extension which, in SSL 3.0, is signaled via SCSV. */
|
||||
|
||||
Reference in New Issue
Block a user