1/*
2 * Copyright (C) 2017 Metrological Group B.V.
3 * Copyright (C) 2017 Igalia S.L.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include <gcrypt.h>
30
31namespace PAL {
32namespace GCrypt {
33
34template<typename T>
35struct HandleDeleter {
36public:
37 void operator()(T handle) = delete;
38};
39
40template<typename T>
41class Handle {
42public:
43 Handle() = default;
44
45 explicit Handle(T handle)
46 : m_handle(handle)
47 { }
48
49 ~Handle()
50 {
51 clear();
52 }
53
54 Handle(const Handle&) = delete;
55 Handle& operator=(const Handle&) = delete;
56
57 Handle(Handle&&) = delete;
58 Handle& operator=(Handle&&) = delete;
59
60 void clear()
61 {
62 if (m_handle)
63 HandleDeleter<T>()(m_handle);
64 m_handle = nullptr;
65 }
66
67 T release()
68 {
69 T handle = m_handle;
70 m_handle = nullptr;
71 return handle;
72 }
73
74 T* operator&() { return &m_handle; }
75
76 T handle() const { return m_handle; }
77 operator T() const { return m_handle; }
78
79 bool operator!() const { return !m_handle; }
80
81private:
82 T m_handle { nullptr };
83};
84
85template<>
86struct HandleDeleter<gcry_cipher_hd_t> {
87 void operator()(gcry_cipher_hd_t handle)
88 {
89 gcry_cipher_close(handle);
90 }
91};
92
93template<>
94struct HandleDeleter<gcry_ctx_t> {
95 void operator()(gcry_ctx_t handle)
96 {
97 gcry_ctx_release(handle);
98 }
99};
100
101template<>
102struct HandleDeleter<gcry_mac_hd_t> {
103 void operator()(gcry_mac_hd_t handle)
104 {
105 gcry_mac_close(handle);
106 }
107};
108
109template<>
110struct HandleDeleter<gcry_mpi_t> {
111 void operator()(gcry_mpi_t handle)
112 {
113 gcry_mpi_release(handle);
114 }
115};
116
117template<>
118struct HandleDeleter<gcry_mpi_point_t> {
119 void operator()(gcry_mpi_point_t handle)
120 {
121 gcry_mpi_point_release(handle);
122 }
123};
124
125template<>
126struct HandleDeleter<gcry_sexp_t> {
127 void operator()(gcry_sexp_t handle)
128 {
129 gcry_sexp_release(handle);
130 }
131};
132
133} // namespace GCrypt
134} // namespace PAL
135