xof: Defined Extended Output Functions
[strongswan.git] / src / libstrongswan / plugins / plugin_feature.c
1 /*
2 * Copyright (C) 2012-2015 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * Copyright (C) 2011 Martin Willi
6 * Copyright (C) 2011 revosec 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 #define _GNU_SOURCE
20 #include <stdio.h>
21
22 #include "plugin_feature.h"
23
24 #include <utils/debug.h>
25
26 ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
27 "NONE",
28 "CRYPTER",
29 "AEAD",
30 "SIGNER",
31 "HASHER",
32 "PRF",
33 "XOF",
34 "DH",
35 "RNG",
36 "NONCE_GEN",
37 "PRIVKEY",
38 "PRIVKEY_GEN",
39 "PRIVKEY_SIGN",
40 "PRIVKEY_DECRYPT",
41 "PUBKEY",
42 "PUBKEY_VERIFY",
43 "PUBKEY_ENCRYPT",
44 "CERT_DECODE",
45 "CERT_ENCODE",
46 "CONTAINER_DECODE",
47 "CONTAINER_ENCODE",
48 "EAP_SERVER",
49 "EAP_CLIENT",
50 "XAUTH_SERVER",
51 "XAUTH_CLIENT",
52 "DATABASE",
53 "FETCHER",
54 "RESOLVER",
55 "CUSTOM",
56 );
57
58 /**
59 * See header.
60 */
61 uint32_t plugin_feature_hash(plugin_feature_t *feature)
62 {
63 chunk_t data = chunk_empty;
64
65 switch (feature->type)
66 {
67 case FEATURE_NONE:
68 case FEATURE_RNG:
69 case FEATURE_NONCE_GEN:
70 case FEATURE_DATABASE:
71 case FEATURE_FETCHER:
72 case FEATURE_RESOLVER:
73 /* put these special cases in their (type-specific) buckets */
74 data = chunk_empty;
75 break;
76 case FEATURE_CRYPTER:
77 data = chunk_from_thing(feature->arg.crypter);
78 break;
79 case FEATURE_AEAD:
80 data = chunk_from_thing(feature->arg.aead);
81 break;
82 case FEATURE_SIGNER:
83 data = chunk_from_thing(feature->arg.signer);
84 break;
85 case FEATURE_HASHER:
86 data = chunk_from_thing(feature->arg.hasher);
87 break;
88 case FEATURE_PRF:
89 data = chunk_from_thing(feature->arg.prf);
90 break;
91 case FEATURE_XOF:
92 data = chunk_from_thing(feature->arg.xof);
93 break;
94 case FEATURE_DH:
95 data = chunk_from_thing(feature->arg.dh_group);
96 break;
97 case FEATURE_PRIVKEY:
98 data = chunk_from_thing(feature->arg.privkey);
99 break;
100 case FEATURE_PRIVKEY_GEN:
101 data = chunk_from_thing(feature->arg.privkey_gen);
102 break;
103 case FEATURE_PUBKEY:
104 data = chunk_from_thing(feature->arg.pubkey);
105 break;
106 case FEATURE_PRIVKEY_SIGN:
107 data = chunk_from_thing(feature->arg.privkey_sign);
108 break;
109 case FEATURE_PUBKEY_VERIFY:
110 data = chunk_from_thing(feature->arg.pubkey_verify);
111 break;
112 case FEATURE_PRIVKEY_DECRYPT:
113 data = chunk_from_thing(feature->arg.privkey_decrypt);
114 break;
115 case FEATURE_PUBKEY_ENCRYPT:
116 data = chunk_from_thing(feature->arg.pubkey_encrypt);
117 break;
118 case FEATURE_CERT_DECODE:
119 case FEATURE_CERT_ENCODE:
120 data = chunk_from_thing(feature->arg.cert);
121 break;
122 case FEATURE_CONTAINER_DECODE:
123 case FEATURE_CONTAINER_ENCODE:
124 data = chunk_from_thing(feature->arg.container);
125 break;
126 case FEATURE_EAP_SERVER:
127 case FEATURE_EAP_PEER:
128 data = chunk_from_thing(feature->arg.eap);
129 break;
130 case FEATURE_CUSTOM:
131 data = chunk_create(feature->arg.custom,
132 strlen(feature->arg.custom));
133 break;
134 case FEATURE_XAUTH_SERVER:
135 case FEATURE_XAUTH_PEER:
136 data = chunk_create(feature->arg.xauth,
137 strlen(feature->arg.xauth));
138 break;
139 }
140 return chunk_hash_inc(chunk_from_thing(feature->type),
141 chunk_hash(data));
142 }
143
144 /**
145 * See header.
146 */
147 bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
148 {
149 if (a->type == b->type)
150 {
151 switch (a->type)
152 {
153 case FEATURE_NONE:
154 return FALSE;
155 case FEATURE_CRYPTER:
156 return a->arg.crypter.alg == b->arg.crypter.alg &&
157 a->arg.crypter.key_size == b->arg.crypter.key_size;
158 case FEATURE_AEAD:
159 return a->arg.aead.alg == b->arg.aead.alg &&
160 a->arg.aead.key_size == b->arg.aead.key_size;
161 case FEATURE_SIGNER:
162 return a->arg.signer == b->arg.signer;
163 case FEATURE_HASHER:
164 return a->arg.hasher == b->arg.hasher;
165 case FEATURE_PRF:
166 return a->arg.prf == b->arg.prf;
167 case FEATURE_XOF:
168 return a->arg.xof == b->arg.xof;
169 case FEATURE_DH:
170 return a->arg.dh_group == b->arg.dh_group;
171 case FEATURE_RNG:
172 return a->arg.rng_quality <= b->arg.rng_quality;
173 case FEATURE_NONCE_GEN:
174 case FEATURE_RESOLVER:
175 return TRUE;
176 case FEATURE_PRIVKEY:
177 case FEATURE_PRIVKEY_GEN:
178 case FEATURE_PUBKEY:
179 return a->arg.privkey == b->arg.privkey;
180 case FEATURE_PRIVKEY_SIGN:
181 case FEATURE_PUBKEY_VERIFY:
182 return a->arg.privkey_sign == b->arg.privkey_sign;
183 case FEATURE_PRIVKEY_DECRYPT:
184 case FEATURE_PUBKEY_ENCRYPT:
185 return a->arg.privkey_decrypt == b->arg.privkey_decrypt;
186 case FEATURE_CERT_DECODE:
187 case FEATURE_CERT_ENCODE:
188 return a->arg.cert == b->arg.cert;
189 case FEATURE_CONTAINER_DECODE:
190 case FEATURE_CONTAINER_ENCODE:
191 return a->arg.container == b->arg.container;
192 case FEATURE_EAP_SERVER:
193 case FEATURE_EAP_PEER:
194 return a->arg.eap.vendor == b->arg.eap.vendor &&
195 a->arg.eap.type == b->arg.eap.type;
196 case FEATURE_DATABASE:
197 return a->arg.database == DB_ANY ||
198 a->arg.database == b->arg.database;
199 case FEATURE_FETCHER:
200 return a->arg.fetcher == NULL ||
201 streq(a->arg.fetcher, b->arg.fetcher);
202 case FEATURE_CUSTOM:
203 return streq(a->arg.custom, b->arg.custom);
204 case FEATURE_XAUTH_SERVER:
205 case FEATURE_XAUTH_PEER:
206 return streq(a->arg.xauth, b->arg.xauth);
207 }
208 }
209 return FALSE;
210 }
211
212 /**
213 * See header.
214 */
215 bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b)
216 {
217 if (a->type == b->type)
218 {
219 switch (a->type)
220 {
221 case FEATURE_NONE:
222 case FEATURE_CRYPTER:
223 case FEATURE_AEAD:
224 case FEATURE_SIGNER:
225 case FEATURE_HASHER:
226 case FEATURE_PRF:
227 case FEATURE_XOF:
228 case FEATURE_DH:
229 case FEATURE_NONCE_GEN:
230 case FEATURE_RESOLVER:
231 case FEATURE_PRIVKEY:
232 case FEATURE_PRIVKEY_GEN:
233 case FEATURE_PUBKEY:
234 case FEATURE_PRIVKEY_SIGN:
235 case FEATURE_PUBKEY_VERIFY:
236 case FEATURE_PRIVKEY_DECRYPT:
237 case FEATURE_PUBKEY_ENCRYPT:
238 case FEATURE_CERT_DECODE:
239 case FEATURE_CERT_ENCODE:
240 case FEATURE_CONTAINER_DECODE:
241 case FEATURE_CONTAINER_ENCODE:
242 case FEATURE_EAP_SERVER:
243 case FEATURE_EAP_PEER:
244 case FEATURE_CUSTOM:
245 case FEATURE_XAUTH_SERVER:
246 case FEATURE_XAUTH_PEER:
247 return plugin_feature_matches(a, b);
248 case FEATURE_RNG:
249 return a->arg.rng_quality == b->arg.rng_quality;
250 case FEATURE_DATABASE:
251 return a->arg.database == b->arg.database;
252 case FEATURE_FETCHER:
253 if (a->arg.fetcher && b->arg.fetcher)
254 {
255 return streq(a->arg.fetcher, b->arg.fetcher);
256 }
257 return !a->arg.fetcher && !b->arg.fetcher;
258 }
259 }
260 return FALSE;
261 }
262
263 /**
264 * See header.
265 */
266 char* plugin_feature_get_string(plugin_feature_t *feature)
267 {
268 char *str = NULL;
269
270 if (feature->kind == FEATURE_REGISTER)
271 {
272 return strdup("(register function)");
273 }
274 switch (feature->type)
275 {
276 case FEATURE_NONE:
277 return strdup("NONE");
278 case FEATURE_CRYPTER:
279 if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
280 encryption_algorithm_names, feature->arg.crypter.alg,
281 feature->arg.crypter.key_size) > 0)
282 {
283 return str;
284 }
285 break;
286 case FEATURE_AEAD:
287 if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
288 encryption_algorithm_names, feature->arg.aead.alg,
289 feature->arg.aead.key_size) > 0)
290 {
291 return str;
292 }
293 break;
294 case FEATURE_SIGNER:
295 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
296 integrity_algorithm_names, feature->arg.signer) > 0)
297 {
298 return str;
299 }
300 break;
301 case FEATURE_HASHER:
302 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
303 hash_algorithm_names, feature->arg.hasher) > 0)
304 {
305 return str;
306 }
307 break;
308 case FEATURE_PRF:
309 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
310 pseudo_random_function_names, feature->arg.prf) > 0)
311 {
312 return str;
313 }
314 break;
315 case FEATURE_XOF:
316 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
317 ext_out_function_names, feature->arg.xof) > 0)
318 {
319 return str;
320 }
321 break;
322 case FEATURE_DH:
323 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
324 diffie_hellman_group_names, feature->arg.dh_group) > 0)
325 {
326 return str;
327 }
328 break;
329 case FEATURE_RNG:
330 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
331 rng_quality_names, feature->arg.rng_quality) > 0)
332 {
333 return str;
334 }
335 break;
336 case FEATURE_NONCE_GEN:
337 case FEATURE_RESOLVER:
338 if (asprintf(&str, "%N", plugin_feature_names, feature->type) > 0)
339 {
340 return str;
341 }
342 break;
343 case FEATURE_PRIVKEY:
344 case FEATURE_PRIVKEY_GEN:
345 case FEATURE_PUBKEY:
346 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
347 key_type_names, feature->arg.privkey) > 0)
348 {
349 return str;
350 }
351 break;
352 case FEATURE_PRIVKEY_SIGN:
353 case FEATURE_PUBKEY_VERIFY:
354 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
355 signature_scheme_names, feature->arg.privkey_sign) > 0)
356 {
357 return str;
358 }
359 break;
360 case FEATURE_PRIVKEY_DECRYPT:
361 case FEATURE_PUBKEY_ENCRYPT:
362 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
363 encryption_scheme_names, feature->arg.privkey_decrypt) > 0)
364 {
365 return str;
366 }
367 break;
368 case FEATURE_CERT_DECODE:
369 case FEATURE_CERT_ENCODE:
370 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
371 certificate_type_names, feature->arg.cert) > 0)
372 {
373 return str;
374 }
375 break;
376 case FEATURE_CONTAINER_DECODE:
377 case FEATURE_CONTAINER_ENCODE:
378 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
379 container_type_names, feature->arg.container) > 0)
380 {
381 return str;
382 }
383 break;
384 case FEATURE_EAP_SERVER:
385 case FEATURE_EAP_PEER:
386 if (feature->arg.eap.vendor &&
387 asprintf(&str, "%N:%d-%d", plugin_feature_names, feature->type,
388 feature->arg.eap.type, feature->arg.eap.vendor) > 0)
389 {
390 return str;
391 }
392 else if (!feature->arg.eap.vendor &&
393 asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
394 eap_type_short_names, feature->arg.eap.type) > 0)
395 {
396 return str;
397 }
398 break;
399 case FEATURE_DATABASE:
400 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
401 db_driver_names, feature->arg.database) > 0)
402 {
403 return str;
404 }
405 break;
406 case FEATURE_FETCHER:
407 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
408 feature->arg.fetcher) > 0)
409 {
410 return str;
411 }
412 break;
413 case FEATURE_CUSTOM:
414 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
415 feature->arg.custom) > 0)
416 {
417 return str;
418 }
419 break;
420 case FEATURE_XAUTH_SERVER:
421 case FEATURE_XAUTH_PEER:
422 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
423 feature->arg.xauth) > 0)
424 {
425 return str;
426 }
427 break;
428 }
429 if (!str)
430 {
431 str = strdup("(invalid)");
432 }
433 return str;
434 }
435
436 /**
437 * See header.
438 */
439 bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
440 plugin_feature_t *reg)
441 {
442 char *name;
443
444 if (!reg)
445 { /* noting to do for this feature */
446 return TRUE;
447 }
448 if (reg->kind == FEATURE_CALLBACK)
449 {
450 if (!reg->arg.cb.f ||
451 reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data))
452 {
453 return TRUE;
454 }
455 return FALSE;
456 }
457 name = plugin->get_name(plugin);
458 switch (feature->type)
459 {
460 case FEATURE_CRYPTER:
461 lib->crypto->add_crypter(lib->crypto, feature->arg.crypter.alg,
462 feature->arg.crypter.key_size,
463 name, reg->arg.reg.f);
464 break;
465 case FEATURE_AEAD:
466 lib->crypto->add_aead(lib->crypto, feature->arg.aead.alg,
467 feature->arg.aead.key_size,
468 name, reg->arg.reg.f);
469 break;
470 case FEATURE_SIGNER:
471 lib->crypto->add_signer(lib->crypto, feature->arg.signer,
472 name, reg->arg.reg.f);
473 break;
474 case FEATURE_HASHER:
475 lib->crypto->add_hasher(lib->crypto, feature->arg.hasher,
476 name, reg->arg.reg.f);
477 break;
478 case FEATURE_PRF:
479 lib->crypto->add_prf(lib->crypto, feature->arg.prf,
480 name, reg->arg.reg.f);
481 break;
482 case FEATURE_XOF:
483 lib->crypto->add_xof(lib->crypto, feature->arg.xof,
484 name, reg->arg.reg.f);
485 break;
486 case FEATURE_DH:
487 lib->crypto->add_dh(lib->crypto, feature->arg.dh_group,
488 name, reg->arg.reg.f);
489 break;
490 case FEATURE_RNG:
491 lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality,
492 name, reg->arg.reg.f);
493 break;
494 case FEATURE_NONCE_GEN:
495 lib->crypto->add_nonce_gen(lib->crypto,
496 name, reg->arg.reg.f);
497 break;
498 case FEATURE_PRIVKEY:
499 case FEATURE_PRIVKEY_GEN:
500 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY,
501 feature->arg.privkey, reg->arg.reg.final,
502 reg->arg.reg.f);
503 break;
504 case FEATURE_PUBKEY:
505 lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY,
506 feature->arg.pubkey, reg->arg.reg.final,
507 reg->arg.reg.f);
508 break;
509 case FEATURE_CERT_DECODE:
510 case FEATURE_CERT_ENCODE:
511 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE,
512 feature->arg.cert, reg->arg.reg.final,
513 reg->arg.reg.f);
514 break;
515 case FEATURE_CONTAINER_DECODE:
516 case FEATURE_CONTAINER_ENCODE:
517 lib->creds->add_builder(lib->creds, CRED_CONTAINER,
518 feature->arg.container, reg->arg.reg.final,
519 reg->arg.reg.f);
520 break;
521 case FEATURE_DATABASE:
522 lib->db->add_database(lib->db, reg->arg.reg.f);
523 break;
524 case FEATURE_FETCHER:
525 lib->fetcher->add_fetcher(lib->fetcher, reg->arg.reg.f,
526 feature->arg.fetcher);
527 break;
528 case FEATURE_RESOLVER:
529 lib->resolver->add_resolver(lib->resolver, reg->arg.reg.f);
530 break;
531 default:
532 break;
533 }
534 return TRUE;
535 }
536
537 /**
538 * See header.
539 */
540 bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
541 plugin_feature_t *reg)
542 {
543 if (!reg)
544 { /* noting to do for this feature */
545 return TRUE;
546 }
547 if (reg->kind == FEATURE_CALLBACK)
548 {
549 if (!reg->arg.cb.f ||
550 reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data))
551 {
552 return TRUE;
553 }
554 return FALSE;
555 }
556 switch (feature->type)
557 {
558 case FEATURE_CRYPTER:
559 lib->crypto->remove_crypter(lib->crypto, reg->arg.reg.f);
560 break;
561 case FEATURE_AEAD:
562 lib->crypto->remove_aead(lib->crypto, reg->arg.reg.f);
563 break;
564 case FEATURE_SIGNER:
565 lib->crypto->remove_signer(lib->crypto, reg->arg.reg.f);
566 break;
567 case FEATURE_HASHER:
568 lib->crypto->remove_hasher(lib->crypto, reg->arg.reg.f);
569 break;
570 case FEATURE_PRF:
571 lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f);
572 break;
573 case FEATURE_XOF:
574 lib->crypto->remove_xof(lib->crypto, reg->arg.reg.f);
575 break;
576 case FEATURE_DH:
577 lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f);
578 break;
579 case FEATURE_RNG:
580 lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f);
581 break;
582 case FEATURE_NONCE_GEN:
583 lib->crypto->remove_nonce_gen(lib->crypto, reg->arg.reg.f);
584 break;
585 case FEATURE_PRIVKEY:
586 case FEATURE_PRIVKEY_GEN:
587 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
588 break;
589 case FEATURE_PUBKEY:
590 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
591 break;
592 case FEATURE_CERT_DECODE:
593 case FEATURE_CERT_ENCODE:
594 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
595 break;
596 case FEATURE_CONTAINER_DECODE:
597 case FEATURE_CONTAINER_ENCODE:
598 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
599 break;
600 case FEATURE_DATABASE:
601 lib->db->remove_database(lib->db, reg->arg.reg.f);
602 break;
603 case FEATURE_FETCHER:
604 lib->fetcher->remove_fetcher(lib->fetcher, reg->arg.reg.f);
605 break;
606 case FEATURE_RESOLVER:
607 lib->resolver->remove_resolver(lib->resolver, reg->arg.reg.f);
608 break;
609 default:
610 break;
611 }
612 return TRUE;
613 }