Add |SSL_CTX_set0_buffer_pool|.
This currently only works for certificates parsed from the network, but
if making several connections that share certificates, some KB of memory
might be saved.
BUG=chromium:671420
Change-Id: I1c7a71d84e1976138641f71830aafff87f795f9d
Reviewed-on: https://boringssl-review.googlesource.com/12706
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index dc806e0..5949020 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -1044,7 +1044,8 @@
uint8_t alert;
sk_CRYPTO_BUFFER_pop_free(ssl->s3->new_session->certs, CRYPTO_BUFFER_free);
- ssl->s3->new_session->certs = ssl_parse_cert_chain(&alert, NULL, &cbs);
+ ssl->s3->new_session->certs =
+ ssl_parse_cert_chain(&alert, NULL, &cbs, ssl->ctx->pool);
if (ssl->s3->new_session->certs == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
return -1;
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index 9b13023..8847251 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -1473,7 +1473,7 @@
ssl_parse_cert_chain(&alert, ssl->retain_only_sha256_of_client_certs
? ssl->s3->new_session->peer_sha256
: NULL,
- &certificate_msg);
+ &certificate_msg, ssl->ctx->pool);
if (ssl->s3->new_session->certs == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
return -1;
diff --git a/ssl/internal.h b/ssl/internal.h
index cd5db9e..3640b65 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -762,7 +762,8 @@
* |out_leaf_sha256|. */
STACK_OF(CRYPTO_BUFFER) *ssl_parse_cert_chain(uint8_t *out_alert,
uint8_t *out_leaf_sha256,
- CBS *cbs);
+ CBS *cbs,
+ CRYPTO_BUFFER_POOL *pool);
/* ssl_add_cert_to_cbb adds |x509| to |cbb|. It returns one on success and zero
* on error. */
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index fa2fbc0..a12af77 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -677,6 +677,7 @@
}
if (has_peer) {
+ /* TODO(agl): this should use the |SSL_CTX|'s pool. */
CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&peer, NULL);
if (buffer == NULL ||
!sk_CRYPTO_BUFFER_push(ret->certs, buffer)) {
@@ -694,6 +695,7 @@
goto err;
}
+ /* TODO(agl): this should use the |SSL_CTX|'s pool. */
CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&cert, NULL);
if (buffer == NULL ||
!sk_CRYPTO_BUFFER_push(ret->certs, buffer)) {
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 66ee068..7711cd1 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -464,7 +464,8 @@
STACK_OF(CRYPTO_BUFFER) *ssl_parse_cert_chain(uint8_t *out_alert,
uint8_t *out_leaf_sha256,
- CBS *cbs) {
+ CBS *cbs,
+ CRYPTO_BUFFER_POOL *pool) {
STACK_OF(CRYPTO_BUFFER) *ret = sk_CRYPTO_BUFFER_new_null();
if (ret == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
@@ -493,7 +494,8 @@
SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256);
}
- CRYPTO_BUFFER *buf = CRYPTO_BUFFER_new_from_CBS(&certificate, NULL);
+ CRYPTO_BUFFER *buf =
+ CRYPTO_BUFFER_new_from_CBS(&certificate, pool);
if (buf == NULL) {
*out_alert = SSL_AD_DECODE_ERROR;
goto err;
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 8638396..e5c0559 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1070,6 +1070,10 @@
uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
+void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, CRYPTO_BUFFER_POOL *pool) {
+ ctx->pool = pool;
+}
+
X509 *SSL_get_peer_certificate(const SSL *ssl) {
if (ssl == NULL) {
return NULL;
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 140e666..3ad906b 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -66,6 +66,8 @@
#include "test_config.h"
+static CRYPTO_BUFFER_POOL *g_pool = nullptr;
+
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
return close(sock);
@@ -909,6 +911,8 @@
return nullptr;
}
+ SSL_CTX_set0_buffer_pool(ssl_ctx.get(), g_pool);
+
// Enable TLS 1.3 for tests.
if (!config->is_dtls &&
!SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION)) {
@@ -1915,6 +1919,8 @@
return Usage(argv[0]);
}
+ g_pool = CRYPTO_BUFFER_POOL_new();
+
// Some code treats the zero time special, so initialize the clock to a
// non-zero time.
g_clock.tv_sec = 1234;
diff --git a/ssl/tls13_both.c b/ssl/tls13_both.c
index a47dd26..dd4a041 100644
--- a/ssl/tls13_both.c
+++ b/ssl/tls13_both.c
@@ -206,7 +206,8 @@
ssl->s3->new_session->peer_sha256);
}
- CRYPTO_BUFFER *buf = CRYPTO_BUFFER_new_from_CBS(&certificate, NULL);
+ CRYPTO_BUFFER *buf =
+ CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool);
if (buf == NULL ||
!sk_CRYPTO_BUFFER_push(certs, buf)) {
CRYPTO_BUFFER_free(buf);