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_attribute.c
23 * @brief helper library to manage identity attributes
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "gnunet_reclaim_attribute_plugin.h"
29 #include "reclaim_attribute.h"
45 struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions *api;
52 static struct Plugin **attr_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_ATTRIBUTE_PluginFunctions *api = lib_ret;
78 struct Plugin *plugin;
80 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
81 "Loading attribute plugin `%s'\n",
83 plugin = GNUNET_new (struct Plugin);
85 plugin->library_name = GNUNET_strdup (library_name);
86 GNUNET_array_append (attr_plugins, num_plugins, plugin);
96 if (GNUNET_YES == initialized)
98 initialized = GNUNET_YES;
99 GNUNET_PLUGIN_load_all ("libgnunet_plugin_reclaim_attribute_",
107 * Convert a type name to the corresponding number
109 * @param typename name to convert
110 * @return corresponding number, UINT32_MAX on error
113 GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (const char *typename)
116 struct Plugin *plugin;
120 for (i = 0; i < num_plugins; i++)
122 plugin = attr_plugins[i];
124 (ret = plugin->api->typename_to_number (plugin->api->cls, typename)))
132 * Convert a type number to the corresponding type string
134 * @param type number of a type
135 * @return corresponding typestring, NULL on error
138 GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type)
141 struct Plugin *plugin;
145 for (i = 0; i < num_plugins; i++)
147 plugin = attr_plugins[i];
149 (ret = plugin->api->number_to_typename (plugin->api->cls, type)))
157 * Convert human-readable version of a 'claim' of an attribute 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_ATTRIBUTE_string_to_value (uint32_t type,
173 struct Plugin *plugin;
176 for (i = 0; i < num_plugins; i++)
178 plugin = attr_plugins[i];
179 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
186 return GNUNET_SYSERR;
191 * Convert the 'claim' of an attribute to a string
193 * @param type the type of attribute
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_ATTRIBUTE_value_to_string (uint32_t type,
204 struct Plugin *plugin;
208 for (i = 0; i < num_plugins; i++)
210 plugin = attr_plugins[i];
211 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
221 * Convert an attestation type name to the corresponding number
223 * @param typename name to convert
224 * @return corresponding number, UINT32_MAX on error
227 GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename)
230 struct Plugin *plugin;
234 for (i = 0; i < num_plugins; i++)
236 plugin = attr_plugins[i];
238 (ret = plugin->api->typename_to_number_attest (plugin->api->cls,
246 * Convert an attestation type number to the corresponding attestation type string
248 * @param type number of a type
249 * @return corresponding typestring, NULL on error
252 GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type)
255 struct Plugin *plugin;
259 for (i = 0; i < num_plugins; i++)
261 plugin = attr_plugins[i];
263 (ret = plugin->api->number_to_typename_attest (plugin->api->cls, type)))
269 * Convert human-readable version of a 'claim' of an attestation to the binary
272 * @param type type of the claim
273 * @param s human-readable string
274 * @param data set to value in binary encoding (will be allocated)
275 * @param data_size set to number of bytes in @a data
276 * @return #GNUNET_OK on success
279 GNUNET_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
285 struct Plugin *plugin;
288 for (i = 0; i < num_plugins; i++)
290 plugin = attr_plugins[i];
291 if (GNUNET_OK == plugin->api->string_to_value_attest (plugin->api->cls,
298 return GNUNET_SYSERR;
303 * Convert the 'claim' of an attestation to a string
305 * @param type the type of attestation
306 * @param data claim in binary encoding
307 * @param data_size number of bytes in @a data
308 * @return NULL on error, otherwise human-readable representation of the claim
311 GNUNET_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
316 struct Plugin *plugin;
320 for (i = 0; i < num_plugins; i++)
322 plugin = attr_plugins[i];
323 if (NULL != (ret = plugin->api->value_to_string_attest (plugin->api->cls,
333 * Create a new attribute.
335 * @param attr_name the attribute name
336 * @param type the attribute type
337 * @param data the attribute value
338 * @param data_size the attribute value size
339 * @return the new attribute
341 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
342 GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
347 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
349 char *attr_name_tmp = GNUNET_strdup (attr_name);
351 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
353 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim)
354 + strlen (attr_name_tmp) + 1 + data_size);
356 attr->data_size = data_size;
358 write_ptr = (char *) &attr[1];
359 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
360 attr->name = write_ptr;
361 write_ptr += strlen (attr->name) + 1;
362 GNUNET_memcpy (write_ptr, data, data_size);
363 attr->data = write_ptr;
364 GNUNET_free (attr_name_tmp);
369 * Create a new attestation.
371 * @param attr_name the attestation name
372 * @param type the attestation type
373 * @param data the attestation value
374 * @param data_size the attestation value size
375 * @return the new attestation
377 struct GNUNET_RECLAIM_ATTESTATION_Claim *
378 GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
383 struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
385 char *attr_name_tmp = GNUNET_strdup (attr_name);
387 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
389 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
390 + strlen (attr_name_tmp) + 1 + data_size);
392 attr->data_size = data_size;
394 write_ptr = (char *) &attr[1];
395 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
396 attr->name = write_ptr;
397 write_ptr += strlen (attr->name) + 1;
398 GNUNET_memcpy (write_ptr, data, data_size);
399 attr->data = write_ptr;
400 GNUNET_free (attr_name_tmp);
405 * Add a new attribute to a claim list
407 * @param attr_name the name of the new attribute claim
408 * @param type the type of the claim
409 * @param data claim payload
410 * @param data_size claim payload size
413 GNUNET_RECLAIM_ATTRIBUTE_list_add (
414 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *claim_list,
415 const char *attr_name,
420 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
422 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
424 GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr_name, type, data, data_size);
425 GNUNET_CONTAINER_DLL_insert (claim_list->list_head,
426 claim_list->list_tail,
432 * Get required size for serialization buffer
434 * @param attrs the attribute list to serialize
435 * @return the required buffer size
438 GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (
439 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
441 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
444 for (le = attrs->list_head; NULL != le; le = le->next)
445 len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
451 * Serialize an attribute list
453 * @param attrs the attribute list to serialize
454 * @param result the serialized attribute
455 * @return length of serialized data
458 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
459 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
462 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
469 for (le = attrs->list_head; NULL != le; le = le->next)
471 len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr);
480 * Deserialize an attribute list
482 * @param data the serialized attribute list
483 * @param data_size the length of the serialized data
484 * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller
486 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
487 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size)
489 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
490 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
492 const char *read_ptr;
494 if (data_size < sizeof(struct Attribute))
497 attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
499 while (((data + data_size) - read_ptr) >= sizeof(struct Attribute))
501 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
503 GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
504 data_size - (read_ptr - data));
505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
506 "Deserialized attribute %s\n",
508 GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
509 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
510 read_ptr += attr_len;
517 * Make a (deep) copy of a claim list
518 * @param attrs claim list to copy
519 * @return copied claim list
521 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
522 GNUNET_RECLAIM_ATTRIBUTE_list_dup (
523 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
525 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
526 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *result_le;
527 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result;
529 result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
530 for (le = attrs->list_head; NULL != le; le = le->next)
532 result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
534 GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
537 le->claim->data_size);
538 result_le->claim->version = le->claim->version;
539 result_le->claim->id = le->claim->id;
540 GNUNET_CONTAINER_DLL_insert (result->list_head,
551 * @param attrs list to destroy
554 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
555 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
557 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
558 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le;
560 for (le = attrs->list_head; NULL != le;)
562 GNUNET_free (le->claim);
565 GNUNET_free (tmp_le);
572 * Get required size for serialization buffer
574 * @param attr the attribute to serialize
575 * @return the required buffer size
578 GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (
579 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
581 return sizeof(struct Attribute) + strlen (attr->name) + attr->data_size;
586 * Serialize an attribute
588 * @param attr the attribute to serialize
589 * @param result the serialized attribute
590 * @return length of serialized data
593 GNUNET_RECLAIM_ATTRIBUTE_serialize (
594 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
599 struct Attribute *attr_ser;
602 attr_ser = (struct Attribute *) result;
603 attr_ser->attribute_type = htons (attr->type);
604 attr_ser->attribute_version = htonl (attr->version);
605 attr_ser->attribute_id = GNUNET_htonll (attr->id);
606 name_len = strlen (attr->name);
607 attr_ser->name_len = htons (name_len);
608 write_ptr = (char *) &attr_ser[1];
609 GNUNET_memcpy (write_ptr, attr->name, name_len);
610 write_ptr += name_len;
612 // data_len_ser = plugin->serialize_attribute_value (attr,
614 data_len_ser = attr->data_size;
615 GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
616 attr_ser->data_size = htons (data_len_ser);
618 return sizeof(struct Attribute) + strlen (attr->name) + attr->data_size;
623 * Deserialize an attribute
625 * @param data the serialized attribute
626 * @param data_size the length of the serialized data
628 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
630 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
631 GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, size_t data_size)
633 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
634 struct Attribute *attr_ser;
639 if (data_size < sizeof(struct Attribute))
642 attr_ser = (struct Attribute *) data;
643 data_len = ntohs (attr_ser->data_size);
644 name_len = ntohs (attr_ser->name_len);
645 if (data_size < sizeof(struct Attribute) + data_len + name_len)
647 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
648 "Buffer too small to deserialize\n");
651 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim)
652 + data_len + name_len + 1);
653 attr->type = ntohs (attr_ser->attribute_type);
654 attr->version = ntohl (attr_ser->attribute_version);
655 attr->id = GNUNET_ntohll (attr_ser->attribute_id);
656 attr->data_size = data_len;
658 write_ptr = (char *) &attr[1];
659 GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
660 write_ptr[name_len] = '\0';
661 attr->name = write_ptr;
663 write_ptr += name_len + 1;
664 GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, attr->data_size);
665 attr->data = write_ptr;
671 * Get required size for serialization buffer
673 * @param attr the attestation to serialize
674 * @return the required buffer size
677 GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
678 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr)
680 return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
684 * Serialize an attestation
686 * @param attr the attestation to serialize
687 * @param result the serialized attestation
688 * @return length of serialized data
691 GNUNET_RECLAIM_ATTESTATION_serialize (
692 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
697 struct Attestation *attr_ser;
700 attr_ser = (struct Attestation *) result;
701 attr_ser->attestation_type = htons (attr->type);
702 attr_ser->attestation_type = htonl (attr->version);
703 attr_ser->attestation_type = GNUNET_htonll (attr->id);
704 name_len = strlen (attr->name);
705 attr_ser->name_len = htons (name_len);
706 write_ptr = (char *) &attr_ser[1];
707 GNUNET_memcpy (write_ptr, attr->name, name_len);
708 write_ptr += name_len;
710 // data_len_ser = plugin->serialize_attribute_value (attr,
712 data_len_ser = attr->data_size;
713 GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
714 attr_ser->data_size = htons (data_len_ser);
716 return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
720 * Deserialize an attestation
722 * @param data the serialized attestation
723 * @param data_size the length of the serialized data
725 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
727 struct GNUNET_RECLAIM_ATTESTATION_Claim *
728 GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size)
730 struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
731 struct Attestation *attr_ser;
736 if (data_size < sizeof(struct Attestation))
739 attr_ser = (struct Attestation *) data;
740 data_len = ntohs (attr_ser->data_size);
741 name_len = ntohs (attr_ser->name_len);
742 if (data_size < sizeof(struct Attestation) + data_len + name_len)
744 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
745 "Buffer too small to deserialize\n");
748 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
749 + data_len + name_len + 1);
750 attr->type = ntohs (attr_ser->attestation_type);
751 attr->version = ntohl (attr_ser->attestation_version);
752 attr->id = GNUNET_ntohll (attr_ser->attestation_id);
753 attr->data_size = data_len;
755 write_ptr = (char *) &attr[1];
756 GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
757 write_ptr[name_len] = '\0';
758 attr->name = write_ptr;
760 write_ptr += name_len + 1;
761 GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, attr->data_size);
762 attr->data = write_ptr;
766 /* end of reclaim_attribute.c */