Remove begin_handshake and allocate init_buf lazily.
For TLS 1.3, we will need to process more complex post-handshake messages. It is simplest if we use the same mechanism. In preparation, allow ssl3_get_message to be called at any point. Note that this stops reserving SSL3_RT_MAX_PLAIN_LENGTH in init_buf right off the bat. Instead it will grow as-needed to accomodate the handshake. SSL3_RT_MAX_PLAIN_LENGTH is rather larger than we probably need to receive, particularly as a server, so this seems a good plan. BUG=83 Change-Id: Id7f4024afc4c8a713b46b0d1625432315594350e Reviewed-on: https://boringssl-review.googlesource.com/8985 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>
This commit is contained in:
parent
7baf681a8b
commit
481b9d2047
@ -92,10 +92,6 @@ static uint16_t dtls1_version_to_wire(uint16_t version) {
|
|||||||
return ~(version - 0x0201);
|
return ~(version - 0x0201);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dtls1_begin_handshake(SSL *ssl) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dtls1_finish_handshake(SSL *ssl) {
|
static void dtls1_finish_handshake(SSL *ssl) {
|
||||||
ssl->d1->handshake_read_seq = 0;
|
ssl->d1->handshake_read_seq = 0;
|
||||||
ssl->d1->handshake_write_seq = 0;
|
ssl->d1->handshake_write_seq = 0;
|
||||||
@ -141,7 +137,6 @@ static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = {
|
|||||||
dtls1_version_to_wire,
|
dtls1_version_to_wire,
|
||||||
dtls1_new,
|
dtls1_new,
|
||||||
dtls1_free,
|
dtls1_free,
|
||||||
dtls1_begin_handshake,
|
|
||||||
dtls1_finish_handshake,
|
dtls1_finish_handshake,
|
||||||
dtls1_get_message,
|
dtls1_get_message,
|
||||||
dtls1_hash_current_message,
|
dtls1_hash_current_message,
|
||||||
|
@ -201,8 +201,7 @@ int ssl3_connect(SSL *ssl) {
|
|||||||
ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1);
|
ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1);
|
||||||
|
|
||||||
ssl->s3->hs = ssl_handshake_new(tls13_client_handshake);
|
ssl->s3->hs = ssl_handshake_new(tls13_client_handshake);
|
||||||
if (ssl->s3->hs == NULL ||
|
if (ssl->s3->hs == NULL) {
|
||||||
!ssl->method->begin_handshake(ssl)) {
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -202,8 +202,7 @@ int ssl3_accept(SSL *ssl) {
|
|||||||
ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1);
|
ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1);
|
||||||
|
|
||||||
ssl->s3->hs = ssl_handshake_new(tls13_server_handshake);
|
ssl->s3->hs = ssl_handshake_new(tls13_server_handshake);
|
||||||
if (ssl->s3->hs == NULL ||
|
if (ssl->s3->hs == NULL) {
|
||||||
!ssl->method->begin_handshake(ssl)) {
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -1039,9 +1039,6 @@ struct ssl_protocol_method_st {
|
|||||||
uint16_t (*version_to_wire)(uint16_t version);
|
uint16_t (*version_to_wire)(uint16_t version);
|
||||||
int (*ssl_new)(SSL *ssl);
|
int (*ssl_new)(SSL *ssl);
|
||||||
void (*ssl_free)(SSL *ssl);
|
void (*ssl_free)(SSL *ssl);
|
||||||
/* begin_handshake is called to start a new handshake. It returns one on
|
|
||||||
* success and zero on error. */
|
|
||||||
int (*begin_handshake)(SSL *ssl);
|
|
||||||
/* finish_handshake is called when a handshake completes. */
|
/* finish_handshake is called when a handshake completes. */
|
||||||
void (*finish_handshake)(SSL *ssl);
|
void (*finish_handshake)(SSL *ssl);
|
||||||
/* ssl_get_message reads the next handshake message. If |msg_type| is not -1,
|
/* ssl_get_message reads the next handshake message. If |msg_type| is not -1,
|
||||||
|
@ -456,8 +456,15 @@ static int read_v2_client_hello(SSL *ssl) {
|
|||||||
rand_len);
|
rand_len);
|
||||||
|
|
||||||
/* Write out an equivalent SSLv3 ClientHello. */
|
/* Write out an equivalent SSLv3 ClientHello. */
|
||||||
|
size_t max_v3_client_hello = SSL3_HM_HEADER_LENGTH + 2 /* version */ +
|
||||||
|
SSL3_RANDOM_SIZE + 1 /* session ID length */ +
|
||||||
|
2 /* cipher list length */ +
|
||||||
|
CBS_len(&cipher_specs) / 3 * 2 +
|
||||||
|
1 /* compression length */ + 1 /* compression */;
|
||||||
CBB client_hello, hello_body, cipher_suites;
|
CBB client_hello, hello_body, cipher_suites;
|
||||||
if (!CBB_init_fixed(&client_hello, (uint8_t *)ssl->init_buf->data,
|
CBB_zero(&client_hello);
|
||||||
|
if (!BUF_MEM_reserve(ssl->init_buf, max_v3_client_hello) ||
|
||||||
|
!CBB_init_fixed(&client_hello, (uint8_t *)ssl->init_buf->data,
|
||||||
ssl->init_buf->max) ||
|
ssl->init_buf->max) ||
|
||||||
!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
|
!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
|
||||||
!CBB_add_u24_length_prefixed(&client_hello, &hello_body) ||
|
!CBB_add_u24_length_prefixed(&client_hello, &hello_body) ||
|
||||||
@ -512,6 +519,14 @@ static int read_v2_client_hello(SSL *ssl) {
|
|||||||
int ssl3_get_message(SSL *ssl, int msg_type,
|
int ssl3_get_message(SSL *ssl, int msg_type,
|
||||||
enum ssl_hash_message_t hash_message) {
|
enum ssl_hash_message_t hash_message) {
|
||||||
again:
|
again:
|
||||||
|
/* Re-create the handshake buffer if needed. */
|
||||||
|
if (ssl->init_buf == NULL) {
|
||||||
|
ssl->init_buf = BUF_MEM_new();
|
||||||
|
if (ssl->init_buf == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ssl->server && !ssl->s3->v2_hello_done) {
|
if (ssl->server && !ssl->s3->v2_hello_done) {
|
||||||
/* Bypass the record layer for the first message to handle V2ClientHello. */
|
/* Bypass the record layer for the first message to handle V2ClientHello. */
|
||||||
assert(hash_message == ssl_hash_message);
|
assert(hash_message == ssl_hash_message);
|
||||||
|
@ -69,21 +69,6 @@ static uint16_t ssl3_version_from_wire(uint16_t wire_version) {
|
|||||||
|
|
||||||
static uint16_t ssl3_version_to_wire(uint16_t version) { return version; }
|
static uint16_t ssl3_version_to_wire(uint16_t version) { return version; }
|
||||||
|
|
||||||
static int ssl3_begin_handshake(SSL *ssl) {
|
|
||||||
if (ssl->init_buf != NULL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
BUF_MEM *buf = BUF_MEM_new();
|
|
||||||
if (buf == NULL || !BUF_MEM_reserve(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
|
|
||||||
BUF_MEM_free(buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssl->init_buf = buf;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ssl3_finish_handshake(SSL *ssl) {
|
static void ssl3_finish_handshake(SSL *ssl) {
|
||||||
BUF_MEM_free(ssl->init_buf);
|
BUF_MEM_free(ssl->init_buf);
|
||||||
ssl->init_buf = NULL;
|
ssl->init_buf = NULL;
|
||||||
@ -125,7 +110,6 @@ static const SSL_PROTOCOL_METHOD kTLSProtocolMethod = {
|
|||||||
ssl3_version_to_wire,
|
ssl3_version_to_wire,
|
||||||
ssl3_new,
|
ssl3_new,
|
||||||
ssl3_free,
|
ssl3_free,
|
||||||
ssl3_begin_handshake,
|
|
||||||
ssl3_finish_handshake,
|
ssl3_finish_handshake,
|
||||||
ssl3_get_message,
|
ssl3_get_message,
|
||||||
ssl3_hash_current_message,
|
ssl3_hash_current_message,
|
||||||
|
Loading…
Reference in New Issue
Block a user