Switch the handshake buffer from memory BIO to BUF_MEM.
A memory BIO is internally a BUF_MEM anyway. There's no need to bring
BIO_write into the mix. BUF_MEM is size_t clean.
Change-Id: I4ec6e4d22c72696bf47c95861771013483f75cab
Reviewed-on: https://boringssl-review.googlesource.com/5616
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index 93da2c3..7249f51 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -385,8 +385,8 @@
int wpend_ret; /* number of bytes submitted */
const uint8_t *wpend_buf;
- /* used during startup, digest all incoming/outgoing packets */
- BIO *handshake_buffer;
+ /* handshake_buffer, if non-NULL, contains the handshake transcript. */
+ BUF_MEM *handshake_buffer;
/* When set of handshake digests is determined, buffer is hashed and freed
* and MD_CTX-es for all required digests are stored in this array */
EVP_MD_CTX **handshake_dgst;
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 85dc9d6..7580016 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -456,18 +456,13 @@
* agreed digest and cached handshake records. Otherwise, use
* SHA1 or MD5 + SHA1 depending on key type. */
if (SSL_USE_SIGALGS(s)) {
- const uint8_t *hdata;
- size_t hdatalen;
EVP_MD_CTX mctx;
unsigned len;
- if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
EVP_MD_CTX_init(&mctx);
if (!EVP_DigestInit_ex(&mctx, *out_md, NULL) ||
- !EVP_DigestUpdate(&mctx, hdata, hdatalen) ||
+ !EVP_DigestUpdate(&mctx, s->s3->handshake_buffer->data,
+ s->s3->handshake_buffer->length) ||
!EVP_DigestFinal(&mctx, out, &len)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
EVP_MD_CTX_cleanup(&mctx);
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index af72549..f860609 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -238,21 +238,14 @@
int ssl3_init_handshake_buffer(SSL *ssl) {
ssl3_free_handshake_buffer(ssl);
ssl3_free_handshake_hash(ssl);
- ssl->s3->handshake_buffer = BIO_new(BIO_s_mem());
- if (ssl->s3->handshake_buffer == NULL) {
- return 0;
- }
- BIO_set_close(ssl->s3->handshake_buffer, BIO_CLOSE);
-
- return 1;
+ ssl->s3->handshake_buffer = BUF_MEM_new();
+ return ssl->s3->handshake_buffer != NULL;
}
int ssl3_init_handshake_hash(SSL *ssl) {
int i;
uint32_t mask;
const EVP_MD *md;
- const uint8_t *hdata;
- size_t hdatalen;
/* Allocate handshake_dgst array */
ssl3_free_handshake_hash(ssl);
@@ -262,12 +255,7 @@
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
-
memset(ssl->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
- if (!BIO_mem_contents(ssl->s3->handshake_buffer, &hdata, &hdatalen)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_LENGTH);
- return 0;
- }
/* Loop through bits of algorithm_prf field and create MD_CTX-es */
for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) {
@@ -283,7 +271,9 @@
OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
- EVP_DigestUpdate(ssl->s3->handshake_dgst[i], hdata, hdatalen);
+ EVP_DigestUpdate(ssl->s3->handshake_dgst[i],
+ ssl->s3->handshake_buffer->data,
+ ssl->s3->handshake_buffer->length);
} else {
ssl->s3->handshake_dgst[i] = NULL;
}
@@ -307,7 +297,7 @@
}
void ssl3_free_handshake_buffer(SSL *ssl) {
- BIO_free(ssl->s3->handshake_buffer);
+ BUF_MEM_free(ssl->s3->handshake_buffer);
ssl->s3->handshake_buffer = NULL;
}
@@ -315,11 +305,16 @@
/* Depending on the state of the handshake, either the handshake buffer may be
* active, the rolling hash, or both. */
- /* TODO(davidben): Replace |handshake_buffer| with a simpler type that doesn't
- * require a cast. */
- if (ssl->s3->handshake_buffer != NULL &&
- BIO_write(ssl->s3->handshake_buffer, in, (int)in_len) < 0) {
- return 0;
+ if (ssl->s3->handshake_buffer != NULL) {
+ size_t new_len = ssl->s3->handshake_buffer->length + in_len;
+ if (new_len < in_len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+ if (!BUF_MEM_grow(ssl->s3->handshake_buffer, new_len)) {
+ return 0;
+ }
+ memcpy(ssl->s3->handshake_buffer->data + new_len - in_len, in, in_len);
}
if (ssl->s3->handshake_dgst != NULL) {