]>
Commit | Line | Data |
---|---|---|
624265c6 RS |
1 | /* |
2 | * Copyright 1998-2001 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
909f1a2e | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
624265c6 RS |
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 | */ | |
7b73b7be MC |
9 | |
10 | #ifndef OPENSSL_HEADER_BASE_H | |
11 | #define OPENSSL_HEADER_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 | ||
7b73b7be MC |
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 /* OPENSSL_HEADER_BASE_H */ |