92e3648e1cc8210a8019d2592ec27c48d57b0105
[openssl.git] / test / ossl_shim / include / openssl / base.h
1 /*
2  * Copyright 1998-2001 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 {
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
48 template <typename T, typename CleanupRet, void (*init)(T *),
49           CleanupRet (*cleanup)(T *)>
50 class 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()));
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 */