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 if (NULL == ale->attestation)
341 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
342 "Failed to deserialize malformed attestation.\n");
346 GNUNET_CONTAINER_DLL_insert (al->list_head, al->list_tail, ale);
347 att_len = GNUNET_RECLAIM_attestation_serialize_get_size (ale->attestation);
355 * Make a (deep) copy of the attestation list
356 * @param attrs claim list to copy
357 * @return copied claim list
359 struct GNUNET_RECLAIM_AttestationList *
360 GNUNET_RECLAIM_attestation_list_dup (
361 const struct GNUNET_RECLAIM_AttestationList *al)
363 struct GNUNET_RECLAIM_AttestationListEntry *ale;
364 struct GNUNET_RECLAIM_AttestationListEntry *result_ale;
365 struct GNUNET_RECLAIM_AttestationList *result;
367 result = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
368 for (ale = al->list_head; NULL != ale; ale = ale->next)
370 result_ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
371 GNUNET_assert (NULL != ale->attestation);
372 result_ale->attestation =
373 GNUNET_RECLAIM_attestation_new (ale->attestation->name,
374 ale->attestation->type,
375 ale->attestation->data,
376 ale->attestation->data_size);
377 result_ale->attestation->id = ale->attestation->id;
378 GNUNET_CONTAINER_DLL_insert (result->list_head,
387 * Destroy attestation list
389 * @param attrs list to destroy
392 GNUNET_RECLAIM_attestation_list_destroy (
393 struct GNUNET_RECLAIM_AttestationList *al)
395 struct GNUNET_RECLAIM_AttestationListEntry *ale;
396 struct GNUNET_RECLAIM_AttestationListEntry *tmp_ale;
398 for (ale = al->list_head; NULL != ale;)
400 if (NULL != ale->attestation)
401 GNUNET_free (ale->attestation);
404 GNUNET_free (tmp_ale);
411 * Get required size for serialization buffer
413 * @param attr the attestation to serialize
414 * @return the required buffer size
417 GNUNET_RECLAIM_attestation_serialize_get_size (
418 const struct GNUNET_RECLAIM_Attestation *attestation)
420 return sizeof(struct Attestation) + strlen (attestation->name)
421 + attestation->data_size;
426 * Serialize an attestation
428 * @param attr the attestation to serialize
429 * @param result the serialized attestation
430 * @return length of serialized data
433 GNUNET_RECLAIM_attestation_serialize (
434 const struct GNUNET_RECLAIM_Attestation *attestation,
439 struct Attestation *atts;
442 atts = (struct Attestation *) result;
443 atts->attestation_type = htons (attestation->type);
444 atts->attestation_flag = htonl (attestation->flag);
445 atts->attestation_id = attestation->id;
446 name_len = strlen (attestation->name);
447 atts->name_len = htons (name_len);
448 write_ptr = (char *) &atts[1];
449 GNUNET_memcpy (write_ptr, attestation->name, name_len);
450 write_ptr += name_len;
452 // data_len_ser = plugin->serialize_attribute_value (attr,
454 data_len_ser = attestation->data_size;
455 GNUNET_memcpy (write_ptr, attestation->data, attestation->data_size);
456 atts->data_size = htons (data_len_ser);
458 return sizeof(struct Attestation) + strlen (attestation->name)
459 + attestation->data_size;
464 * Deserialize an attestation
466 * @param data the serialized attestation
467 * @param data_size the length of the serialized data
469 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
471 struct GNUNET_RECLAIM_Attestation *
472 GNUNET_RECLAIM_attestation_deserialize (const char *data, size_t data_size)
474 struct GNUNET_RECLAIM_Attestation *attestation;
475 struct Attestation *atts;
480 if (data_size < sizeof(struct Attestation))
483 atts = (struct Attestation *) data;
484 data_len = ntohs (atts->data_size);
485 name_len = ntohs (atts->name_len);
486 if (data_size < sizeof(struct Attestation) + data_len + name_len)
488 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
489 "Buffer too small to deserialize\n");
492 attestation = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Attestation)
493 + data_len + name_len + 1);
494 attestation->type = ntohs (atts->attestation_type);
495 attestation->flag = ntohl (atts->attestation_flag);
496 attestation->id = atts->attestation_id;
497 attestation->data_size = data_len;
499 write_ptr = (char *) &attestation[1];
500 GNUNET_memcpy (write_ptr, &atts[1], name_len);
501 write_ptr[name_len] = '\0';
502 attestation->name = write_ptr;
504 write_ptr += name_len + 1;
505 GNUNET_memcpy (write_ptr, (char *) &atts[1] + name_len,
506 attestation->data_size);
507 attestation->data = write_ptr;
512 struct GNUNET_RECLAIM_AttributeList*
513 GNUNET_RECLAIM_attestation_get_attributes (const struct
514 GNUNET_RECLAIM_Attestation *attest)
517 struct Plugin *plugin;
518 struct GNUNET_RECLAIM_AttributeList *ret;
520 for (i = 0; i < num_plugins; i++)
522 plugin = attest_plugins[i];
524 (ret = plugin->api->get_attributes (plugin->api->cls,
533 GNUNET_RECLAIM_attestation_get_issuer (const struct
534 GNUNET_RECLAIM_Attestation *attest)
537 struct Plugin *plugin;
540 for (i = 0; i < num_plugins; i++)
542 plugin = attest_plugins[i];
544 (ret = plugin->api->get_issuer (plugin->api->cls,
553 GNUNET_RECLAIM_attestation_get_expiration (const struct
554 GNUNET_RECLAIM_Attestation *attest,
555 struct GNUNET_TIME_Absolute* exp)
558 struct Plugin *plugin;
560 for (i = 0; i < num_plugins; i++)
562 plugin = attest_plugins[i];
563 if (GNUNET_OK != plugin->api->get_expiration (plugin->api->cls,
569 return GNUNET_SYSERR;