Add CRYPTO_BUFFER and CRYPTO_BUFFER_POOL. These structures allow for blobs of data (e.g. certificates) to be deduplicated in memory. Change-Id: Iebfec90b85d55565848a178b6951562b4ccc083e Reviewed-on: https://boringssl-review.googlesource.com/11820 Reviewed-by: Adam Langley <alangley@gmail.com> Commit-Queue: Adam Langley <alangley@gmail.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 4cc5ae2..20a38dc 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt
@@ -64,6 +64,7 @@ add_subdirectory(buf) add_subdirectory(base64) add_subdirectory(bytestring) +add_subdirectory(pool) # Level 0.2 - depends on nothing but itself add_subdirectory(sha) @@ -136,6 +137,7 @@ $<TARGET_OBJECTS:err> $<TARGET_OBJECTS:base64> $<TARGET_OBJECTS:bytestring> + $<TARGET_OBJECTS:pool> $<TARGET_OBJECTS:sha> $<TARGET_OBJECTS:md4> $<TARGET_OBJECTS:md5>
diff --git a/crypto/pool/CMakeLists.txt b/crypto/pool/CMakeLists.txt new file mode 100644 index 0000000..fe55af2 --- /dev/null +++ b/crypto/pool/CMakeLists.txt
@@ -0,0 +1,20 @@ +include_directories(../../include) + +add_library( + pool + + OBJECT + + pool.c +) + +add_executable( + pool_test + + pool_test.cc + + $<TARGET_OBJECTS:test_support> +) + +target_link_libraries(pool_test crypto) +add_dependencies(all_tests pool_test)
diff --git a/crypto/pool/internal.h b/crypto/pool/internal.h new file mode 100644 index 0000000..3ec2ec2 --- /dev/null +++ b/crypto/pool/internal.h
@@ -0,0 +1,45 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_INTERNAL_H +#define OPENSSL_HEADER_POOL_INTERNAL_H + +#include <openssl/lhash.h> +#include <openssl/thread.h> + +#if defined(__cplusplus) +extern "C" { +#endif + + +DECLARE_LHASH_OF(CRYPTO_BUFFER); + +struct crypto_buffer_st { + CRYPTO_BUFFER_POOL *pool; + uint8_t *data; + size_t len; + CRYPTO_refcount_t references; +}; + +struct crypto_buffer_pool_st { + LHASH_OF(CRYPTO_BUFFER) *bufs; + CRYPTO_MUTEX lock; +}; + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_POOL_INTERNAL_H */
diff --git a/crypto/pool/pool.c b/crypto/pool/pool.c new file mode 100644 index 0000000..ebe1b24 --- /dev/null +++ b/crypto/pool/pool.c
@@ -0,0 +1,200 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <openssl/pool.h> + +#include <assert.h> +#include <string.h> + +#include <openssl/buf.h> +#include <openssl/bytestring.h> +#include <openssl/mem.h> +#include <openssl/thread.h> + +#include "../internal.h" +#include "internal.h" + + +static uint32_t CRYPTO_BUFFER_hash(const CRYPTO_BUFFER *buf) { + return OPENSSL_hash32(buf->data, buf->len); +} + +static int CRYPTO_BUFFER_cmp(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b) { + if (a->len != b->len) { + return 1; + } + return memcmp(a->data, b->data, a->len); +} + +CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) { + CRYPTO_BUFFER_POOL *pool = OPENSSL_malloc(sizeof(CRYPTO_BUFFER_POOL)); + if (pool == NULL) { + return NULL; + } + + memset(pool, 0, sizeof(CRYPTO_BUFFER_POOL)); + pool->bufs = lh_CRYPTO_BUFFER_new(CRYPTO_BUFFER_hash, CRYPTO_BUFFER_cmp); + if (pool->bufs == NULL) { + OPENSSL_free(pool); + return NULL; + } + + CRYPTO_MUTEX_init(&pool->lock); + + return pool; +} + +void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool) { + if (pool == NULL) { + return; + } + +#if !defined(NDEBUG) + CRYPTO_MUTEX_lock_write(&pool->lock); + assert(lh_CRYPTO_BUFFER_num_items(pool->bufs) == 0); + CRYPTO_MUTEX_unlock_write(&pool->lock); +#endif + + lh_CRYPTO_BUFFER_free(pool->bufs); + CRYPTO_MUTEX_cleanup(&pool->lock); + OPENSSL_free(pool); +} + +CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool) { + if (pool != NULL) { + CRYPTO_BUFFER tmp; + tmp.data = (uint8_t *) data; + tmp.len = len; + + CRYPTO_MUTEX_lock_read(&pool->lock); + CRYPTO_BUFFER *const duplicate = + lh_CRYPTO_BUFFER_retrieve(pool->bufs, &tmp); + if (duplicate != NULL) { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_read(&pool->lock); + + if (duplicate != NULL) { + return duplicate; + } + } + + CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER)); + if (buf == NULL) { + return NULL; + } + memset(buf, 0, sizeof(CRYPTO_BUFFER)); + + buf->data = BUF_memdup(data, len); + if (len != 0 && buf->data == NULL) { + OPENSSL_free(buf); + return NULL; + } + + buf->len = len; + buf->references = 1; + + if (pool == NULL) { + return buf; + } + + buf->pool = pool; + + CRYPTO_MUTEX_lock_write(&pool->lock); + CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf); + int inserted = 0; + if (duplicate == NULL) { + CRYPTO_BUFFER *old = NULL; + inserted = lh_CRYPTO_BUFFER_insert(pool->bufs, &old, buf); + assert(old == NULL); + } else { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_write(&pool->lock); + + if (!inserted) { + /* We raced to insert |buf| into the pool and lost, or else there was an + * error inserting. */ + OPENSSL_free(buf->data); + OPENSSL_free(buf); + return duplicate; + } + + return buf; +} + +CRYPTO_BUFFER* CRYPTO_BUFFER_new_from_CBS(CBS *cbs, CRYPTO_BUFFER_POOL *pool) { + return CRYPTO_BUFFER_new(CBS_data(cbs), CBS_len(cbs), pool); +} + +void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf) { + if (buf == NULL) { + return; + } + + CRYPTO_BUFFER_POOL *const pool = buf->pool; + if (pool == NULL) { + if (CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + /* If a reference count of zero is observed, there cannot be a reference + * from any pool to this buffer and thus we are able to free this + * buffer. */ + OPENSSL_free(buf->data); + OPENSSL_free(buf); + } + + return; + } + + CRYPTO_MUTEX_lock_write(&pool->lock); + if (!CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + return; + } + + /* We have an exclusive lock on the pool, therefore no concurrent lookups can + * find this buffer and increment the reference count. Thus, if the count is + * zero there are and can never be any more references and thus we can free + * this buffer. */ + void *found = lh_CRYPTO_BUFFER_delete(pool->bufs, buf); + assert(found != NULL); + assert(found == buf); + (void)found; + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + OPENSSL_free(buf->data); + OPENSSL_free(buf); +} + +int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf) { + /* This is safe in the case that |buf->pool| is NULL because it's just + * standard reference counting in that case. + * + * This is also safe if |buf->pool| is non-NULL because, if it were racing + * with |CRYPTO_BUFFER_free| then the two callers must have independent + * references already and so the reference count will never hit zero. */ + CRYPTO_refcount_inc(&buf->references); + return 1; +} + +const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf) { + return buf->data; +} + +const size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf) { + return buf->len; +} + +void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out) { + CBS_init(out, buf->data, buf->len); +}
diff --git a/crypto/pool/pool_test.cc b/crypto/pool/pool_test.cc new file mode 100644 index 0000000..4dfc546 --- /dev/null +++ b/crypto/pool/pool_test.cc
@@ -0,0 +1,85 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <string.h> + +#include <openssl/pool.h> + + +static bool TestUnpooled() { + static const uint8_t kData[4] = {1, 2, 3, 4}; + bssl::UniquePtr<CRYPTO_BUFFER> buf( + CRYPTO_BUFFER_new(kData, sizeof(kData), nullptr)); + if (!buf) { + return false; + } + + if (CRYPTO_BUFFER_len(buf.get()) != sizeof(kData) || + memcmp(kData, CRYPTO_BUFFER_data(buf.get()), sizeof(kData)) != 0) { + fprintf(stderr, "CRYPTO_BUFFER corrupted data.\n"); + return false; + } + + CRYPTO_BUFFER_up_ref(buf.get()); + bssl::UniquePtr<CRYPTO_BUFFER> buf2(buf.get()); + + return true; +} + +static bool TestEmpty() { + bssl::UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(nullptr, 0, nullptr)); + if (!buf) { + return false; + } + + return true; +} + +static bool TestPool() { + bssl::UniquePtr<CRYPTO_BUFFER_POOL> pool(CRYPTO_BUFFER_POOL_new()); + if (!pool) { + return false; + } + + static const uint8_t kData[4] = {1, 2, 3, 4}; + bssl::UniquePtr<CRYPTO_BUFFER> buf( + CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get())); + if (!buf) { + return false; + } + + bssl::UniquePtr<CRYPTO_BUFFER> buf2( + CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get())); + if (!buf2) { + return false; + } + + if (buf.get() != buf2.get()) { + fprintf(stderr, "CRYPTO_BUFFER_POOL did not dedup data.\n"); + return false; + } + + return true; +} + +int main(int argc, char **argv) { + if (!TestUnpooled() || + !TestEmpty() || + !TestPool()) { + return 1; + } + + printf("PASS\n"); + return 0; +}
diff --git a/include/openssl/base.h b/include/openssl/base.h index 10a22ce..cb847d5 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h
@@ -255,6 +255,8 @@ typedef struct cmac_ctx_st CMAC_CTX; typedef struct conf_st CONF; typedef struct conf_value_st CONF_VALUE; +typedef struct crypto_buffer_pool_st CRYPTO_BUFFER_POOL; +typedef struct crypto_buffer_st CRYPTO_BUFFER; typedef struct dh_st DH; typedef struct dsa_st DSA; typedef struct ec_group_st EC_GROUP;
diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h index 0d6d3ae..130ffb1 100644 --- a/include/openssl/lhash.h +++ b/include/openssl/lhash.h
@@ -97,6 +97,7 @@ * * LHASH_OF:ASN1_OBJECT * LHASH_OF:CONF_VALUE + * LHASH_OF:CRYPTO_BUFFER * LHASH_OF:SSL_SESSION */ #define IN_LHASH_H
diff --git a/include/openssl/lhash_macros.h b/include/openssl/lhash_macros.h index 1d98107..ca349a9 100644 --- a/include/openssl/lhash_macros.h +++ b/include/openssl/lhash_macros.h
@@ -17,11 +17,11 @@ #endif /* ASN1_OBJECT */ -#define lh_ASN1_OBJECT_new(hash, comp) \ - ((LHASH_OF(ASN1_OBJECT) *)lh_new( \ - CHECKED_CAST(lhash_hash_func, uint32_t (*)(const ASN1_OBJECT *), hash), \ - CHECKED_CAST(lhash_cmp_func, \ - int (*)(const ASN1_OBJECT *a, const ASN1_OBJECT *b), \ +#define lh_ASN1_OBJECT_new(hash, comp) \ + ((LHASH_OF(ASN1_OBJECT) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const ASN1_OBJECT *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const ASN1_OBJECT *a, const ASN1_OBJECT *b), \ comp))) #define lh_ASN1_OBJECT_free(lh) \ @@ -55,11 +55,12 @@ void (*)(ASN1_OBJECT *, void *), func), \ arg); + /* CONF_VALUE */ -#define lh_CONF_VALUE_new(hash, comp) \ - ((LHASH_OF(CONF_VALUE) *)lh_new( \ - CHECKED_CAST(lhash_hash_func, uint32_t (*)(const CONF_VALUE *), hash), \ - CHECKED_CAST(lhash_cmp_func, \ +#define lh_CONF_VALUE_new(hash, comp) \ + ((LHASH_OF(CONF_VALUE) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const CONF_VALUE *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ int (*)(const CONF_VALUE *a, const CONF_VALUE *b), comp))) #define lh_CONF_VALUE_free(lh) \ @@ -92,12 +93,53 @@ void (*)(CONF_VALUE *, void *), func), \ arg); + +/* CRYPTO_BUFFER */ +#define lh_CRYPTO_BUFFER_new(hash, comp) \ + ((LHASH_OF(CRYPTO_BUFFER) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const CRYPTO_BUFFER *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b), \ + comp))) + +#define lh_CRYPTO_BUFFER_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh)); + +#define lh_CRYPTO_BUFFER_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh)) + +#define lh_CRYPTO_BUFFER_retrieve(lh, data) \ + ((CRYPTO_BUFFER *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data))) + +#define lh_CRYPTO_BUFFER_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void **, CRYPTO_BUFFER **, old_data), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data)) + +#define lh_CRYPTO_BUFFER_delete(lh, data) \ + ((CRYPTO_BUFFER *)lh_delete( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data))) + +#define lh_CRYPTO_BUFFER_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(CRYPTO_BUFFER *), func)); + +#define lh_CRYPTO_BUFFER_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(CRYPTO_BUFFER *, void *), func), \ + arg); + + /* SSL_SESSION */ -#define lh_SSL_SESSION_new(hash, comp) \ - ((LHASH_OF(SSL_SESSION) *)lh_new( \ - CHECKED_CAST(lhash_hash_func, uint32_t (*)(const SSL_SESSION *), hash), \ - CHECKED_CAST(lhash_cmp_func, \ - int (*)(const SSL_SESSION *a, const SSL_SESSION *b), \ +#define lh_SSL_SESSION_new(hash, comp) \ + ((LHASH_OF(SSL_SESSION) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const SSL_SESSION *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const SSL_SESSION *a, const SSL_SESSION *b), \ comp))) #define lh_SSL_SESSION_free(lh) \
diff --git a/include/openssl/pool.h b/include/openssl/pool.h new file mode 100644 index 0000000..0f6a3c8 --- /dev/null +++ b/include/openssl/pool.h
@@ -0,0 +1,87 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_H +#define OPENSSL_HEADER_POOL_H + +#include <openssl/base.h> + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* Buffers and buffer pools. + * + * |CRYPTO_BUFFER|s are simply reference-counted blobs. A |CRYPTO_BUFFER_POOL| is + * an intern table for |CRYPTO_BUFFER|s. This allows for a single copy of a given + * blob to be kept in memory and referenced from multiple places. */ + + +/* CRYPTO_BUFFER_POOL_new returns a freshly allocated |CRYPTO_BUFFER_POOL| or + * NULL on error. */ +OPENSSL_EXPORT CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void); + +/* CRYPTO_BUFFER_POOL_free frees |pool|, which must be empty. */ +OPENSSL_EXPORT void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool); + +/* CRYPTO_BUFFER_new returns a |CRYPTO_BUFFER| containing a copy of |data|, or + * else NULL on error. If |pool| is not NULL then the returned value may be a + * reference to a previously existing |CRYPTO_BUFFER| that contained the same + * data. Otherwise, the returned, fresh |CRYPTO_BUFFER| will be added to the + * pool. */ +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool); + +/* CRYPTO_BUFFER_new_from_CBS acts the same as |CRYPTO_BUFFER_new|. */ +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_CBS( + CBS *cbs, CRYPTO_BUFFER_POOL *pool); + +/* CRYPTO_BUFFER_free decrements the reference count of |buf|. If there are no + * other references, or if the only remaining reference is from a pool, then + * |buf| will be freed. */ +OPENSSL_EXPORT void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf); + +/* CRYPTO_BUFFER_up_ref increments the reference count of |buf| and returns + * one. */ +OPENSSL_EXPORT int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf); + +/* CRYPTO_BUFFER_data returns a pointer to the data contained in |buf|. */ +OPENSSL_EXPORT const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf); + +/* CRYPTO_BUFFER_len returns the length, in bytes, of the data contained in + * |buf|. */ +OPENSSL_EXPORT const size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf); + +/* CRYPTO_BUFFER_init_CBS initialises |out| to point at the data from |buf|. */ +OPENSSL_EXPORT void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out); + + +#if defined(__cplusplus) +} /* extern C */ + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER_POOL, CRYPTO_BUFFER_POOL_free) +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER, CRYPTO_BUFFER_free) + +} // namespace bssl + +} /* extern C++ */ + +#endif + +#endif // OPENSSL_HEADER_POOL_H
diff --git a/util/all_tests.json b/util/all_tests.json index ac4b3c7..369e1aa 100644 --- a/util/all_tests.json +++ b/util/all_tests.json
@@ -54,6 +54,7 @@ ["crypto/pkcs8/pkcs12_test"], ["crypto/pkcs8/pkcs8_test"], ["crypto/poly1305/poly1305_test", "crypto/poly1305/poly1305_tests.txt"], + ["crypto/pool/pool_test"], ["crypto/refcount_test"], ["crypto/rsa/rsa_test"], ["crypto/thread_test"],
diff --git a/util/doc.config b/util/doc.config index e7cfa82..f3f3d52 100644 --- a/util/doc.config +++ b/util/doc.config
@@ -14,6 +14,7 @@ "include/openssl/lhash.h", "include/openssl/mem.h", "include/openssl/obj.h", + "include/openssl/pool.h", "include/openssl/rand.h", "include/openssl/stack.h", "include/openssl/time_support.h"