1/* 2 * Copyright 1998-2001 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10#ifndef OSSL_TEST_SHIM_INCLUDE_OPENSSL_BASE_H 11#define OSSL_TEST_SHIM_INCLUDE_OPENSSL_BASE_H 12 13/* Needed for BORINGSSL_MAKE_DELETER */ 14# include <openssl/bio.h> 15# include <openssl/evp.h> 16# include <openssl/dh.h> 17# include <openssl/x509.h> 18# include <openssl/ssl.h> 19 20# define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) 21 22extern "C++" { 23 24#include <memory> 25 26namespace bssl { 27 28namespace internal { 29 30template <typename T> 31struct DeleterImpl {}; 32 33template <typename T> 34struct Deleter { 35 void operator()(T *ptr) { 36 // Rather than specialize Deleter for each type, we specialize 37 // DeleterImpl. This allows bssl::UniquePtr<T> to be used while only 38 // including base.h as long as the destructor is not emitted. This matches 39 // std::unique_ptr's behavior on forward-declared types. 40 // 41 // DeleterImpl itself is specialized in the corresponding module's header 42 // and must be included to release an object. If not included, the compiler 43 // will error that DeleterImpl<T> does not have a method Free. 44 DeleterImpl<T>::Free(ptr); 45 } 46}; 47 48template <typename T, typename CleanupRet, void (*init)(T *), 49 CleanupRet (*cleanup)(T *)> 50class StackAllocated { 51 public: 52 StackAllocated() { init(&ctx_); } 53 ~StackAllocated() { cleanup(&ctx_); } 54 55 StackAllocated(const StackAllocated<T, CleanupRet, init, cleanup> &) = delete; 56 T& operator=(const StackAllocated<T, CleanupRet, init, cleanup> &) = delete; 57 58 T *get() { return &ctx_; } 59 const T *get() const { return &ctx_; } 60 61 void Reset() { 62 cleanup(&ctx_); 63 init(&ctx_); 64 } 65 66 private: 67 T ctx_; 68}; 69 70} // namespace internal 71 72#define BORINGSSL_MAKE_DELETER(type, deleter) \ 73 namespace internal { \ 74 template <> \ 75 struct DeleterImpl<type> { \ 76 static void Free(type *ptr) { deleter(ptr); } \ 77 }; \ 78 } 79 80// This makes a unique_ptr to STACK_OF(type) that owns all elements on the 81// stack, i.e. it uses sk_pop_free() to clean up. 82#define BORINGSSL_MAKE_STACK_DELETER(type, deleter) \ 83 namespace internal { \ 84 template <> \ 85 struct DeleterImpl<STACK_OF(type)> { \ 86 static void Free(STACK_OF(type) *ptr) { \ 87 sk_##type##_pop_free(ptr, deleter); \ 88 } \ 89 }; \ 90 } 91 92// Holds ownership of heap-allocated BoringSSL structures. Sample usage: 93// bssl::UniquePtr<BIO> rsa(RSA_new()); 94// bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem())); 95template <typename T> 96using UniquePtr = std::unique_ptr<T, internal::Deleter<T>>; 97 98BORINGSSL_MAKE_DELETER(BIO, BIO_free) 99BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free) 100BORINGSSL_MAKE_DELETER(DH, DH_free) 101BORINGSSL_MAKE_DELETER(X509, X509_free) 102BORINGSSL_MAKE_DELETER(SSL, SSL_free) 103BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free) 104BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free) 105 106} // namespace bssl 107 108} /* extern C++ */ 109 110 111#endif /* OSSL_TEST_SHIM_INCLUDE_OPENSSL_BASE_H */ 112