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:
David Benjamin
2016-10-09 16:48:52 +00:00
committed by Adam Langley
parent a048678cd6
commit f5d2cd0808
4 changed files with 42 additions and 43 deletions
-21
View File
@@ -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;
+7 -7
View File
@@ -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,
+21
View File
@@ -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
View File
@@ -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. */