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 22 extern "C++" { 23 24 #include <memory> 25 26 namespace bssl { 27 28 namespace internal { 29 30 template <typename T> 31 struct DeleterImpl {}; 32 33 template <typename T> 34 struct Deleter { operatorDeleter35 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 48 template <typename T, typename CleanupRet, void (*init)(T *), 49 CleanupRet (*cleanup)(T *)> 50 class StackAllocated { 51 public: StackAllocated()52 StackAllocated() { init(&ctx_); } ~StackAllocated()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 get()58 T *get() { return &ctx_; } get()59 const T *get() const { return &ctx_; } 60 Reset()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())); 95 template <typename T> 96 using UniquePtr = std::unique_ptr<T, internal::Deleter<T>>; 97 98 BORINGSSL_MAKE_DELETER(BIO, BIO_free) 99 BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free) 100 BORINGSSL_MAKE_DELETER(DH, DH_free) 101 BORINGSSL_MAKE_DELETER(X509, X509_free) 102 BORINGSSL_MAKE_DELETER(SSL, SSL_free) 103 BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free) 104 BORINGSSL_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