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