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. Change-Id: I0ea4589d7a8b5c41df225ad7f282b6d1376a8db4 Reviewed-on: https://boringssl-review.googlesource.com/12164 Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 165dca1..689fa82 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h
@@ -730,6 +730,16 @@ * modes enabled for |ssl|. */ OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl); +/* SSL_CTX_set0_buffer_pool sets a |CRYPTO_BUFFER_POOL| that will be used to + * store certificates. This can allow multiple connections to share + * certificates and thus save memory. + * + * The SSL_CTX does not take ownership of |pool| and the caller must ensure + * that |pool| outlives |ctx| and all objects linked to it, including |SSL|, + * |X509| and |SSL_SESSION| objects. Basically, don't ever free |pool|. */ +OPENSSL_EXPORT void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, + CRYPTO_BUFFER_POOL *pool); + /* Configuring certificates and private keys. * @@ -4073,6 +4083,10 @@ * TODO(agl): remove once node.js no longer references this. */ STACK_OF(X509)* extra_certs; int freelist_max_len; + + /* pool is used for all |CRYPTO_BUFFER|s in case we wish to share certificate + * memory. */ + CRYPTO_BUFFER_POOL *pool; }; typedef struct ssl_handshake_st SSL_HANDSHAKE;
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index 39c52ed..a984e8e 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c
@@ -685,6 +685,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) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); @@ -719,6 +720,7 @@ } } + /* TODO(agl): this should use the |SSL_CTX|'s pool. */ CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&cert, NULL); if (buffer == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 1ddf69a..4297245 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c
@@ -481,7 +481,8 @@ SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256); } - CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&certificate, NULL); + CRYPTO_BUFFER *buffer = + CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool); if (buffer == NULL) { *out_alert = SSL_AD_INTERNAL_ERROR; OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index ac5a7dd..ad4d1b2 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c
@@ -1080,6 +1080,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/tls13_both.c b/ssl/tls13_both.c index 8639089..85d804f 100644 --- a/ssl/tls13_both.c +++ b/ssl/tls13_both.c
@@ -207,7 +207,8 @@ ssl->s3->new_session->peer_sha256); } - CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&certificate, NULL); + CRYPTO_BUFFER *buffer = + CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool); if (buffer == NULL) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);