libfilezilla
Loading...
Searching...
No Matches
basic_tls_params.hpp
1#ifndef LIBFILEZILLA_BASIC_TLS_PARAMS_HEADER
2#define LIBFILEZILLA_BASIC_TLS_PARAMS_HEADER
3
8
9#include "format.hpp"
10#include "hash.hpp"
11#include "string.hpp"
12#include "forward_like.hpp"
13
14#include <variant>
15
16namespace fz {
17
18template <typename T, typename Tag, typename Policy>
19struct basic_tls_param;
20
21template <typename T, typename Tag>
22struct is_same_kind_of_basic_tls_param : std::false_type{};
23
24template <typename T, typename Tag, typename Policy>
25struct is_same_kind_of_basic_tls_param<basic_tls_param<T, Tag, Policy>, Tag> : std::true_type{};
26
27template <typename T, typename Tag, typename Policy>
28struct basic_tls_param final
29{
30 basic_tls_param(basic_tls_param const &) = default;
31 basic_tls_param& operator=(basic_tls_param &&) = default;
32 basic_tls_param& operator=(basic_tls_param const &) = default;
33
34 template <typename U = T, std::enable_if_t<std::is_default_constructible_v<U>>* = nullptr>
35 basic_tls_param()
36 : value{}
37 {}
38
39 template <typename U, std::enable_if_t<std::is_constructible_v<T, U>>* = nullptr>
40 explicit basic_tls_param(U && v)
41 : value(std::forward<U>(v))
42 {}
43
44 template <typename U, typename V = std::remove_cv_t<std::remove_reference_t<U>>, std::enable_if_t<
45 !std::is_same_v<V, basic_tls_param> &&
46 is_same_kind_of_basic_tls_param<V, Tag>::value>* = nullptr>
47 basic_tls_param(U && other)
48 : value(forward_like<U>(other.value))
49 {}
50
51 explicit operator bool() const
52 {
53 return Policy::is_valid(value);
54 }
55
56 bool is_valid() const
57 {
58 return Policy::is_valid(value);
59 }
60
61 template <typename U, typename P>
62 bool operator ==(basic_tls_param<U, Tag, P> const & rhs) const
63 {
64 return value == rhs.value;
65 }
66
67 template <typename U, typename P>
68 bool operator !=(basic_tls_param<U, Tag, P> const & rhs) const
69 {
70 return value != rhs.value;
71 }
72
73 template <typename U, typename P>
74 bool operator <(basic_tls_param<U, Tag, P> const & rhs) const
75 {
76 return value < rhs.value;
77 }
78
79 template <typename U, typename P>
80 bool operator <=(basic_tls_param<U, Tag, P> const & rhs) const
81 {
82 return value <= rhs.value;
83 }
84
85 template <typename U, typename P>
86 bool operator >(basic_tls_param<U, Tag, P> const & rhs) const
87 {
88 return value > rhs.value;
89 }
90
91 template <typename U, typename P>
92 bool operator >=(basic_tls_param<U, Tag, P> const & rhs) const
93 {
94 return value >= rhs.value;
95 }
96
97 T value;
98};
99
100struct basic_tls_param_policy
101{
102 template <typename T>
103 static bool is_valid(T const & v)
104 {
105 return !v.empty();
106 }
107};
108
109struct tls_pkcs11url_policy
110{
111 static bool is_valid(std::string_view v)
112 {
113 static constexpr std::string_view pkcs11_scheme = "pkcs11:";
114
115 return fz::starts_with(v, pkcs11_scheme);
116 }
117};
118
119template <typename T>
120using basic_tls_blob = basic_tls_param<T, struct tls_blob_tag, basic_tls_param_policy>;
121
122template <typename T>
123using basic_tls_filepath = basic_tls_param<T, struct tls_filepath_tag, basic_tls_param_policy>;
124
125template <typename T>
126using basic_tls_pkcs11url = basic_tls_param<T, struct tls_pkcs11url_tag, tls_pkcs11url_policy>;
127
128template <typename B, typename F, typename P>
129struct basic_tls_param_variant;
130
131template <typename T>
132struct is_basic_tls_param_variant : std::false_type{};
133
134template <typename B, typename F, typename P>
135struct is_basic_tls_param_variant<basic_tls_param_variant<B, F, P>> : std::true_type{};
136
137template <typename B, typename F, typename P>
138struct basic_tls_param_variant final
139{
140 using blob_type = basic_tls_blob<B>;
141 using filepath_type = basic_tls_filepath<F>;
142 using pkcs11url_type = basic_tls_pkcs11url<P>;
143
144 using variant_type = std::variant<
145 blob_type,
146 filepath_type,
147 pkcs11url_type
148 >;
149
150 blob_type const *blob() const
151 {
152 return std::get_if<blob_type>(&value);
153 }
154
155 filepath_type const *filepath() const
156 {
157 return std::get_if<filepath_type>(&value);
158 }
159
160 pkcs11url_type const *pkcs11url() const
161 {
162 return std::get_if<pkcs11url_type>(&value);
163 }
164
165 blob_type *blob()
166 {
167 return std::get_if<blob_type>(&value);
168 }
169
170 filepath_type *filepath()
171 {
172 return std::get_if<filepath_type>(&value);
173 }
174
175 pkcs11url_type *pkcs11url()
176 {
177 return std::get_if<pkcs11url_type>(&value);
178 }
179
180 native_string url() const
181 {
182 struct visitor
183 {
184 native_string operator()(filepath_type const &v)
185 {
186 return fz::sprintf(fzT("file:%s"), v ? v.value : fzT("<invalid>"));
187 }
188
189 native_string operator()(pkcs11url_type const &v)
190 {
191 if (v) {
192 return to_native(v.value);
193 }
194
195 return fzT("pkcs11:<invalid>");
196 }
197
198 native_string operator()(blob_type const &v)
199 {
200 if (v) {
201 return fz::sprintf(fzT("blob:md5:%s"), hex_encode<native_string>(md5(v.value)));
202 }
203
204 return fzT("blob:<invalid>");
205 }
206 };
207
208 return std::visit(visitor(), value);
209 }
210
211 basic_tls_param_variant() = default;
212 basic_tls_param_variant(basic_tls_param_variant &&) = default;
213 basic_tls_param_variant(basic_tls_param_variant const &) = default;
214 basic_tls_param_variant& operator=(basic_tls_param_variant &&) = default;
215 basic_tls_param_variant& operator=(basic_tls_param_variant const &) = default;
216
217 template <typename T, std::enable_if_t<std::is_constructible_v<variant_type, T>>* = nullptr>
218 basic_tls_param_variant(T && v)
219 : value(std::forward<T>(v))
220 {}
221
222 template <typename T, typename U = std::remove_cv_t<std::remove_reference_t<T>>, std::enable_if_t<
223 !std::is_same_v<U, basic_tls_param_variant>
224 && is_basic_tls_param_variant<U>::value>* = nullptr>
225 basic_tls_param_variant(T && other)
226 : value(std::visit([](auto && v) {
227 return variant_type(std::forward<decltype(v)>(v));
228 }, forward_like<T>(other.value)))
229 {
230 }
231
232 template <typename T, std::enable_if_t<!std::is_same_v<T, basic_tls_param_variant> && is_basic_tls_param_variant<T>::value>* = nullptr>
233 basic_tls_param_variant& operator=(T && other)
234 {
235 *this = basic_tls_param_variant(std::forward<T>(other));
236 return *this;
237 }
238
239 explicit operator bool() const
240 {
241 return std::visit([](auto && v) {
242 return bool(v);
243 }, value);
244 }
245
246 bool is_valid() const
247 {
248 return bool(*this);
249 }
250
251 template <typename F2, typename P2, typename B2>
252 bool operator ==(basic_tls_param_variant<F2, P2, B2> const & rhs) const
253 {
254 return value == rhs.value;
255 }
256
257 template <typename F2, typename P2, typename B2>
258 bool operator !=(basic_tls_param_variant<F2, P2, B2> const & rhs) const
259 {
260 return value != rhs.value;
261 }
262
263 template <typename F2, typename P2, typename B2>
264 bool operator <(basic_tls_param_variant<F2, P2, B2> const & rhs) const
265 {
266 return value < rhs.value;
267 }
268
269 template <typename F2, typename P2, typename B2>
270 bool operator <=(basic_tls_param_variant<F2, P2, B2> const & rhs) const
271 {
272 return value <= rhs.value;
273 }
274
275 template <typename F2, typename P2, typename B2>
276 bool operator >(basic_tls_param_variant<F2, P2, B2> const & rhs) const
277 {
278 return value > rhs.value;
279 }
280
281 template <typename F2, typename P2, typename B2>
282 bool operator >=(basic_tls_param_variant<F2, P2, B2> const & rhs) const
283 {
284 return value >= rhs.value;
285 }
286
287 variant_type value;
288};
289
290}
291
292#endif
293
Header for the sprintf string formatting function.
A function that acts like std::forward, but applies the value category of its first template paramete...
Collection of cryptographic hash and MAC functions.
The namespace used by libfilezilla.
Definition apply.hpp:17
constexpr detail::apply_value_category_t< T, U > forward_like(U &&u) noexcept
applies the value category of T to u, so that u can be perfectly forwarded as-if it were of type T.
Definition forward_like.hpp:31
std::enable_if_t< std::is_same_v< string_value_type_t< String >, string_value_type_t< Beginning > >, bool > starts_with(String const &s, Beginning const &beginning)
Tests whether the first string starts with the second string.
Definition string.hpp:831
std::vector< uint8_t > md5(std::string_view const &data)
Standard MD5.
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition string.hpp:69
std::string sprintf(std::string_view const &fmt, Args &&... args)
A simple type-safe sprintf replacement.
Definition format.hpp:456
native_string to_native(std::string_view const &in)
Converts std::string to native_string.
String types and assorted functions.
#define fzT(x)
Macro for a string literal in system-native character type. Note: Macro definition changes depending...
Definition string.hpp:324
@ value
Definition xml.hpp:36