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
,
60 uint32_t plugin_feature_hash(plugin_feature_t
*feature
)
62 chunk_t data
= chunk_empty
;
64 switch (feature
->type
)
68 case FEATURE_NONCE_GEN
:
69 case FEATURE_DATABASE
:
71 case FEATURE_RESOLVER
:
72 /* put these special cases in their (type-specific) buckets */
76 data
= chunk_from_thing(feature
->arg
.crypter
);
79 data
= chunk_from_thing(feature
->arg
.aead
);
82 data
= chunk_from_thing(feature
->arg
.signer
);
85 data
= chunk_from_thing(feature
->arg
.hasher
);
88 data
= chunk_from_thing(feature
->arg
.prf
);
91 data
= chunk_from_thing(feature
->arg
.dh_group
);
94 data
= chunk_from_thing(feature
->arg
.privkey
);
96 case FEATURE_PRIVKEY_GEN
:
97 data
= chunk_from_thing(feature
->arg
.privkey_gen
);
100 data
= chunk_from_thing(feature
->arg
.pubkey
);
102 case FEATURE_PRIVKEY_SIGN
:
103 data
= chunk_from_thing(feature
->arg
.privkey_sign
);
105 case FEATURE_PUBKEY_VERIFY
:
106 data
= chunk_from_thing(feature
->arg
.pubkey_verify
);
108 case FEATURE_PRIVKEY_DECRYPT
:
109 data
= chunk_from_thing(feature
->arg
.privkey_decrypt
);
111 case FEATURE_PUBKEY_ENCRYPT
:
112 data
= chunk_from_thing(feature
->arg
.pubkey_encrypt
);
114 case FEATURE_CERT_DECODE
:
115 case FEATURE_CERT_ENCODE
:
116 data
= chunk_from_thing(feature
->arg
.cert
);
118 case FEATURE_CONTAINER_DECODE
:
119 case FEATURE_CONTAINER_ENCODE
:
120 data
= chunk_from_thing(feature
->arg
.container
);
122 case FEATURE_EAP_SERVER
:
123 case FEATURE_EAP_PEER
:
124 data
= chunk_from_thing(feature
->arg
.eap
);
127 data
= chunk_create(feature
->arg
.custom
,
128 strlen(feature
->arg
.custom
));
130 case FEATURE_XAUTH_SERVER
:
131 case FEATURE_XAUTH_PEER
:
132 data
= chunk_create(feature
->arg
.xauth
,
133 strlen(feature
->arg
.xauth
));
136 return chunk_hash_inc(chunk_from_thing(feature
->type
),
143 bool plugin_feature_matches(plugin_feature_t
*a
, plugin_feature_t
*b
)
145 if (a
->type
== b
->type
)
151 case FEATURE_CRYPTER
:
152 return a
->arg
.crypter
.alg
== b
->arg
.crypter
.alg
&&
153 a
->arg
.crypter
.key_size
== b
->arg
.crypter
.key_size
;
155 return a
->arg
.aead
.alg
== b
->arg
.aead
.alg
&&
156 a
->arg
.aead
.key_size
== b
->arg
.aead
.key_size
;
158 return a
->arg
.signer
== b
->arg
.signer
;
160 return a
->arg
.hasher
== b
->arg
.hasher
;
162 return a
->arg
.prf
== b
->arg
.prf
;
164 return a
->arg
.dh_group
== b
->arg
.dh_group
;
166 return a
->arg
.rng_quality
<= b
->arg
.rng_quality
;
167 case FEATURE_NONCE_GEN
:
168 case FEATURE_RESOLVER
:
170 case FEATURE_PRIVKEY
:
171 case FEATURE_PRIVKEY_GEN
:
173 return a
->arg
.privkey
== b
->arg
.privkey
;
174 case FEATURE_PRIVKEY_SIGN
:
175 case FEATURE_PUBKEY_VERIFY
:
176 return a
->arg
.privkey_sign
== b
->arg
.privkey_sign
;
177 case FEATURE_PRIVKEY_DECRYPT
:
178 case FEATURE_PUBKEY_ENCRYPT
:
179 return a
->arg
.privkey_decrypt
== b
->arg
.privkey_decrypt
;
180 case FEATURE_CERT_DECODE
:
181 case FEATURE_CERT_ENCODE
:
182 return a
->arg
.cert
== b
->arg
.cert
;
183 case FEATURE_CONTAINER_DECODE
:
184 case FEATURE_CONTAINER_ENCODE
:
185 return a
->arg
.container
== b
->arg
.container
;
186 case FEATURE_EAP_SERVER
:
187 case FEATURE_EAP_PEER
:
188 return a
->arg
.eap
.vendor
== b
->arg
.eap
.vendor
&&
189 a
->arg
.eap
.type
== b
->arg
.eap
.type
;
190 case FEATURE_DATABASE
:
191 return a
->arg
.database
== DB_ANY
||
192 a
->arg
.database
== b
->arg
.database
;
193 case FEATURE_FETCHER
:
194 return a
->arg
.fetcher
== NULL
||
195 streq(a
->arg
.fetcher
, b
->arg
.fetcher
);
197 return streq(a
->arg
.custom
, b
->arg
.custom
);
198 case FEATURE_XAUTH_SERVER
:
199 case FEATURE_XAUTH_PEER
:
200 return streq(a
->arg
.xauth
, b
->arg
.xauth
);
209 bool plugin_feature_equals(plugin_feature_t
*a
, plugin_feature_t
*b
)
211 if (a
->type
== b
->type
)
216 case FEATURE_CRYPTER
:
222 case FEATURE_NONCE_GEN
:
223 case FEATURE_RESOLVER
:
224 case FEATURE_PRIVKEY
:
225 case FEATURE_PRIVKEY_GEN
:
227 case FEATURE_PRIVKEY_SIGN
:
228 case FEATURE_PUBKEY_VERIFY
:
229 case FEATURE_PRIVKEY_DECRYPT
:
230 case FEATURE_PUBKEY_ENCRYPT
:
231 case FEATURE_CERT_DECODE
:
232 case FEATURE_CERT_ENCODE
:
233 case FEATURE_CONTAINER_DECODE
:
234 case FEATURE_CONTAINER_ENCODE
:
235 case FEATURE_EAP_SERVER
:
236 case FEATURE_EAP_PEER
:
238 case FEATURE_XAUTH_SERVER
:
239 case FEATURE_XAUTH_PEER
:
240 return plugin_feature_matches(a
, b
);
242 return a
->arg
.rng_quality
== b
->arg
.rng_quality
;
243 case FEATURE_DATABASE
:
244 return a
->arg
.database
== b
->arg
.database
;
245 case FEATURE_FETCHER
:
246 if (a
->arg
.fetcher
&& b
->arg
.fetcher
)
248 return streq(a
->arg
.fetcher
, b
->arg
.fetcher
);
250 return !a
->arg
.fetcher
&& !b
->arg
.fetcher
;
259 char* plugin_feature_get_string(plugin_feature_t
*feature
)
263 if (feature
->kind
== FEATURE_REGISTER
)
265 return strdup("(register function)");
267 switch (feature
->type
)
270 return strdup("NONE");
271 case FEATURE_CRYPTER
:
272 if (asprintf(&str
, "%N:%N-%d", plugin_feature_names
, feature
->type
,
273 encryption_algorithm_names
, feature
->arg
.crypter
.alg
,
274 feature
->arg
.crypter
.key_size
) > 0)
280 if (asprintf(&str
, "%N:%N-%d", plugin_feature_names
, feature
->type
,
281 encryption_algorithm_names
, feature
->arg
.aead
.alg
,
282 feature
->arg
.aead
.key_size
) > 0)
288 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
289 integrity_algorithm_names
, feature
->arg
.signer
) > 0)
295 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
296 hash_algorithm_names
, feature
->arg
.hasher
) > 0)
302 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
303 pseudo_random_function_names
, feature
->arg
.prf
) > 0)
309 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
310 diffie_hellman_group_names
, feature
->arg
.dh_group
) > 0)
316 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
317 rng_quality_names
, feature
->arg
.rng_quality
) > 0)
322 case FEATURE_NONCE_GEN
:
323 case FEATURE_RESOLVER
:
324 if (asprintf(&str
, "%N", plugin_feature_names
, feature
->type
) > 0)
329 case FEATURE_PRIVKEY
:
330 case FEATURE_PRIVKEY_GEN
:
332 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
333 key_type_names
, feature
->arg
.privkey
) > 0)
338 case FEATURE_PRIVKEY_SIGN
:
339 case FEATURE_PUBKEY_VERIFY
:
340 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
341 signature_scheme_names
, feature
->arg
.privkey_sign
) > 0)
346 case FEATURE_PRIVKEY_DECRYPT
:
347 case FEATURE_PUBKEY_ENCRYPT
:
348 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
349 encryption_scheme_names
, feature
->arg
.privkey_decrypt
) > 0)
354 case FEATURE_CERT_DECODE
:
355 case FEATURE_CERT_ENCODE
:
356 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
357 certificate_type_names
, feature
->arg
.cert
) > 0)
362 case FEATURE_CONTAINER_DECODE
:
363 case FEATURE_CONTAINER_ENCODE
:
364 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
365 container_type_names
, feature
->arg
.container
) > 0)
370 case FEATURE_EAP_SERVER
:
371 case FEATURE_EAP_PEER
:
372 if (feature
->arg
.eap
.vendor
&&
373 asprintf(&str
, "%N:%d-%d", plugin_feature_names
, feature
->type
,
374 feature
->arg
.eap
.type
, feature
->arg
.eap
.vendor
) > 0)
378 else if (!feature
->arg
.eap
.vendor
&&
379 asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
380 eap_type_short_names
, feature
->arg
.eap
.type
) > 0)
385 case FEATURE_DATABASE
:
386 if (asprintf(&str
, "%N:%N", plugin_feature_names
, feature
->type
,
387 db_driver_names
, feature
->arg
.database
) > 0)
392 case FEATURE_FETCHER
:
393 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
394 feature
->arg
.fetcher
) > 0)
400 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
401 feature
->arg
.custom
) > 0)
406 case FEATURE_XAUTH_SERVER
:
407 case FEATURE_XAUTH_PEER
:
408 if (asprintf(&str
, "%N:%s", plugin_feature_names
, feature
->type
,
409 feature
->arg
.xauth
) > 0)
417 str
= strdup("(invalid)");
425 bool plugin_feature_load(plugin_t
*plugin
, plugin_feature_t
*feature
,
426 plugin_feature_t
*reg
)
431 { /* noting to do for this feature */
434 if (reg
->kind
== FEATURE_CALLBACK
)
436 if (!reg
->arg
.cb
.f
||
437 reg
->arg
.cb
.f(plugin
, feature
, TRUE
, reg
->arg
.cb
.data
))
443 name
= plugin
->get_name(plugin
);
444 switch (feature
->type
)
446 case FEATURE_CRYPTER
:
447 lib
->crypto
->add_crypter(lib
->crypto
, feature
->arg
.crypter
.alg
,
448 feature
->arg
.crypter
.key_size
,
449 name
, reg
->arg
.reg
.f
);
452 lib
->crypto
->add_aead(lib
->crypto
, feature
->arg
.aead
.alg
,
453 feature
->arg
.aead
.key_size
,
454 name
, reg
->arg
.reg
.f
);
457 lib
->crypto
->add_signer(lib
->crypto
, feature
->arg
.signer
,
458 name
, reg
->arg
.reg
.f
);
461 lib
->crypto
->add_hasher(lib
->crypto
, feature
->arg
.hasher
,
462 name
, reg
->arg
.reg
.f
);
465 lib
->crypto
->add_prf(lib
->crypto
, feature
->arg
.prf
,
466 name
, reg
->arg
.reg
.f
);
469 lib
->crypto
->add_dh(lib
->crypto
, feature
->arg
.dh_group
,
470 name
, reg
->arg
.reg
.f
);
473 lib
->crypto
->add_rng(lib
->crypto
, feature
->arg
.rng_quality
,
474 name
, reg
->arg
.reg
.f
);
476 case FEATURE_NONCE_GEN
:
477 lib
->crypto
->add_nonce_gen(lib
->crypto
,
478 name
, reg
->arg
.reg
.f
);
480 case FEATURE_PRIVKEY
:
481 case FEATURE_PRIVKEY_GEN
:
482 lib
->creds
->add_builder(lib
->creds
, CRED_PRIVATE_KEY
,
483 feature
->arg
.privkey
, reg
->arg
.reg
.final
,
487 lib
->creds
->add_builder(lib
->creds
, CRED_PUBLIC_KEY
,
488 feature
->arg
.pubkey
, reg
->arg
.reg
.final
,
491 case FEATURE_CERT_DECODE
:
492 case FEATURE_CERT_ENCODE
:
493 lib
->creds
->add_builder(lib
->creds
, CRED_CERTIFICATE
,
494 feature
->arg
.cert
, reg
->arg
.reg
.final
,
497 case FEATURE_CONTAINER_DECODE
:
498 case FEATURE_CONTAINER_ENCODE
:
499 lib
->creds
->add_builder(lib
->creds
, CRED_CONTAINER
,
500 feature
->arg
.container
, reg
->arg
.reg
.final
,
503 case FEATURE_DATABASE
:
504 lib
->db
->add_database(lib
->db
, reg
->arg
.reg
.f
);
506 case FEATURE_FETCHER
:
507 lib
->fetcher
->add_fetcher(lib
->fetcher
, reg
->arg
.reg
.f
,
508 feature
->arg
.fetcher
);
510 case FEATURE_RESOLVER
:
511 lib
->resolver
->add_resolver(lib
->resolver
, reg
->arg
.reg
.f
);
522 bool plugin_feature_unload(plugin_t
*plugin
, plugin_feature_t
*feature
,
523 plugin_feature_t
*reg
)
526 { /* noting to do for this feature */
529 if (reg
->kind
== FEATURE_CALLBACK
)
531 if (!reg
->arg
.cb
.f
||
532 reg
->arg
.cb
.f(plugin
, feature
, FALSE
, reg
->arg
.cb
.data
))
538 switch (feature
->type
)
540 case FEATURE_CRYPTER
:
541 lib
->crypto
->remove_crypter(lib
->crypto
, reg
->arg
.reg
.f
);
544 lib
->crypto
->remove_aead(lib
->crypto
, reg
->arg
.reg
.f
);
547 lib
->crypto
->remove_signer(lib
->crypto
, reg
->arg
.reg
.f
);
550 lib
->crypto
->remove_hasher(lib
->crypto
, reg
->arg
.reg
.f
);
553 lib
->crypto
->remove_prf(lib
->crypto
, reg
->arg
.reg
.f
);
556 lib
->crypto
->remove_dh(lib
->crypto
, reg
->arg
.reg
.f
);
559 lib
->crypto
->remove_rng(lib
->crypto
, reg
->arg
.reg
.f
);
561 case FEATURE_NONCE_GEN
:
562 lib
->crypto
->remove_nonce_gen(lib
->crypto
, reg
->arg
.reg
.f
);
564 case FEATURE_PRIVKEY
:
565 case FEATURE_PRIVKEY_GEN
:
566 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
569 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
571 case FEATURE_CERT_DECODE
:
572 case FEATURE_CERT_ENCODE
:
573 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
575 case FEATURE_CONTAINER_DECODE
:
576 case FEATURE_CONTAINER_ENCODE
:
577 lib
->creds
->remove_builder(lib
->creds
, reg
->arg
.reg
.f
);
579 case FEATURE_DATABASE
:
580 lib
->db
->remove_database(lib
->db
, reg
->arg
.reg
.f
);
582 case FEATURE_FETCHER
:
583 lib
->fetcher
->remove_fetcher(lib
->fetcher
, reg
->arg
.reg
.f
);
585 case FEATURE_RESOLVER
:
586 lib
->resolver
->remove_resolver(lib
->resolver
, reg
->arg
.reg
.f
);