-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathsignal.hh
More file actions
253 lines (207 loc) · 8.79 KB
/
signal.hh
File metadata and controls
253 lines (207 loc) · 8.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#pragma once
#include <fmt/core.h>
#include <memory>
#include <functional>
#include <type_traits>
#include <signal_protocol.h>
#include <key_helper.h>
#include <session_builder.h>
#include <session_cipher.h>
#include <session_pre_key.h>
#include <protocol.h>
#include <curve.h>
namespace libsignal {
template<typename T>
struct deleter {
void operator() (T *ptr) { SIGNAL_UNREF(ptr); }
};
template<typename T>
using object = std::unique_ptr<T, deleter<T>>;
template<typename T, typename CFun, typename DFun,
CFun &f_create, DFun &f_destroy, typename Base = T>
class type {
private:
T *_ptr;
protected:
typedef T* pointer_type;
inline type(T *ptr) : _ptr(ptr) {
}
template<typename Fun, Fun &func, int success = 0, typename... Args,
typename = std::enable_if_t<std::is_same_v<int, std::invoke_result_t<Fun, pointer_type, Args...>>>>
inline void call(Args&&... args) {
int ret = func(*this, std::forward<Args>(args)...);
if (ret != success) throw std::runtime_error(
fmt::format("Signal Error: expected {}, was {}", success, ret));
}
template<typename Fun, Fun &func, typename... Args,
typename = std::enable_if_t<!std::is_same_v<int, std::invoke_result_t<Fun, pointer_type, Args...>>>>
inline typename std::invoke_result<Fun, pointer_type, Args...>::type
call(Args&&... args) {
return func(*this, std::forward<Args>(args)...);
}
public:
inline explicit type() : _ptr(nullptr) {
}
template<typename... Args>
inline explicit type(Args&&... args) : type() {
f_create(&_ptr, std::forward<Args>(args)...);
}
inline ~type() {
if (_ptr)
f_destroy(reinterpret_cast<Base*>(_ptr));
_ptr = nullptr;
}
type(const type &other) = delete; /* no copy construction */
type(type &&other) = default;
template<typename... Args>
inline void create(Args&&... args) {
if (_ptr)
f_destroy(reinterpret_cast<Base*>(_ptr));
_ptr = nullptr;
f_create(&_ptr, std::forward<Args>(args)...);
}
type& operator =(const type &other) = delete; /* no copy assignment */
type& operator =(type &&other) = default;
inline operator bool() const { return _ptr; }
inline T* operator *() { return _ptr; }
inline operator T*() { return _ptr; }
inline operator const T*() const { return _ptr; }
};
typedef type<struct signal_context,
decltype(signal_context_create), decltype(signal_context_destroy),
signal_context_create, signal_context_destroy> context_type;
class context : public context_type {
public:
using context_type::context_type;
inline auto set_log_function(auto &&...args) {
return call<decltype(signal_context_set_log_function),
signal_context_set_log_function>(args...);
}
inline auto set_crypto_provider(auto &&...args) {
return call<decltype(signal_context_set_crypto_provider),
signal_context_set_crypto_provider>(args...);
}
inline auto set_locking_functions(auto &&...args) {
return call<decltype(signal_context_set_locking_functions),
signal_context_set_locking_functions>(args...);
}
};
typedef type<struct signal_protocol_store_context,
decltype(signal_protocol_store_context_create),
decltype(signal_protocol_store_context_destroy),
signal_protocol_store_context_create,
signal_protocol_store_context_destroy> store_context_type;
class store_context : public store_context_type {
public:
using store_context_type::store_context_type;
inline auto set_identity_key_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_identity_key_store),
signal_protocol_store_context_set_identity_key_store>(args...);
}
inline auto set_pre_key_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_pre_key_store),
signal_protocol_store_context_set_pre_key_store>(args...);
}
inline auto set_signed_pre_key_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_signed_pre_key_store),
signal_protocol_store_context_set_signed_pre_key_store>(args...);
}
inline auto set_session_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_session_store),
signal_protocol_store_context_set_session_store>(args...);
}
inline auto set_sender_key_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_sender_key_store),
signal_protocol_store_context_set_sender_key_store>(args...);
}
};
typedef type<struct ec_public_key,
decltype(curve_decode_point),
decltype(ec_public_key_destroy),
curve_decode_point,
ec_public_key_destroy,
signal_type_base> public_key_type;
class public_key : public public_key_type {
public:
using public_key_type::public_key_type;
inline static public_key deserialize(auto &&...args) {
pointer_type pointer;
ec_public_key_deserialize(&pointer, args...);
return public_key(pointer);
}
inline auto serialize(auto &&...args) {
return call<decltype(ec_public_key_serialize),
ec_public_key_serialize>(args...);
}
friend class identity_key_pair;
};
typedef type<struct ec_private_key,
decltype(curve_decode_private_point),
decltype(ec_private_key_destroy),
curve_decode_private_point,
ec_private_key_destroy,
signal_type_base> private_key_type;
class private_key : public private_key_type {
public:
using private_key_type::private_key_type;
inline static private_key deserialize(auto &&...args) {
pointer_type pointer;
ec_private_key_deserialize(&pointer, args...);
return private_key(pointer);
}
inline auto serialize(auto &&...args) {
return call<decltype(ec_private_key_serialize),
ec_private_key_serialize>(args...);
}
friend class identity_key_pair;
};
typedef type<struct ratchet_identity_key_pair,
decltype(ratchet_identity_key_pair_create),
decltype(ratchet_identity_key_pair_destroy),
ratchet_identity_key_pair_create,
ratchet_identity_key_pair_destroy,
signal_type_base> identity_key_pair_type;
class identity_key_pair : public identity_key_pair_type {
public:
using identity_key_pair_type::identity_key_pair_type;
inline static identity_key_pair generate(auto &&...args) {
pointer_type pointer;
signal_protocol_key_helper_generate_identity_key_pair(&pointer, args...);
return identity_key_pair(pointer);
}
inline public_key get_public(auto &&...args) {
return call<decltype(ratchet_identity_key_pair_get_public),
ratchet_identity_key_pair_get_public>(args...);
}
inline private_key get_private(auto &&...args) {
return call<decltype(ratchet_identity_key_pair_get_private),
ratchet_identity_key_pair_get_private>(args...);
}
};
typedef type<struct session_pre_key_bundle,
decltype(session_pre_key_bundle_create),
decltype(session_pre_key_bundle_destroy),
session_pre_key_bundle_create,
session_pre_key_bundle_destroy,
signal_type_base> pre_key_bundle_type;
class pre_key_bundle : public pre_key_bundle_type {
public:
using pre_key_bundle_type::pre_key_bundle_type;
};
typedef type<struct session_builder,
decltype(session_builder_create),
decltype(session_builder_free),
session_builder_create,
session_builder_free> session_builder_type;
class session_builder : public session_builder_type {
public:
using session_builder_type::session_builder_type;
inline auto process_pre_key_bundle(auto &&...args) {
return call<decltype(session_builder_process_pre_key_bundle),
session_builder_process_pre_key_bundle>(args...);
}
};
}