Use the record-layer buffer for sniffing V2ClientHellos.

I'm not sure why I made a separate one. (Not quite how the V2ClientHello
code will look in the buffer-free API yet. Probably the future
refactored SSL_HANDSHAKE gadget will need separate entry points to
consume a handshake message or V2ClientHello and the driver deals with
framing.)

This also means that ssl3_setup_read_buffer is never called external to
ssl3_read_n.

BUG=468889

Change-Id: I872f1188270968bf53ee9d0488a761c772a11e9e
Reviewed-on: https://boringssl-review.googlesource.com/5713
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2015-07-24 23:24:12 -04:00 committed by Adam Langley
parent 97760d5254
commit 45c6c3e8ef
3 changed files with 25 additions and 64 deletions

View File

@ -363,11 +363,6 @@ typedef struct ssl3_state_st {
* completed. */
char initial_handshake_complete;
/* sniff_buffer is used by the server in the initial handshake to read a
* V2ClientHello before the record layer is initialized. */
BUF_MEM *sniff_buffer;
size_t sniff_buffer_len;
SSL3_BUFFER rbuf; /* read IO goes into here */
SSL3_BUFFER wbuf; /* write IO goes into here */

View File

@ -223,7 +223,6 @@ void ssl3_free(SSL *s) {
return;
}
BUF_MEM_free(s->s3->sniff_buffer);
ssl3_cleanup_key_block(s);
ssl3_release_read_buffer(s);
ssl3_release_write_buffer(s);

View File

@ -589,42 +589,15 @@ end:
return ret;
}
static int ssl3_read_sniff_buffer(SSL *s, size_t n) {
if (s->s3->sniff_buffer == NULL) {
s->s3->sniff_buffer = BUF_MEM_new();
}
if (s->s3->sniff_buffer == NULL || !BUF_MEM_grow(s->s3->sniff_buffer, n)) {
return -1;
}
while (s->s3->sniff_buffer_len < n) {
int ret;
s->rwstate = SSL_READING;
ret = BIO_read(s->rbio, s->s3->sniff_buffer->data + s->s3->sniff_buffer_len,
n - s->s3->sniff_buffer_len);
if (ret <= 0) {
return ret;
}
s->rwstate = SSL_NOTHING;
s->s3->sniff_buffer_len += ret;
}
return 1;
}
int ssl3_get_initial_bytes(SSL *s) {
int ret;
const uint8_t *p;
/* Read the first 8 bytes. To recognize a V2ClientHello only needs the first 4
* bytes, but 8 is needed to recognize CONNECT below. */
ret = ssl3_read_sniff_buffer(s, INITIAL_SNIFF_BUFFER_SIZE);
int ret = ssl3_read_n(s, INITIAL_SNIFF_BUFFER_SIZE, 0 /* new packet */);
if (ret <= 0) {
return ret;
}
assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
p = (const uint8_t *)s->s3->sniff_buffer->data;
assert(s->packet_length == INITIAL_SNIFF_BUFFER_SIZE);
const uint8_t *p = s->packet;
/* Some dedicated error codes for protocol mixups should the application wish
* to interpret them differently. (These do not overlap with ClientHello or
@ -649,23 +622,15 @@ int ssl3_get_initial_bytes(SSL *s) {
return 1;
}
/* Fall through to the standard logic. Initialize the record layer with the
* already consumed data and continue the handshake. */
if (!ssl3_setup_read_buffer(s)) {
return -1;
}
/* Fall through to the standard logic. Unread what's been read to re-process
* it. */
assert(s->rstate == SSL_ST_READ_HEADER);
/* There cannot have already been data in the record layer. */
assert(s->s3->rbuf.left == 0);
memcpy(s->s3->rbuf.buf, p, s->s3->sniff_buffer_len);
s->s3->rbuf.offset = 0;
s->s3->rbuf.left = s->s3->sniff_buffer_len;
assert(s->s3->rbuf.offset >= INITIAL_SNIFF_BUFFER_SIZE);
s->s3->rbuf.offset -= INITIAL_SNIFF_BUFFER_SIZE;
s->s3->rbuf.left += INITIAL_SNIFF_BUFFER_SIZE;
s->packet = NULL;
s->packet_length = 0;
BUF_MEM_free(s->s3->sniff_buffer);
s->s3->sniff_buffer = NULL;
s->s3->sniff_buffer_len = 0;
s->state = SSL3_ST_SR_CLNT_HELLO_A;
return 1;
}
@ -680,29 +645,31 @@ int ssl3_get_v2_client_hello(SSL *s) {
CBB client_hello, hello_body, cipher_suites;
uint8_t random[SSL3_RANDOM_SIZE];
/* Read the remainder of the V2ClientHello. We have previously read 8 bytes
* in ssl3_get_initial_bytes. */
assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
p = (const uint8_t *)s->s3->sniff_buffer->data;
/* Determine the length of the V2ClientHello. */
assert(s->packet_length >= INITIAL_SNIFF_BUFFER_SIZE);
p = (const uint8_t *)s->packet;
msg_length = ((p[0] & 0x7f) << 8) | p[1];
if (msg_length > (1024 * 4)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return -1;
}
if (msg_length < INITIAL_SNIFF_BUFFER_SIZE - 2) {
/* Reject lengths that are too short early. We have already read 8 bytes,
* so we should not attempt to process an (invalid) V2ClientHello which
* would be shorter than that. */
/* Reject lengths that are too short early. We have already read
* |INITIAL_SNIFF_BUFFER_SIZE| bytes, so we should not attempt to process an
* (invalid) V2ClientHello which would be shorter than that. */
OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH);
return -1;
}
ret = ssl3_read_sniff_buffer(s, msg_length + 2);
/* Read the remainder of the V2ClientHello. We have previously read
* |INITIAL_SNIFF_BUFFER_SIZE| bytes in ssl3_get_initial_bytes. */
ret = ssl3_read_n(s, msg_length - (INITIAL_SNIFF_BUFFER_SIZE - 2),
1 /* extend */);
if (ret <= 0) {
return ret;
}
assert(s->s3->sniff_buffer_len == msg_length + 2);
CBS_init(&v2_client_hello, (const uint8_t *)s->s3->sniff_buffer->data + 2,
assert(s->packet_length == msg_length + 2);
CBS_init(&v2_client_hello, (const uint8_t *)s->packet + 2,
msg_length);
/* The V2ClientHello without the length is incorporated into the handshake
@ -792,10 +759,10 @@ int ssl3_get_v2_client_hello(SSL *s) {
/* The handshake message header is 4 bytes. */
s->s3->tmp.message_size = len - 4;
/* Drop the sniff buffer. */
BUF_MEM_free(s->s3->sniff_buffer);
s->s3->sniff_buffer = NULL;
s->s3->sniff_buffer_len = 0;
/* The V2ClientHello was processed, so it may be released now. */
if (s->s3->rbuf.left == 0) {
ssl3_release_read_buffer(s);
}
return 1;
}