2 * Copyright (C) 2012-2015 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2011 Martin Willi
6 * Copyright (C) 2011 revosec AG
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>.
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
22 #include "plugin_feature.h"
24 #include <utils/debug.h>
26 ENUM(plugin_feature_names
, FEATURE_NONE
, FEATURE_CUSTOM
,
61 uint32_t plugin_feature_hash(plugin_feature_t
*feature
)
63 chunk_t data
= chunk_empty
;
65 switch (feature
->type
)
69 case FEATURE_NONCE_GEN
:
70 case FEATURE_DATABASE
:
72 case FEATURE_RESOLVER
:
73 /* put these special cases in their (type-specific) buckets */
77 data
= chunk_from_thing(feature
->arg
.crypter
);
80 data
= chunk_from_thing(feature
->arg
.aead
);
83 data
= chunk_from_thing(feature
->arg
.signer
);
86 data
= chunk_from_thing(feature
->arg
.hasher
);
89 data
= chunk_from_thing(feature
->arg
.prf
);
92 data
= chunk_from_thing(feature
->arg
.xof
);
95 data
= chunk_from_thing(feature
->arg
.dh_group
);
98 data
= chunk_from_thing(feature
->arg
.privkey
);
100 case FEATURE_PRIVKEY_GEN
:
101 data
= chunk_from_thing(feature
->arg
.privkey_gen
);
104 data
= chunk_from_thing(feature
->arg
.pubkey
);
106 case FEATURE_PRIVKEY_SIGN
:
107 data
= chunk_from_thing(feature
->arg
.privkey_sign
);
109 case FEATURE_PUBKEY_VERIFY
:
110 data
= chunk_from_thing(feature
->arg
.pubkey_verify
);
112 case FEATURE_PRIVKEY_DECRYPT
:
113 data
= chunk_from_thing(feature
->arg
.privkey_decrypt
);
115 case FEATURE_PUBKEY_ENCRYPT
:
116 data
= chunk_from_thing(feature
->arg
.pubkey_encrypt
);
118 case FEATURE_CERT_DECODE
:
119 case FEATURE_CERT_ENCODE
:
120 data
= chunk_from_thing(feature
->arg
.cert
);
122 case FEATURE_CONTAINER_DECODE
:
123 case FEATURE_CONTAINER_ENCODE
:
124 data
= chunk_from_thing(feature
->arg
.container
);
126 case FEATURE_EAP_SERVER
:
127 case FEATURE_EAP_PEER
:
128 data
= chunk_from_thing(feature
->arg
.eap
);
131 data
= chunk_create(feature
->arg
.custom
,
132 strlen(feature
->arg
.custom
));
134 case FEATURE_XAUTH_SERVER
:
135 case FEATURE_XAUTH_PEER
:
136 data
= chunk_create(feature
->arg
.xauth
,
137 strlen(feature
->arg
.xauth
));
140 return chunk_hash_inc(chunk_from_thing(feature
->type
),
147 bool plugin_feature_matches(plugin_feature_t
*a
, plugin_feature_t
*b
)
149 if (a
->type
== b
->type
)
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
;
159 return a
->arg
.aead
.alg
== b
->arg
.aead
.alg
&&
160 a
->arg
.aead
.key_size
== b
->arg
.aead
.key_size
;
162 return a
->arg
.signer
== b
->arg
.signer
;
164 return a
->arg
.hasher
== b
->arg
.hasher
;
166 return a
->arg
.prf
== b
->arg
.prf
;
168 return a
->arg
.xof
== b
->arg
.xof
;
170 return a
->arg
.dh_group
== b
->arg
.dh_group
;
172 return a
->arg
.rng_quality
<= b
->arg
.rng_quality
;
173 case FEATURE_NONCE_GEN
:
174 case FEATURE_RESOLVER
:
176 case FEATURE_PRIVKEY
:
177 case FEATURE_PRIVKEY_GEN
:
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
);
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
);
215 bool plugin_feature_equals(plugin_feature_t
*a
, plugin_feature_t
*b
)
217 if (a
->type
== b
->type
)
222 case FEATURE_CRYPTER
:
229 case FEATURE_NONCE_GEN
:
230 case FEATURE_RESOLVER
:
231 case FEATURE_PRIVKEY
:
232 case FEATURE_PRIVKEY_GEN
:
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
:
245 case FEATURE_XAUTH_SERVER
:
246 case FEATURE_XAUTH_PEER
:
247 return plugin_feature_matches(a
, b
);
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
)
255 return streq(a
->arg
.fetcher
, b
->arg
.fetcher
);
257 return !a
->arg
.fetcher
&& !b
->arg
.fetcher
;
266 char* plugin_feature_get_string(plugin_feature_t
*feature
)
270 if (feature
->kind
== FEATURE_REGISTER
)
272 return strdup("(register function)");
274 switch (feature
->type
)
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)
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)
295 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
296 integrity_algorithm_names
, feature
->arg
.signer
) > 0)
302 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
303 hash_algorithm_names
, feature
->arg
.hasher
) > 0)
309 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
310 pseudo_random_function_names
, feature
->arg
.prf
) > 0)
316 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
317 ext_out_function_names
, feature
->arg
.xof
) > 0)
323 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
324 diffie_hellman_group_names
, feature
->arg
.dh_group
) > 0)
330 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
331 rng_quality_names
, feature
->arg
.rng_quality
) > 0)
336 case FEATURE_NONCE_GEN
:
337 case FEATURE_RESOLVER
:
338 if (asprintf(&str
, "%N", plugin_feature_names
, feature
->type
) > 0)
343 case FEATURE_PRIVKEY
:
344 case FEATURE_PRIVKEY_GEN
:
346 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
347 key_type_names
, feature
->arg
.privkey
) > 0)
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)
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)
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)
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)
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)
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)
399 case FEATURE_DATABASE
:
400 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
401 db_driver_names
, feature
->arg
.database
) > 0)
406 case FEATURE_FETCHER
:
407 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
408 feature
->arg
.fetcher
) > 0)
414 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
415 feature
->arg
.custom
) > 0)
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)
431 str
= strdup("(invalid)");
439 bool plugin_feature_load(plugin_t
*plugin
, plugin_feature_t
*feature
,
440 plugin_feature_t
*reg
)
445 { /* noting to do for this feature */
448 if (reg
->kind
== FEATURE_CALLBACK
)
450 if (!reg
->arg
.cb
.f
||
451 reg
->arg
.cb
.f(plugin
, feature
, TRUE
, reg
->arg
.cb
.data
))
457 name
= plugin
->get_name(plugin
);
458 switch (feature
->type
)
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
);
466 lib
->crypto
->add_aead(lib
->crypto
, feature
->arg
.aead
.alg
,
467 feature
->arg
.aead
.key_size
,
468 name
, reg
->arg
.reg
.f
);
471 lib
->crypto
->add_signer(lib
->crypto
, feature
->arg
.signer
,
472 name
, reg
->arg
.reg
.f
);
475 lib
->crypto
->add_hasher(lib
->crypto
, feature
->arg
.hasher
,
476 name
, reg
->arg
.reg
.f
);
479 lib
->crypto
->add_prf(lib
->crypto
, feature
->arg
.prf
,
480 name
, reg
->arg
.reg
.f
);
483 lib
->crypto
->add_xof(lib
->crypto
, feature
->arg
.xof
,
484 name
, reg
->arg
.reg
.f
);
487 lib
->crypto
->add_dh(lib
->crypto
, feature
->arg
.dh_group
,
488 name
, reg
->arg
.reg
.f
);
491 lib
->crypto
->add_rng(lib
->crypto
, feature
->arg
.rng_quality
,
492 name
, reg
->arg
.reg
.f
);
494 case FEATURE_NONCE_GEN
:
495 lib
->crypto
->add_nonce_gen(lib
->crypto
,
496 name
, reg
->arg
.reg
.f
);
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
,
505 lib
->creds
->add_builder(lib
->creds
, CRED_PUBLIC_KEY
,
506 feature
->arg
.pubkey
, reg
->arg
.reg
.final
,
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
,
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
,
521 case FEATURE_DATABASE
:
522 lib
->db
->add_database(lib
->db
, reg
->arg
.reg
.f
);
524 case FEATURE_FETCHER
:
525 lib
->fetcher
->add_fetcher(lib
->fetcher
, reg
->arg
.reg
.f
,
526 feature
->arg
.fetcher
);
528 case FEATURE_RESOLVER
:
529 lib
->resolver
->add_resolver(lib
->resolver
, reg
->arg
.reg
.f
);
540 bool plugin_feature_unload(plugin_t
*plugin
, plugin_feature_t
*feature
,
541 plugin_feature_t
*reg
)
544 { /* noting to do for this feature */
547 if (reg
->kind
== FEATURE_CALLBACK
)
549 if (!reg
->arg
.cb
.f
||
550 reg
->arg
.cb
.f(plugin
, feature
, FALSE
, reg
->arg
.cb
.data
))
556 switch (feature
->type
)
558 case FEATURE_CRYPTER
:
559 lib
->crypto
->remove_crypter(lib
->crypto
, reg
->arg
.reg
.f
);
562 lib
->crypto
->remove_aead(lib
->crypto
, reg
->arg
.reg
.f
);
565 lib
->crypto
->remove_signer(lib
->crypto
, reg
->arg
.reg
.f
);
568 lib
->crypto
->remove_hasher(lib
->crypto
, reg
->arg
.reg
.f
);
571 lib
->crypto
->remove_prf(lib
->crypto
, reg
->arg
.reg
.f
);
574 lib
->crypto
->remove_xof(lib
->crypto
, reg
->arg
.reg
.f
);
577 lib
->crypto
->remove_dh(lib
->crypto
, reg
->arg
.reg
.f
);
580 lib
->crypto
->remove_rng(lib
->crypto
, reg
->arg
.reg
.f
);
582 case FEATURE_NONCE_GEN
:
583 lib
->crypto
->remove_nonce_gen(lib
->crypto
, reg
->arg
.reg
.f
);
585 case FEATURE_PRIVKEY
:
586 case FEATURE_PRIVKEY_GEN
:
587 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
590 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
592 case FEATURE_CERT_DECODE
:
593 case FEATURE_CERT_ENCODE
:
594 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
596 case FEATURE_CONTAINER_DECODE
:
597 case FEATURE_CONTAINER_ENCODE
:
598 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
600 case FEATURE_DATABASE
:
601 lib
->db
->remove_database(lib
->db
, reg
->arg
.reg
.f
);
603 case FEATURE_FETCHER
:
604 lib
->fetcher
->remove_fetcher(lib
->fetcher
, reg
->arg
.reg
.f
);
606 case FEATURE_RESOLVER
:
607 lib
->resolver
->remove_resolver(lib
->resolver
, reg
->arg
.reg
.f
);