Add nonce generator interface
[strongswan.git] / src / libstrongswan / plugins / plugin_feature.c
1 /*
2 * Copyright (C) 2011 Martin Willi
3 * Copyright (C) 2011 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #define _GNU_SOURCE
17 #include <stdio.h>
18
19 #include "plugin_feature.h"
20
21 #include <debug.h>
22
23 ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
24 "NONE",
25 "CRYPTER",
26 "AEAD",
27 "SIGNER",
28 "HASHER",
29 "PRF",
30 "DH",
31 "RNG",
32 "NONCE_GEN",
33 "PRIVKEY",
34 "PRIVKEY_GEN",
35 "PRIVKEY_SIGN",
36 "PRIVKEY_DECRYPT",
37 "PUBKEY",
38 "PUBKEY_VERIFY",
39 "PUBKEY_ENCRYPT",
40 "CERT_DECODE",
41 "CERT_ENCODE",
42 "EAP_SERVER",
43 "EAP_CLIENT",
44 "XAUTH_SERVER",
45 "XAUTH_CLIENT",
46 "DATABASE",
47 "FETCHER",
48 "CUSTOM",
49 );
50
51 /**
52 * See header.
53 */
54 bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
55 {
56 if (a->type == b->type)
57 {
58 switch (a->type)
59 {
60 case FEATURE_NONE:
61 return FALSE;
62 case FEATURE_CRYPTER:
63 return a->arg.crypter.alg == b->arg.crypter.alg &&
64 a->arg.crypter.key_size == b->arg.crypter.key_size;
65 case FEATURE_AEAD:
66 return a->arg.aead.alg == b->arg.aead.alg &&
67 a->arg.aead.key_size == b->arg.aead.key_size;
68 case FEATURE_SIGNER:
69 return a->arg.signer == b->arg.signer;
70 case FEATURE_HASHER:
71 return a->arg.hasher == b->arg.hasher;
72 case FEATURE_PRF:
73 return a->arg.prf == b->arg.prf;
74 case FEATURE_DH:
75 return a->arg.dh_group == b->arg.dh_group;
76 case FEATURE_RNG:
77 return a->arg.rng_quality <= b->arg.rng_quality;
78 case FEATURE_NONCE_GEN:
79 return TRUE;
80 case FEATURE_PRIVKEY:
81 case FEATURE_PRIVKEY_GEN:
82 case FEATURE_PUBKEY:
83 return a->arg.privkey == b->arg.privkey;
84 case FEATURE_PRIVKEY_SIGN:
85 case FEATURE_PUBKEY_VERIFY:
86 return a->arg.privkey_sign == b->arg.privkey_sign;
87 case FEATURE_PRIVKEY_DECRYPT:
88 case FEATURE_PUBKEY_ENCRYPT:
89 return a->arg.privkey_decrypt == b->arg.privkey_decrypt;
90 case FEATURE_CERT_DECODE:
91 case FEATURE_CERT_ENCODE:
92 return a->arg.cert == b->arg.cert;
93 case FEATURE_EAP_SERVER:
94 case FEATURE_EAP_PEER:
95 return a->arg.eap == b->arg.eap;
96 case FEATURE_DATABASE:
97 return a->arg.database == DB_ANY ||
98 a->arg.database == b->arg.database;
99 case FEATURE_FETCHER:
100 return a->arg.fetcher == NULL ||
101 streq(a->arg.fetcher, b->arg.fetcher);
102 case FEATURE_CUSTOM:
103 return streq(a->arg.custom, b->arg.custom);
104 case FEATURE_XAUTH_SERVER:
105 case FEATURE_XAUTH_PEER:
106 return streq(a->arg.xauth, b->arg.xauth);
107 }
108 }
109 return FALSE;
110 }
111
112 /**
113 * See header.
114 */
115 char* plugin_feature_get_string(plugin_feature_t *feature)
116 {
117 char *str = NULL;
118
119 if (feature->kind == FEATURE_REGISTER)
120 {
121 return strdup("(register function)");
122 }
123 switch (feature->type)
124 {
125 case FEATURE_NONE:
126 return strdup("NONE");
127 case FEATURE_CRYPTER:
128 if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
129 encryption_algorithm_names, feature->arg.crypter.alg,
130 feature->arg.crypter.key_size) > 0)
131 {
132 return str;
133 }
134 break;
135 case FEATURE_AEAD:
136 if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
137 encryption_algorithm_names, feature->arg.aead.alg,
138 feature->arg.aead.key_size) > 0)
139 {
140 return str;
141 }
142 break;
143 case FEATURE_SIGNER:
144 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
145 integrity_algorithm_names, feature->arg.signer) > 0)
146 {
147 return str;
148 }
149 break;
150 case FEATURE_HASHER:
151 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
152 hash_algorithm_names, feature->arg.hasher) > 0)
153 {
154 return str;
155 }
156 break;
157 case FEATURE_PRF:
158 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
159 pseudo_random_function_names, feature->arg.prf) > 0)
160 {
161 return str;
162 }
163 break;
164 case FEATURE_DH:
165 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
166 diffie_hellman_group_names, feature->arg.dh_group) > 0)
167 {
168 return str;
169 }
170 break;
171 case FEATURE_RNG:
172 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
173 rng_quality_names, feature->arg.rng_quality) > 0)
174 {
175 return str;
176 }
177 break;
178 case FEATURE_NONCE_GEN:
179 if (asprintf(&str, "%N", plugin_feature_names, feature->type) > 0)
180 {
181 return str;
182 }
183 break;
184 case FEATURE_PRIVKEY:
185 case FEATURE_PRIVKEY_GEN:
186 case FEATURE_PUBKEY:
187 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
188 key_type_names, feature->arg.privkey) > 0)
189 {
190 return str;
191 }
192 break;
193 case FEATURE_PRIVKEY_SIGN:
194 case FEATURE_PUBKEY_VERIFY:
195 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
196 signature_scheme_names, feature->arg.privkey_sign) > 0)
197 {
198 return str;
199 }
200 break;
201 case FEATURE_PRIVKEY_DECRYPT:
202 case FEATURE_PUBKEY_ENCRYPT:
203 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
204 encryption_scheme_names, feature->arg.privkey_decrypt) > 0)
205 {
206 return str;
207 }
208 break;
209 case FEATURE_CERT_DECODE:
210 case FEATURE_CERT_ENCODE:
211 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
212 certificate_type_names, feature->arg.cert) > 0)
213 {
214 return str;
215 }
216 break;
217 case FEATURE_EAP_SERVER:
218 case FEATURE_EAP_PEER:
219 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
220 eap_type_short_names, feature->arg.eap) > 0)
221 {
222 return str;
223 }
224 break;
225 case FEATURE_DATABASE:
226 if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
227 db_driver_names, feature->arg.database) > 0)
228 {
229 return str;
230 }
231 break;
232 case FEATURE_FETCHER:
233 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
234 feature->arg.fetcher) > 0)
235 {
236 return str;
237 }
238 break;
239 case FEATURE_CUSTOM:
240 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
241 feature->arg.custom) > 0)
242 {
243 return str;
244 }
245 break;
246 case FEATURE_XAUTH_SERVER:
247 case FEATURE_XAUTH_PEER:
248 if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
249 feature->arg.xauth) > 0)
250 {
251 return str;
252 }
253 break;
254 }
255 if (!str)
256 {
257 str = strdup("(invalid)");
258 }
259 return str;
260 }
261
262 /**
263 * See header.
264 */
265 bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
266 plugin_feature_t *reg)
267 {
268 char *name;
269
270 if (!reg)
271 { /* noting to do for this feature */
272 return TRUE;
273 }
274 if (reg->kind == FEATURE_CALLBACK)
275 {
276 if (reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data))
277 {
278 return TRUE;
279 }
280 return FALSE;
281 }
282 name = plugin->get_name(plugin);
283 switch (feature->type)
284 {
285 case FEATURE_CRYPTER:
286 lib->crypto->add_crypter(lib->crypto, feature->arg.crypter.alg,
287 name, reg->arg.reg.f);
288 break;
289 case FEATURE_AEAD:
290 lib->crypto->add_aead(lib->crypto, feature->arg.aead.alg,
291 name, reg->arg.reg.f);
292 break;
293 case FEATURE_SIGNER:
294 lib->crypto->add_signer(lib->crypto, feature->arg.signer,
295 name, reg->arg.reg.f);
296 break;
297 case FEATURE_HASHER:
298 lib->crypto->add_hasher(lib->crypto, feature->arg.hasher,
299 name, reg->arg.reg.f);
300 break;
301 case FEATURE_PRF:
302 lib->crypto->add_prf(lib->crypto, feature->arg.prf,
303 name, reg->arg.reg.f);
304 break;
305 case FEATURE_DH:
306 lib->crypto->add_dh(lib->crypto, feature->arg.dh_group,
307 name, reg->arg.reg.f);
308 break;
309 case FEATURE_RNG:
310 lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality,
311 name, reg->arg.reg.f);
312 break;
313 case FEATURE_NONCE_GEN:
314 lib->crypto->add_nonce_gen(lib->crypto,
315 name, reg->arg.reg.f);
316 break;
317 case FEATURE_PRIVKEY:
318 case FEATURE_PRIVKEY_GEN:
319 lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY,
320 feature->arg.privkey, reg->arg.reg.final,
321 reg->arg.reg.f);
322 break;
323 case FEATURE_PUBKEY:
324 lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY,
325 feature->arg.pubkey, reg->arg.reg.final,
326 reg->arg.reg.f);
327 break;
328 case FEATURE_CERT_DECODE:
329 case FEATURE_CERT_ENCODE:
330 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE,
331 feature->arg.cert, reg->arg.reg.final,
332 reg->arg.reg.f);
333 break;
334 case FEATURE_DATABASE:
335 lib->db->add_database(lib->db, reg->arg.reg.f);
336 break;
337 case FEATURE_FETCHER:
338 lib->fetcher->add_fetcher(lib->fetcher, reg->arg.reg.f,
339 feature->arg.fetcher);
340 break;
341 default:
342 break;
343 }
344 return TRUE;
345 }
346
347 /**
348 * See header.
349 */
350 bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
351 plugin_feature_t *reg)
352 {
353 if (!reg)
354 { /* noting to do for this feature */
355 return TRUE;
356 }
357 if (reg->kind == FEATURE_CALLBACK)
358 {
359 if (reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data))
360 {
361 return TRUE;
362 }
363 return FALSE;
364 }
365 switch (feature->type)
366 {
367 case FEATURE_CRYPTER:
368 lib->crypto->remove_crypter(lib->crypto, reg->arg.reg.f);
369 break;
370 case FEATURE_AEAD:
371 lib->crypto->remove_aead(lib->crypto, reg->arg.reg.f);
372 break;
373 case FEATURE_SIGNER:
374 lib->crypto->remove_signer(lib->crypto, reg->arg.reg.f);
375 break;
376 case FEATURE_HASHER:
377 lib->crypto->remove_hasher(lib->crypto, reg->arg.reg.f);
378 break;
379 case FEATURE_PRF:
380 lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f);
381 break;
382 case FEATURE_DH:
383 lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f);
384 break;
385 case FEATURE_RNG:
386 lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f);
387 break;
388 case FEATURE_NONCE_GEN:
389 lib->crypto->remove_nonce_gen(lib->crypto, reg->arg.reg.f);
390 break;
391 case FEATURE_PRIVKEY:
392 case FEATURE_PRIVKEY_GEN:
393 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
394 break;
395 case FEATURE_PUBKEY:
396 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
397 break;
398 case FEATURE_CERT_DECODE:
399 case FEATURE_CERT_ENCODE:
400 lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
401 break;
402 case FEATURE_DATABASE:
403 lib->db->remove_database(lib->db, reg->arg.reg.f);
404 break;
405 case FEATURE_FETCHER:
406 lib->fetcher->remove_fetcher(lib->fetcher, reg->arg.reg.f);
407 break;
408 default:
409 break;
410 }
411 return TRUE;
412 }