aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/reclaim_attestation.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2020-02-07 15:51:56 +0100
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2020-02-09 20:38:11 +0100
commit5f9f9cae1714eb33e0ee9c824f3d88e6aab8cf63 (patch)
treea83fc7724ee2efbfee7d7a353b54930fb1d511b8 /src/reclaim/reclaim_attestation.c
parent141a279fb55bc9b11aaa765ca3ad54689003e291 (diff)
downloadgnunet-5f9f9cae1714eb33e0ee9c824f3d88e6aab8cf63.tar.gz
gnunet-5f9f9cae1714eb33e0ee9c824f3d88e6aab8cf63.zip
consolidate reclaim attribute lib
Diffstat (limited to 'src/reclaim/reclaim_attestation.c')
-rw-r--r--src/reclaim/reclaim_attestation.c520
1 files changed, 520 insertions, 0 deletions
diff --git a/src/reclaim/reclaim_attestation.c b/src/reclaim/reclaim_attestation.c
new file mode 100644
index 000000000..961c6ede4
--- /dev/null
+++ b/src/reclaim/reclaim_attestation.c
@@ -0,0 +1,520 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file reclaim-attribute/reclaim_attestation.c
23 * @brief helper library to manage identity attribute attestations
24 * @author Martin Schanzenbach
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_reclaim_plugin.h"
29#include "reclaim_attestation.h"
30
31
32/**
33 * Handle for a plugin
34 */
35struct Plugin
36{
37 /**
38 * Name of the plugin
39 */
40 char *library_name;
41
42 /**
43 * Plugin API
44 */
45 struct GNUNET_RECLAIM_AttestationPluginFunctions *api;
46};
47
48
49/**
50 * Plugins
51 */
52static struct Plugin **attest_plugins;
53
54
55/**
56 * Number of plugins
57 */
58static unsigned int num_plugins;
59
60
61/**
62 * Init canary
63 */
64static int initialized;
65
66
67/**
68 * Add a plugin
69 *
70 * @param cls closure
71 * @param library_name name of the API library
72 * @param lib_ret the plugin API pointer
73 */
74static void
75add_plugin (void *cls, const char *library_name, void *lib_ret)
76{
77 struct GNUNET_RECLAIM_AttestationPluginFunctions *api = lib_ret;
78 struct Plugin *plugin;
79
80 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
81 "Loading attestation plugin `%s'\n",
82 library_name);
83 plugin = GNUNET_new (struct Plugin);
84 plugin->api = api;
85 plugin->library_name = GNUNET_strdup (library_name);
86 GNUNET_array_append (attest_plugins, num_plugins, plugin);
87}
88
89
90/**
91 * Load plugins
92 */
93static void
94init ()
95{
96 if (GNUNET_YES == initialized)
97 return;
98 initialized = GNUNET_YES;
99 GNUNET_PLUGIN_load_all ("libgnunet_plugin_reclaim_attestation_",
100 NULL,
101 &add_plugin,
102 NULL);
103}
104
105
106/**
107 * Convert an attestation type name to the corresponding number
108 *
109 * @param typename name to convert
110 * @return corresponding number, UINT32_MAX on error
111 */
112uint32_t
113GNUNET_RECLAIM_attestation_typename_to_number (const char *typename)
114{
115 unsigned int i;
116 struct Plugin *plugin;
117 uint32_t ret;
118 init ();
119 for (i = 0; i < num_plugins; i++)
120 {
121 plugin = attest_plugins[i];
122 if (UINT32_MAX !=
123 (ret = plugin->api->typename_to_number (plugin->api->cls,
124 typename)))
125 return ret;
126 }
127 return UINT32_MAX;
128}
129
130
131/**
132 * Convert an attestation type number to the corresponding attestation type string
133 *
134 * @param type number of a type
135 * @return corresponding typestring, NULL on error
136 */
137const char *
138GNUNET_RECLAIM_attestation_number_to_typename (uint32_t type)
139{
140 unsigned int i;
141 struct Plugin *plugin;
142 const char *ret;
143
144 init ();
145 for (i = 0; i < num_plugins; i++)
146 {
147 plugin = attest_plugins[i];
148 if (NULL !=
149 (ret = plugin->api->number_to_typename (plugin->api->cls, type)))
150 return ret;
151 }
152 return NULL;
153}
154
155
156/**
157 * Convert human-readable version of a 'claim' of an attestation to the binary
158 * representation
159 *
160 * @param type type of the claim
161 * @param s human-readable string
162 * @param data set to value in binary encoding (will be allocated)
163 * @param data_size set to number of bytes in @a data
164 * @return #GNUNET_OK on success
165 */
166int
167GNUNET_RECLAIM_attestation_string_to_value (uint32_t type,
168 const char *s,
169 void **data,
170 size_t *data_size)
171{
172 unsigned int i;
173 struct Plugin *plugin;
174
175 init ();
176 for (i = 0; i < num_plugins; i++)
177 {
178 plugin = attest_plugins[i];
179 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
180 type,
181 s,
182 data,
183 data_size))
184 return GNUNET_OK;
185 }
186 return GNUNET_SYSERR;
187}
188
189
190/**
191 * Convert the 'claim' of an attestation to a string
192 *
193 * @param type the type of attestation
194 * @param data claim in binary encoding
195 * @param data_size number of bytes in @a data
196 * @return NULL on error, otherwise human-readable representation of the claim
197 */
198char *
199GNUNET_RECLAIM_attestation_value_to_string (uint32_t type,
200 const void *data,
201 size_t data_size)
202{
203 unsigned int i;
204 struct Plugin *plugin;
205 char *ret;
206
207 init ();
208 for (i = 0; i < num_plugins; i++)
209 {
210 plugin = attest_plugins[i];
211 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
212 type,
213 data,
214 data_size)))
215 return ret;
216 }
217 return NULL;
218}
219
220
221/**
222 * Create a new attestation.
223 *
224 * @param attr_name the attestation name
225 * @param type the attestation type
226 * @param data the attestation value
227 * @param data_size the attestation value size
228 * @return the new attestation
229 */
230struct GNUNET_RECLAIM_Attestation *
231GNUNET_RECLAIM_attestation_new (const char *attr_name,
232 uint32_t type,
233 const void *data,
234 size_t data_size)
235{
236 struct GNUNET_RECLAIM_Attestation *attr;
237 char *write_ptr;
238 char *attr_name_tmp = GNUNET_strdup (attr_name);
239
240 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
241
242 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Attestation)
243 + strlen (attr_name_tmp) + 1 + data_size);
244 attr->type = type;
245 attr->data_size = data_size;
246 attr->flag = 0;
247 write_ptr = (char *) &attr[1];
248 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
249 attr->name = write_ptr;
250 write_ptr += strlen (attr->name) + 1;
251 GNUNET_memcpy (write_ptr, data, data_size);
252 attr->data = write_ptr;
253 GNUNET_free (attr_name_tmp);
254 return attr;
255}
256
257
258/**
259 * Get required size for serialization buffer
260 *
261 * @param attrs the attribute list to serialize
262 * @return the required buffer size
263 */
264size_t
265GNUNET_RECLAIM_attestation_list_serialize_get_size (
266 const struct GNUNET_RECLAIM_AttestationList *attestations)
267{
268 struct GNUNET_RECLAIM_AttestationListEntry *le;
269 size_t len = 0;
270
271 for (le = attestations->list_head; NULL != le; le = le->next)
272 {
273 GNUNET_assert (NULL != le->attestation);
274 len += GNUNET_RECLAIM_attestation_serialize_get_size (le->attestation);
275 len += sizeof(struct GNUNET_RECLAIM_AttestationListEntry);
276 }
277 return len;
278}
279
280
281/**
282 * Serialize an attribute list
283 *
284 * @param attrs the attribute list to serialize
285 * @param result the serialized attribute
286 * @return length of serialized data
287 */
288size_t
289GNUNET_RECLAIM_attestation_list_serialize (
290 const struct GNUNET_RECLAIM_AttestationList *attestations,
291 char *result)
292{
293 struct GNUNET_RECLAIM_AttestationListEntry *le;
294 size_t len;
295 size_t total_len;
296 char *write_ptr;
297 write_ptr = result;
298 total_len = 0;
299 for (le = attestations->list_head; NULL != le; le = le->next)
300 {
301 GNUNET_assert (NULL != le->attestation);
302 len = GNUNET_RECLAIM_attestation_serialize (le->attestation, write_ptr);
303 total_len += len;
304 write_ptr += len;
305 }
306 return total_len;
307}
308
309
310/**
311 * Deserialize an attestation list
312 *
313 * @param data the serialized attribute list
314 * @param data_size the length of the serialized data
315 * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller
316 */
317struct GNUNET_RECLAIM_AttestationList *
318GNUNET_RECLAIM_attestation_list_deserialize (const char *data, size_t data_size)
319{
320 struct GNUNET_RECLAIM_AttestationList *al;
321 struct GNUNET_RECLAIM_AttestationListEntry *ale;
322 size_t att_len;
323 const char *read_ptr;
324
325 al = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
326
327 if ((data_size < sizeof(struct
328 Attestation)
329 + sizeof(struct GNUNET_RECLAIM_AttestationListEntry)))
330 return al;
331
332 read_ptr = data;
333 while (((data + data_size) - read_ptr) >= sizeof(struct Attestation))
334 {
335 ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
336 ale->attestation =
337 GNUNET_RECLAIM_attestation_deserialize (read_ptr,
338 data_size - (read_ptr - data));
339 GNUNET_CONTAINER_DLL_insert (al->list_head, al->list_tail, ale);
340 att_len = GNUNET_RECLAIM_attestation_serialize_get_size (ale->attestation);
341 read_ptr += att_len;
342 }
343 return al;
344}
345
346
347/**
348 * Make a (deep) copy of the attestation list
349 * @param attrs claim list to copy
350 * @return copied claim list
351 */
352struct GNUNET_RECLAIM_AttestationList *
353GNUNET_RECLAIM_attestation_list_dup (
354 const struct GNUNET_RECLAIM_AttestationList *al)
355{
356 struct GNUNET_RECLAIM_AttestationListEntry *ale;
357 struct GNUNET_RECLAIM_AttestationListEntry *result_ale;
358 struct GNUNET_RECLAIM_AttestationList *result;
359
360 result = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
361 for (ale = al->list_head; NULL != ale; ale = ale->next)
362 {
363 result_ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
364 GNUNET_assert (NULL != ale->attestation);
365 result_ale->attestation =
366 GNUNET_RECLAIM_attestation_new (ale->attestation->name,
367 ale->attestation->type,
368 ale->attestation->data,
369 ale->attestation->data_size);
370 result_ale->attestation->id = ale->attestation->id;
371 GNUNET_CONTAINER_DLL_insert (result->list_head,
372 result->list_tail,
373 result_ale);
374 }
375 return result;
376}
377
378
379/**
380 * Destroy attestation list
381 *
382 * @param attrs list to destroy
383 */
384void
385GNUNET_RECLAIM_attestation_list_destroy (
386 struct GNUNET_RECLAIM_AttestationList *al)
387{
388 struct GNUNET_RECLAIM_AttestationListEntry *ale;
389 struct GNUNET_RECLAIM_AttestationListEntry *tmp_ale;
390
391 for (ale = al->list_head; NULL != ale;)
392 {
393 if (NULL != ale->attestation)
394 GNUNET_free (ale->attestation);
395 tmp_ale = ale;
396 ale = ale->next;
397 GNUNET_free (tmp_ale);
398 }
399 GNUNET_free (al);
400}
401
402
403/**
404 * Get required size for serialization buffer
405 *
406 * @param attr the attestation to serialize
407 * @return the required buffer size
408 */
409size_t
410GNUNET_RECLAIM_attestation_serialize_get_size (
411 const struct GNUNET_RECLAIM_Attestation *attestation)
412{
413 return sizeof(struct Attestation) + strlen (attestation->name)
414 + attestation->data_size;
415}
416
417
418/**
419 * Serialize an attestation
420 *
421 * @param attr the attestation to serialize
422 * @param result the serialized attestation
423 * @return length of serialized data
424 */
425size_t
426GNUNET_RECLAIM_attestation_serialize (
427 const struct GNUNET_RECLAIM_Attestation *attestation,
428 char *result)
429{
430 size_t data_len_ser;
431 size_t name_len;
432 struct Attestation *atts;
433 char *write_ptr;
434
435 atts = (struct Attestation *) result;
436 atts->attestation_type = htons (attestation->type);
437 atts->attestation_flag = htonl (attestation->flag);
438 atts->attestation_id = attestation->id;
439 name_len = strlen (attestation->name);
440 atts->name_len = htons (name_len);
441 write_ptr = (char *) &atts[1];
442 GNUNET_memcpy (write_ptr, attestation->name, name_len);
443 write_ptr += name_len;
444 // TODO plugin-ize
445 // data_len_ser = plugin->serialize_attribute_value (attr,
446 // &attr_ser[1]);
447 data_len_ser = attestation->data_size;
448 GNUNET_memcpy (write_ptr, attestation->data, attestation->data_size);
449 atts->data_size = htons (data_len_ser);
450
451 return sizeof(struct Attestation) + strlen (attestation->name)
452 + attestation->data_size;
453}
454
455
456/**
457 * Deserialize an attestation
458 *
459 * @param data the serialized attestation
460 * @param data_size the length of the serialized data
461 *
462 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
463 */
464struct GNUNET_RECLAIM_Attestation *
465GNUNET_RECLAIM_attestation_deserialize (const char *data, size_t data_size)
466{
467 struct GNUNET_RECLAIM_Attestation *attestation;
468 struct Attestation *atts;
469 size_t data_len;
470 size_t name_len;
471 char *write_ptr;
472
473 if (data_size < sizeof(struct Attestation))
474 return NULL;
475
476 atts = (struct Attestation *) data;
477 data_len = ntohs (atts->data_size);
478 name_len = ntohs (atts->name_len);
479 if (data_size < sizeof(struct Attestation) + data_len + name_len)
480 {
481 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
482 "Buffer too small to deserialize\n");
483 return NULL;
484 }
485 attestation = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Attestation)
486 + data_len + name_len + 1);
487 attestation->type = ntohs (atts->attestation_type);
488 attestation->flag = ntohl (atts->attestation_flag);
489 attestation->id = atts->attestation_id;
490 attestation->data_size = data_len;
491
492 write_ptr = (char *) &attestation[1];
493 GNUNET_memcpy (write_ptr, &atts[1], name_len);
494 write_ptr[name_len] = '\0';
495 attestation->name = write_ptr;
496
497 write_ptr += name_len + 1;
498 GNUNET_memcpy (write_ptr, (char *) &atts[1] + name_len,
499 attestation->data_size);
500 attestation->data = write_ptr;
501 return attestation;
502}
503
504struct GNUNET_RECLAIM_AttributeList*
505GNUNET_RECLAIM_attestation_get_attributes (const struct GNUNET_RECLAIM_Attestation *attest)
506{
507 unsigned int i;
508 struct Plugin *plugin;
509 struct GNUNET_RECLAIM_AttributeList *ret;
510 init ();
511 for (i = 0; i < num_plugins; i++)
512 {
513 plugin = attest_plugins[i];
514 if (NULL !=
515 (ret = plugin->api->get_attributes (plugin->api->cls,
516 attest)))
517 return ret;
518 }
519 return NULL;
520}