]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/plugins/plugin_feature.h
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libstrongswan / plugins / plugin_feature.h
1 /*
2 * Copyright (C) 2016-2019 Andreas Steffen
3 * Copyright (C) 2012-2015 Tobias Brunner
4 * Copyright (C) 2011 Martin Willi
5 *
6 * Copyright (C) secunet Security Networks AG
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 /**
20 * @defgroup plugin_feature plugin_feature
21 * @{ @ingroup plugins
22 */
23
24 #ifndef PLUGIN_FEATURE_H_
25 #define PLUGIN_FEATURE_H_
26
27 typedef struct plugin_feature_t plugin_feature_t;
28
29 #include <library.h>
30 #include <eap/eap.h>
31 #include <plugins/plugin.h>
32 #include <credentials/containers/container.h>
33
34 /**
35 * Callback function of a plugin to (un-)register a specified feature.
36 *
37 * @param plugin plugin instance
38 * @param feature feature to register
39 * @param reg TRUE to register, FALSE to unregister
40 * @param cb_data user data passed with callback function
41 * @return TRUE if registered successfully
42 */
43 typedef bool (*plugin_feature_callback_t)(plugin_t *plugin,
44 plugin_feature_t *feature,
45 bool reg,void *cb_data);
46
47 /**
48 * Feature a plugin provides or depends on, including registration functions.
49 *
50 * Each plugin returns a list of plugin features, allowing the plugin loader
51 * to resolve dependencies and register the feature. FEATURE_PROVIDE defines
52 * features provided by the plugin, hard (DEPENDS) or soft (SDEPEND) dependency
53 * specified is related to the previously defined PROVIDE feature.
54 * If a plugin feature requires to hook in functionality into the library
55 * or a daemon, it can use REGISTER or CALLBACK entries. Each PROVIDE feature
56 * uses the REGISTER/CALLBACK entry defined previously. The REGISTER entry
57 * defines a common feature registration function directly passed to the
58 * associated manager or factory (crypto/credential factory etc.). A callback
59 * function is more generic allows the loader to invoke a callback to do
60 * the registration. PROVIDE features that do not use a registration or callback
61 * function must be listed before any REGISTER/CALLBACK entry, or use the NOOP
62 * helper macro.
63 *
64 * To conveniently create feature lists, use the macros PLUGIN_REGISTER,
65 * PLUGIN_CALLBACK, PLUGIN_NOOP, PLUGIN_PROVIDE, PLUGIN_DEPENDS and
66 * PLUGIN_SDEPEND. Use indentation to show how the registration functions
67 * and dependencies are related to a provided feature, such as:
68 *
69 * @verbatim
70 // two features, one with two dependencies, both use a callback to register
71 PLUGIN_CALLBACK(...),
72 PLUGIN_PROVIDE(...),
73 PLUGIN_DEPENDS(...),
74 PLUGIN_SDEPEND(...),
75 PLUGIN_PROVIDE(...),
76 // common constructor to register for a feature with one dependency
77 PLUGIN_REGISTER(...),
78 PLUGIN_PROVIDE(...),
79 PLUGIN_DEPENDS(...),
80 // feature that does not use a registration function
81 PLUGIN_NOOP,
82 PLUGIN_PROVIDE(...),
83 @endverbatim
84 */
85 struct plugin_feature_t {
86 /** kind of entry */
87 enum {
88 /* plugin provides this feature */
89 FEATURE_PROVIDE,
90 /* a feature depends on this feature, hard dependency */
91 FEATURE_DEPENDS,
92 /* a feature can optionally use this feature, soft dependency */
93 FEATURE_SDEPEND,
94 /* register the specified function for all following features */
95 FEATURE_REGISTER,
96 /* use a callback to register all following features */
97 FEATURE_CALLBACK,
98 } kind;
99 /* type of feature */
100 enum {
101 /** not a feature */
102 FEATURE_NONE,
103 /** crypter_t */
104 FEATURE_CRYPTER,
105 /** aead_t */
106 FEATURE_AEAD,
107 /** signer_t */
108 FEATURE_SIGNER,
109 /** hasher_t */
110 FEATURE_HASHER,
111 /** prf_t */
112 FEATURE_PRF,
113 /** xof_t */
114 FEATURE_XOF,
115 /** kdf_t */
116 FEATURE_KDF,
117 /** drbg_t */
118 FEATURE_DRBG,
119 /** diffie_hellman_t */
120 FEATURE_DH,
121 /** rng_t */
122 FEATURE_RNG,
123 /** nonce_gen_t */
124 FEATURE_NONCE_GEN,
125 /** generic private key support */
126 FEATURE_PRIVKEY,
127 /** generating new private keys */
128 FEATURE_PRIVKEY_GEN,
129 /** private_key_t->sign() */
130 FEATURE_PRIVKEY_SIGN,
131 /** private_key_t->decrypt() */
132 FEATURE_PRIVKEY_DECRYPT,
133 /** generic public key support */
134 FEATURE_PUBKEY,
135 /** public_key_t->verify() */
136 FEATURE_PUBKEY_VERIFY,
137 /** public_key_t->encrypt() */
138 FEATURE_PUBKEY_ENCRYPT,
139 /** parsing certificates */
140 FEATURE_CERT_DECODE,
141 /** generating certificates */
142 FEATURE_CERT_ENCODE,
143 /** parsing containers */
144 FEATURE_CONTAINER_DECODE,
145 /** generating containers */
146 FEATURE_CONTAINER_ENCODE,
147 /** EAP server implementation */
148 FEATURE_EAP_SERVER,
149 /** EAP peer implementation */
150 FEATURE_EAP_PEER,
151 /** XAuth server implementation */
152 FEATURE_XAUTH_SERVER,
153 /** XAuth peer implementation */
154 FEATURE_XAUTH_PEER,
155 /** database_t */
156 FEATURE_DATABASE,
157 /** fetcher_t */
158 FEATURE_FETCHER,
159 /** resolver_t */
160 FEATURE_RESOLVER,
161 /** custom feature, described with a string */
162 FEATURE_CUSTOM,
163 } type;
164 /** More specific data for each type */
165 union {
166 /** FEATURE_CRYPTER */
167 struct {
168 encryption_algorithm_t alg;
169 size_t key_size;
170 } crypter;
171 /** FEATURE_AEAD */
172 struct {
173 encryption_algorithm_t alg;
174 size_t key_size;
175 } aead;
176 /** FEATURE_SIGNER */
177 integrity_algorithm_t signer;
178 /** FEATURE_PRF */
179 pseudo_random_function_t prf;
180 /** FEATURE_XOF */
181 ext_out_function_t xof;
182 /** FEATURE_KDF */
183 key_derivation_function_t kdf;
184 /** FEATURE_DRBG */
185 drbg_type_t drbg;
186 /** FEATURE_HASHER */
187 hash_algorithm_t hasher;
188 /** FEATURE_DH */
189 diffie_hellman_group_t dh_group;
190 /** FEATURE_RNG */
191 rng_quality_t rng_quality;
192 /** FEATURE_PRIVKEY */
193 key_type_t privkey;
194 /** FEATURE_PRIVKEY_GEN */
195 key_type_t privkey_gen;
196 /** FEATURE_PRIVKEY_SIGN */
197 signature_scheme_t privkey_sign;
198 /** FEATURE_PRIVKEY_DECRYPT */
199 encryption_scheme_t privkey_decrypt;
200 /** FEATURE_PUBKEY */
201 key_type_t pubkey;
202 /** FEATURE_PUBKEY_VERIFY */
203 signature_scheme_t pubkey_verify;
204 /** FEATURE_PUBKEY_ENCRYPT */
205 encryption_scheme_t pubkey_encrypt;
206 /** FEATURE_CERT_DECODE/ENCODE */
207 certificate_type_t cert;
208 /** FEATURE_CONTAINER_DECODE/ENCODE */
209 container_type_t container;
210 /** FEATURE_EAP_SERVER/CLIENT */
211 eap_vendor_type_t eap;
212 /** FEATURE_DATABASE */
213 db_driver_t database;
214 /** FEATURE_FETCHER */
215 char *fetcher;
216 /** FEATURE_CUSTOM */
217 char *custom;
218 /** FEATURE_XAUTH_SERVER/CLIENT */
219 char *xauth;
220
221 /** FEATURE_REGISTER */
222 struct {
223 /** final flag to pass for builder_function_t */
224 bool final;
225 /** feature specific function to register for this type */
226 void *f;
227 } reg;
228
229 /** FEATURE_CALLBACK */
230 struct {
231 /** callback function to invoke for registration */
232 plugin_feature_callback_t f;
233 /** data to pass to callback */
234 void *data;
235 } cb;
236 } arg;
237 };
238
239 #define FEATURE(kind, type, ...) _PLUGIN_FEATURE_##type(kind, __VA_ARGS__)
240
241 /**
242 * Define function to register directly for all upcoming features.
243 *
244 * @param type feature type to register
245 * @param f type specific function to register
246 * @param ... type specific additional arguments
247 */
248 #define PLUGIN_REGISTER(type, f, ...) _PLUGIN_FEATURE_REGISTER_##type(type, f, ##__VA_ARGS__)
249
250 /**
251 * Define a callback to invoke for registering all upcoming features.
252 *
253 * @param cb type specific callback function to register
254 * @param data data pointer to pass to callback
255 */
256 #define PLUGIN_CALLBACK(cb, data) _PLUGIN_FEATURE_CALLBACK(cb, data)
257
258 /**
259 * The upcoming features use neither a callback nor a register function.
260 */
261 #define PLUGIN_NOOP _PLUGIN_FEATURE_CALLBACK(NULL, NULL)
262
263 /**
264 * Define a feature the plugin provides.
265 *
266 * @param type feature type to provide
267 * @param ... type specific arguments
268 */
269 #define PLUGIN_PROVIDE(type, ...) _PLUGIN_FEATURE_##type(PROVIDE, __VA_ARGS__)
270
271 /**
272 * Define a hard dependency for the previously defined feature.
273 *
274 * @param type feature type to provide
275 * @param ... type specific arguments
276 */
277 #define PLUGIN_DEPENDS(type, ...) _PLUGIN_FEATURE_##type(DEPENDS, __VA_ARGS__)
278
279 /**
280 * Define a soft dependency for the previously defined feature.
281 *
282 * @param type feature type to provide
283 * @param ... type specific arguments
284 */
285 #define PLUGIN_SDEPEND(type, ...) _PLUGIN_FEATURE_##type(SDEPEND, __VA_ARGS__)
286
287 #define __PLUGIN_FEATURE(kind, type, ...) (plugin_feature_t){ FEATURE_##kind, FEATURE_##type, { __VA_ARGS__ }}
288 #define _PLUGIN_FEATURE_CRYPTER(kind, alg, size) __PLUGIN_FEATURE(kind, CRYPTER, .crypter = { alg, size })
289 #define _PLUGIN_FEATURE_AEAD(kind, alg, size) __PLUGIN_FEATURE(kind, AEAD, .aead = { alg, size })
290 #define _PLUGIN_FEATURE_SIGNER(kind, alg) __PLUGIN_FEATURE(kind, SIGNER, .signer = alg)
291 #define _PLUGIN_FEATURE_HASHER(kind, alg) __PLUGIN_FEATURE(kind, HASHER, .hasher = alg)
292 #define _PLUGIN_FEATURE_PRF(kind, alg) __PLUGIN_FEATURE(kind, PRF, .prf = alg)
293 #define _PLUGIN_FEATURE_XOF(kind, alg) __PLUGIN_FEATURE(kind, XOF, .xof = alg)
294 #define _PLUGIN_FEATURE_KDF(kind, alg) __PLUGIN_FEATURE(kind, KDF, .kdf = alg)
295 #define _PLUGIN_FEATURE_DRBG(kind, type) __PLUGIN_FEATURE(kind, DRBG, .drbg = type)
296 #define _PLUGIN_FEATURE_DH(kind, group) __PLUGIN_FEATURE(kind, DH, .dh_group = group)
297 #define _PLUGIN_FEATURE_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality)
298 #define _PLUGIN_FEATURE_NONCE_GEN(kind, ...) __PLUGIN_FEATURE(kind, NONCE_GEN, .custom = NULL)
299 #define _PLUGIN_FEATURE_PRIVKEY(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY, .privkey = type)
300 #define _PLUGIN_FEATURE_PRIVKEY_GEN(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY_GEN, .privkey_gen = type)
301 #define _PLUGIN_FEATURE_PRIVKEY_SIGN(kind, scheme) __PLUGIN_FEATURE(kind, PRIVKEY_SIGN, .privkey_sign = scheme)
302 #define _PLUGIN_FEATURE_PRIVKEY_DECRYPT(kind, scheme) __PLUGIN_FEATURE(kind, PRIVKEY_DECRYPT, .privkey_decrypt = scheme)
303 #define _PLUGIN_FEATURE_PUBKEY(kind, type) __PLUGIN_FEATURE(kind, PUBKEY, .pubkey = type)
304 #define _PLUGIN_FEATURE_PUBKEY_VERIFY(kind, scheme) __PLUGIN_FEATURE(kind, PUBKEY_VERIFY, .pubkey_verify = scheme)
305 #define _PLUGIN_FEATURE_PUBKEY_ENCRYPT(kind, scheme) __PLUGIN_FEATURE(kind, PUBKEY_ENCRYPT, .pubkey_encrypt = scheme)
306 #define _PLUGIN_FEATURE_CERT_DECODE(kind, type) __PLUGIN_FEATURE(kind, CERT_DECODE, .cert = type)
307 #define _PLUGIN_FEATURE_CERT_ENCODE(kind, type) __PLUGIN_FEATURE(kind, CERT_ENCODE, .cert = type)
308 #define _PLUGIN_FEATURE_CONTAINER_DECODE(kind, type) __PLUGIN_FEATURE(kind, CONTAINER_DECODE, .container = type)
309 #define _PLUGIN_FEATURE_CONTAINER_ENCODE(kind, type) __PLUGIN_FEATURE(kind, CONTAINER_ENCODE, .container = type)
310 #define _PLUGIN_FEATURE_EAP_SERVER(kind, type) _PLUGIN_FEATURE_EAP_SERVER_VENDOR(kind, type, 0)
311 #define _PLUGIN_FEATURE_EAP_PEER(kind, type) _PLUGIN_FEATURE_EAP_PEER_VENDOR(kind, type, 0)
312 #define _PLUGIN_FEATURE_EAP_SERVER_VENDOR(kind, type, vendor)__PLUGIN_FEATURE(kind, EAP_SERVER, .eap = { type, vendor })
313 #define _PLUGIN_FEATURE_EAP_PEER_VENDOR(kind, type, vendor) __PLUGIN_FEATURE(kind, EAP_PEER, .eap = { type, vendor })
314 #define _PLUGIN_FEATURE_DATABASE(kind, type) __PLUGIN_FEATURE(kind, DATABASE, .database = type)
315 #define _PLUGIN_FEATURE_FETCHER(kind, type) __PLUGIN_FEATURE(kind, FETCHER, .fetcher = type)
316 #define _PLUGIN_FEATURE_RESOLVER(kind, ...) __PLUGIN_FEATURE(kind, RESOLVER, .custom = NULL)
317 #define _PLUGIN_FEATURE_CUSTOM(kind, name) __PLUGIN_FEATURE(kind, CUSTOM, .custom = name)
318 #define _PLUGIN_FEATURE_XAUTH_SERVER(kind, name) __PLUGIN_FEATURE(kind, XAUTH_SERVER, .xauth = name)
319 #define _PLUGIN_FEATURE_XAUTH_PEER(kind, name) __PLUGIN_FEATURE(kind, XAUTH_PEER, .xauth = name)
320
321 #define __PLUGIN_FEATURE_REGISTER(type, _f) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg.f = _f }
322 #define __PLUGIN_FEATURE_REGISTER_BUILDER(type, _f, _final) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg = {.f = _f, .final = _final, }}
323 #define _PLUGIN_FEATURE_REGISTER_CRYPTER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
324 #define _PLUGIN_FEATURE_REGISTER_AEAD(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
325 #define _PLUGIN_FEATURE_REGISTER_SIGNER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
326 #define _PLUGIN_FEATURE_REGISTER_HASHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
327 #define _PLUGIN_FEATURE_REGISTER_PRF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
328 #define _PLUGIN_FEATURE_REGISTER_XOF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
329 #define _PLUGIN_FEATURE_REGISTER_KDF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
330 #define _PLUGIN_FEATURE_REGISTER_DRBG(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
331 #define _PLUGIN_FEATURE_REGISTER_DH(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
332 #define _PLUGIN_FEATURE_REGISTER_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
333 #define _PLUGIN_FEATURE_REGISTER_NONCE_GEN(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
334 #define _PLUGIN_FEATURE_REGISTER_PRIVKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
335 #define _PLUGIN_FEATURE_REGISTER_PRIVKEY_GEN(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
336 #define _PLUGIN_FEATURE_REGISTER_PUBKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
337 #define _PLUGIN_FEATURE_REGISTER_CERT_DECODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
338 #define _PLUGIN_FEATURE_REGISTER_CERT_ENCODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
339 #define _PLUGIN_FEATURE_REGISTER_CONTAINER_DECODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
340 #define _PLUGIN_FEATURE_REGISTER_CONTAINER_ENCODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
341 #define _PLUGIN_FEATURE_REGISTER_DATABASE(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
342 #define _PLUGIN_FEATURE_REGISTER_FETCHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
343 #define _PLUGIN_FEATURE_REGISTER_RESOLVER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
344
345 #define _PLUGIN_FEATURE_CALLBACK(_cb, _data) (plugin_feature_t){ FEATURE_CALLBACK, FEATURE_NONE, .arg.cb = { .f = _cb, .data = _data } }
346
347 /**
348 * Names for plugin_feature_t types.
349 */
350 extern enum_name_t *plugin_feature_names;
351
352 /**
353 * Add a set of plugin features to the given array, which must have enough space
354 * to store the added features.
355 *
356 * @param features the array of plugin features to extend
357 * @param to_add the features to add
358 * @param count number of features to add
359 * @param pos current position in the features array, gets advanced
360 */
361 static inline void plugin_features_add(plugin_feature_t *features,
362 plugin_feature_t *to_add,
363 int count, int *pos)
364 {
365 int i;
366
367 for (i = 0; i < count; i++)
368 {
369 features[(*pos)++] = to_add[i];
370 }
371 }
372
373 /**
374 * Calculates a hash value for the given feature.
375 *
376 * Since this is intended to be used with the plugin_features_matches function
377 * the hash is not really unique for all types of features (e.g. RNGs are all
378 * mapped to the same value because they are loosely matched by said function).
379 *
380 * @param feature feature to hash
381 * @return hash value of the feature
382 */
383 uint32_t plugin_feature_hash(plugin_feature_t *feature);
384
385 /**
386 * Check if feature a matches to feature b.
387 *
388 * This is no check for equality. For instance, for FEATURE_RNG a matches b if
389 * a's strength is at least the strength of b. Or for FEATURE_SQL if a is
390 * DB_ANY it will match b if it is of the same type.
391 *
392 * @param a feature to check
393 * @param b feature to match against
394 * @return TRUE if a matches b
395 */
396 bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b);
397
398 /**
399 * Check if feature a equals feature b.
400 *
401 * @param a feature
402 * @param b feature to compare
403 * @return TRUE if a equals b
404 */
405 bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b);
406
407 /**
408 * Get a string describing feature.
409 *
410 * @param feature feature to describe
411 * @return allocated string describing feature
412 */
413 char* plugin_feature_get_string(plugin_feature_t *feature);
414
415 /**
416 * Load a plugin feature using a REGISTER/CALLBACK feature entry.
417 *
418 * @param plugin plugin providing feature
419 * @param feature feature to load
420 * @param reg REGISTER/CALLBACK feature entry to use for registration
421 */
422 bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
423 plugin_feature_t *reg);
424
425 /**
426 * Unload a plugin feature using a REGISTER/CALLBACK feature entry.
427 *
428 * @param plugin plugin providing feature
429 * @param feature feature to unload
430 * @param reg REGISTER/CALLBACK feature entry to use for deregistration
431 */
432 bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
433 plugin_feature_t *reg);
434
435 #endif /** PLUGIN_FEATURE_H_ @}*/