2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file reclaim-attribute/reclaim_attestation.c
23 * @brief helper library to manage identity attribute attestations
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "gnunet_reclaim_plugin.h"
29 #include "reclaim_attestation.h"
45 struct GNUNET_RECLAIM_AttestationPluginFunctions *api;
52 static struct Plugin **attest_plugins;
58 static unsigned int num_plugins;
64 static int initialized;
71 * @param library_name name of the API library
72 * @param lib_ret the plugin API pointer
75 add_plugin (void *cls, const char *library_name, void *lib_ret)
77 struct GNUNET_RECLAIM_AttestationPluginFunctions *api = lib_ret;
78 struct Plugin *plugin;
80 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
81 "Loading attestation plugin `%s'\n",
83 plugin = GNUNET_new (struct Plugin);
85 plugin->library_name = GNUNET_strdup (library_name);
86 GNUNET_array_append (attest_plugins, num_plugins, plugin);
96 if (GNUNET_YES == initialized)
98 initialized = GNUNET_YES;
99 GNUNET_PLUGIN_load_all ("libgnunet_plugin_reclaim_attestation_",
107 * Convert an attestation type name to the corresponding number
109 * @param typename name to convert
110 * @return corresponding number, UINT32_MAX on error
113 GNUNET_RECLAIM_attestation_typename_to_number (const char *typename)
116 struct Plugin *plugin;
119 for (i = 0; i < num_plugins; i++)
121 plugin = attest_plugins[i];
123 (ret = plugin->api->typename_to_number (plugin->api->cls,
132 * Convert an attestation type number to the corresponding attestation type string
134 * @param type number of a type
135 * @return corresponding typestring, NULL on error
138 GNUNET_RECLAIM_attestation_number_to_typename (uint32_t type)
141 struct Plugin *plugin;
145 for (i = 0; i < num_plugins; i++)
147 plugin = attest_plugins[i];
149 (ret = plugin->api->number_to_typename (plugin->api->cls, type)))
157 * Convert human-readable version of a 'claim' of an attestation to the binary
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
167 GNUNET_RECLAIM_attestation_string_to_value (uint32_t type,
173 struct Plugin *plugin;
176 for (i = 0; i < num_plugins; i++)
178 plugin = attest_plugins[i];
179 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
186 return GNUNET_SYSERR;
191 * Convert the 'claim' of an attestation to a string
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
199 GNUNET_RECLAIM_attestation_value_to_string (uint32_t type,
204 struct Plugin *plugin;
208 for (i = 0; i < num_plugins; i++)
210 plugin = attest_plugins[i];
211 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
222 * Create a new attestation.
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
230 struct GNUNET_RECLAIM_Attestation *
231 GNUNET_RECLAIM_attestation_new (const char *attr_name,
236 struct GNUNET_RECLAIM_Attestation *attr;
238 char *attr_name_tmp = GNUNET_strdup (attr_name);
240 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
242 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Attestation)
243 + strlen (attr_name_tmp) + 1 + data_size);
245 attr->data_size = data_size;
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);
259 * Get required size for serialization buffer
261 * @param attrs the attribute list to serialize
262 * @return the required buffer size
265 GNUNET_RECLAIM_attestation_list_serialize_get_size (
266 const struct GNUNET_RECLAIM_AttestationList *attestations)
268 struct GNUNET_RECLAIM_AttestationListEntry *le;
271 for (le = attestations->list_head; NULL != le; le = le->next)
273 GNUNET_assert (NULL != le->attestation);
274 len += GNUNET_RECLAIM_attestation_serialize_get_size (le->attestation);
275 len += sizeof(struct GNUNET_RECLAIM_AttestationListEntry);
282 * Serialize an attribute list
284 * @param attrs the attribute list to serialize
285 * @param result the serialized attribute
286 * @return length of serialized data
289 GNUNET_RECLAIM_attestation_list_serialize (
290 const struct GNUNET_RECLAIM_AttestationList *attestations,
293 struct GNUNET_RECLAIM_AttestationListEntry *le;
299 for (le = attestations->list_head; NULL != le; le = le->next)
301 GNUNET_assert (NULL != le->attestation);
302 len = GNUNET_RECLAIM_attestation_serialize (le->attestation, write_ptr);
311 * Deserialize an attestation list
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
317 struct GNUNET_RECLAIM_AttestationList *
318 GNUNET_RECLAIM_attestation_list_deserialize (const char *data, size_t data_size)
320 struct GNUNET_RECLAIM_AttestationList *al;
321 struct GNUNET_RECLAIM_AttestationListEntry *ale;
323 const char *read_ptr;
325 al = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
327 if ((data_size < sizeof(struct
329 + sizeof(struct GNUNET_RECLAIM_AttestationListEntry)))
333 while (((data + data_size) - read_ptr) >= sizeof(struct Attestation))
335 ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
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);
348 * Make a (deep) copy of the attestation list
349 * @param attrs claim list to copy
350 * @return copied claim list
352 struct GNUNET_RECLAIM_AttestationList *
353 GNUNET_RECLAIM_attestation_list_dup (
354 const struct GNUNET_RECLAIM_AttestationList *al)
356 struct GNUNET_RECLAIM_AttestationListEntry *ale;
357 struct GNUNET_RECLAIM_AttestationListEntry *result_ale;
358 struct GNUNET_RECLAIM_AttestationList *result;
360 result = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
361 for (ale = al->list_head; NULL != ale; ale = ale->next)
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,
380 * Destroy attestation list
382 * @param attrs list to destroy
385 GNUNET_RECLAIM_attestation_list_destroy (
386 struct GNUNET_RECLAIM_AttestationList *al)
388 struct GNUNET_RECLAIM_AttestationListEntry *ale;
389 struct GNUNET_RECLAIM_AttestationListEntry *tmp_ale;
391 for (ale = al->list_head; NULL != ale;)
393 if (NULL != ale->attestation)
394 GNUNET_free (ale->attestation);
397 GNUNET_free (tmp_ale);
404 * Get required size for serialization buffer
406 * @param attr the attestation to serialize
407 * @return the required buffer size
410 GNUNET_RECLAIM_attestation_serialize_get_size (
411 const struct GNUNET_RECLAIM_Attestation *attestation)
413 return sizeof(struct Attestation) + strlen (attestation->name)
414 + attestation->data_size;
419 * Serialize an attestation
421 * @param attr the attestation to serialize
422 * @param result the serialized attestation
423 * @return length of serialized data
426 GNUNET_RECLAIM_attestation_serialize (
427 const struct GNUNET_RECLAIM_Attestation *attestation,
432 struct Attestation *atts;
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;
445 // data_len_ser = plugin->serialize_attribute_value (attr,
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);
451 return sizeof(struct Attestation) + strlen (attestation->name)
452 + attestation->data_size;
457 * Deserialize an attestation
459 * @param data the serialized attestation
460 * @param data_size the length of the serialized data
462 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
464 struct GNUNET_RECLAIM_Attestation *
465 GNUNET_RECLAIM_attestation_deserialize (const char *data, size_t data_size)
467 struct GNUNET_RECLAIM_Attestation *attestation;
468 struct Attestation *atts;
473 if (data_size < sizeof(struct Attestation))
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)
481 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
482 "Buffer too small to deserialize\n");
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;
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;
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;
504 struct GNUNET_RECLAIM_AttributeList*
505 GNUNET_RECLAIM_attestation_get_attributes (const struct GNUNET_RECLAIM_Attestation *attest)
508 struct Plugin *plugin;
509 struct GNUNET_RECLAIM_AttributeList *ret;
511 for (i = 0; i < num_plugins; i++)
513 plugin = attest_plugins[i];
515 (ret = plugin->api->get_attributes (plugin->api->cls,