aboutsummaryrefslogtreecommitdiff
path: root/src/identity-attribute/identity_attribute.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2017-12-04 17:39:55 +0100
committerSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2017-12-04 17:39:55 +0100
commitd4b252fd73bdda7be51a971ba06a650a1dceb45c (patch)
tree15026001f43b756e4a86d7ec80f62fc0d9756dea /src/identity-attribute/identity_attribute.c
parent514dd6f53cb735d0e48f35ddf92eae469c0abc8a (diff)
parent24a0b84d503375bf66b5df932cd18631cc88cf8d (diff)
Merge branch 'identity_abe' into identity_oidc
Diffstat (limited to 'src/identity-attribute/identity_attribute.c')
-rw-r--r--src/identity-attribute/identity_attribute.c421
1 files changed, 421 insertions, 0 deletions
diff --git a/src/identity-attribute/identity_attribute.c b/src/identity-attribute/identity_attribute.c
new file mode 100644
index 0000000000..a8aae6ced7
--- /dev/null
+++ b/src/identity-attribute/identity_attribute.c
@@ -0,0 +1,421 @@
+/*
+ This file is part of GNUnet
+ Copyright (C) 2010-2015 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file identity-provider/identity_attribute.c
+ * @brief helper library to manage identity attributes
+ * @author Martin Schanzenbach
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "identity_attribute.h"
+#include "gnunet_identity_attribute_plugin.h"
+
+/**
+ * Handle for a plugin
+ */
+struct Plugin
+{
+ /**
+ * Name of the plugin
+ */
+ char *library_name;
+
+ /**
+ * Plugin API
+ */
+ struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api;
+};
+
+/**
+ * Plugins
+ */
+static struct Plugin **attr_plugins;
+
+/**
+ * Number of plugins
+ */
+static unsigned int num_plugins;
+
+/**
+ * Init canary
+ */
+static int initialized;
+
+/**
+ * Add a plugin
+ */
+static void
+add_plugin (void* cls,
+ const char *library_name,
+ void *lib_ret)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api = lib_ret;
+ struct Plugin *plugin;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Loading attribute plugin `%s'\n",
+ library_name);
+ plugin = GNUNET_new (struct Plugin);
+ plugin->api = api;
+ plugin->library_name = GNUNET_strdup (library_name);
+ GNUNET_array_append (attr_plugins, num_plugins, plugin);
+}
+
+/**
+ * Load plugins
+ */
+static void
+init()
+{
+ if (GNUNET_YES == initialized)
+ return;
+ initialized = GNUNET_YES;
+ GNUNET_PLUGIN_load_all ("libgnunet_plugin_identity_attribute_", NULL,
+ &add_plugin, NULL);
+}
+
+/**
+ * Convert a type name to the corresponding number
+ *
+ * @param typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+uint32_t
+GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (const char *typename)
+{
+ unsigned int i;
+ struct Plugin *plugin;
+ uint32_t ret;
+
+ init ();
+ for (i = 0; i < num_plugins; i++)
+ {
+ plugin = attr_plugins[i];
+ if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
+ typename)))
+ return ret;
+ }
+ return UINT32_MAX;
+}
+
+/**
+ * Convert a type number to the corresponding type string
+ *
+ * @param type number of a type
+ * @return corresponding typestring, NULL on error
+ */
+const char*
+GNUNET_IDENTITY_ATTRIBUTE_number_to_typename (uint32_t type)
+{
+ unsigned int i;
+ struct Plugin *plugin;
+ const char *ret;
+
+ init ();
+ for (i = 0; i < num_plugins; i++)
+ {
+ plugin = attr_plugins[i];
+ if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
+ type)))
+ return ret;
+ }
+ return NULL;
+}
+
+/**
+ * Convert human-readable version of a 'claim' of an attribute to the binary
+ * representation
+ *
+ * @param type type of the claim
+ * @param s human-readable string
+ * @param data set to value in binary encoding (will be allocated)
+ * @param data_size set to number of bytes in @a data
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_IDENTITY_ATTRIBUTE_string_to_value (uint32_t type,
+ const char *s,
+ void **data,
+ size_t *data_size)
+{
+ unsigned int i;
+ struct Plugin *plugin;
+
+ init ();
+ for (i = 0; i < num_plugins; i++)
+ {
+ plugin = attr_plugins[i];
+ if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
+ type,
+ s,
+ data,
+ data_size))
+ return GNUNET_OK;
+ }
+ return GNUNET_SYSERR;
+}
+
+/**
+ * Convert the 'claim' of an attribute to a string
+ *
+ * @param type the type of attribute
+ * @param data claim in binary encoding
+ * @param data_size number of bytes in @a data
+ * @return NULL on error, otherwise human-readable representation of the claim
+ */
+char *
+GNUNET_IDENTITY_ATTRIBUTE_value_to_string (uint32_t type,
+ const void* data,
+ size_t data_size)
+{
+ unsigned int i;
+ struct Plugin *plugin;
+ char *ret;
+
+ init();
+ for (i = 0; i < num_plugins; i++)
+ {
+ plugin = attr_plugins[i];
+ if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
+ type,
+ data,
+ data_size)))
+ return ret;
+ }
+ return NULL;
+}
+
+/**
+ * Create a new attribute.
+ *
+ * @param name the attribute name
+ * @param type the attribute type
+ * @param data the attribute value
+ * @param data_size the attribute value size
+ * @return the new attribute
+ */
+struct GNUNET_IDENTITY_ATTRIBUTE_Claim *
+GNUNET_IDENTITY_ATTRIBUTE_claim_new (const char* attr_name,
+ uint32_t attr_type,
+ const void* data,
+ size_t data_size)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
+ char *write_ptr;
+
+ attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) +
+ strlen (attr_name) + 1 +
+ data_size);
+ attr->type = attr_type;
+ attr->data_size = data_size;
+ attr->version = 0;
+ write_ptr = (char*)&attr[1];
+ GNUNET_memcpy (write_ptr,
+ attr_name,
+ strlen (attr_name) + 1);
+ attr->name = write_ptr;
+ write_ptr += strlen (attr->name) + 1;
+ GNUNET_memcpy (write_ptr,
+ data,
+ data_size);
+ attr->data = write_ptr;
+ return attr;
+}
+
+size_t
+GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+ size_t len = 0;
+ for (le = attrs->list_head; NULL != le; le = le->next)
+ len += GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim);
+ return len;
+}
+
+size_t
+GNUNET_IDENTITY_ATTRIBUTE_list_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
+ char *result)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+ size_t len;
+ size_t total_len;
+ char* write_ptr;
+
+ write_ptr = result;
+ total_len = 0;
+ for (le = attrs->list_head; NULL != le; le = le->next)
+ {
+ len = GNUNET_IDENTITY_ATTRIBUTE_serialize (le->claim,
+ write_ptr);
+ total_len += len;
+ write_ptr += len;
+ }
+ return total_len;
+}
+
+struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *
+GNUNET_IDENTITY_ATTRIBUTE_list_deserialize (const char* data,
+ size_t data_size)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+ size_t attr_len;
+ const char* read_ptr;
+
+ if (data_size < sizeof (struct Attribute))
+ return NULL;
+
+ attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
+ read_ptr = data;
+ while (((data + data_size) - read_ptr) >= sizeof (struct Attribute))
+ {
+
+ le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
+ le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (read_ptr,
+ data_size - (read_ptr - data));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Deserialized attribute %s\n", le->claim->name);
+ GNUNET_CONTAINER_DLL_insert (attrs->list_head,
+ attrs->list_tail,
+ le);
+ attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim);
+ read_ptr += attr_len;
+ }
+ return attrs;
+}
+
+struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList*
+GNUNET_IDENTITY_ATTRIBUTE_list_dup (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *result_le;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *result;
+ size_t len;
+
+ result = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
+ for (le = attrs->list_head; NULL != le; le = le->next)
+ {
+ result_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
+ len = sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) + le->claim->data_size;
+ result_le->claim = GNUNET_malloc (len);
+ GNUNET_memcpy (result_le->claim,
+ le->claim,
+ len);
+ result_le->claim->name = (const char*)&result_le->claim[1];
+ GNUNET_CONTAINER_DLL_insert (result->list_head,
+ result->list_tail,
+ result_le);
+ }
+ return result;
+}
+
+
+void
+GNUNET_IDENTITY_ATTRIBUTE_list_destroy (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *tmp_le;
+
+ for (le = attrs->list_head; NULL != le;)
+ {
+ GNUNET_free (le->claim);
+ tmp_le = le;
+ le = le->next;
+ GNUNET_free (tmp_le);
+ }
+ GNUNET_free (attrs);
+
+}
+
+size_t
+GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr)
+{
+ return sizeof (struct Attribute)
+ + strlen (attr->name)
+ + attr->data_size;
+}
+
+size_t
+GNUNET_IDENTITY_ATTRIBUTE_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
+ char *result)
+{
+ size_t data_len_ser;
+ size_t name_len;
+ struct Attribute *attr_ser;
+ char* write_ptr;
+
+ attr_ser = (struct Attribute*)result;
+ attr_ser->attribute_type = htons (attr->type);
+ attr_ser->attribute_version = htonl (attr->version);
+ name_len = strlen (attr->name);
+ attr_ser->name_len = htons (name_len);
+ write_ptr = (char*)&attr_ser[1];
+ GNUNET_memcpy (write_ptr, attr->name, name_len);
+ write_ptr += name_len;
+ //TODO plugin-ize
+ //data_len_ser = plugin->serialize_attribute_value (attr,
+ // &attr_ser[1]);
+ data_len_ser = attr->data_size;
+ GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
+ attr_ser->data_size = htons (data_len_ser);
+
+ return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size;
+}
+
+struct GNUNET_IDENTITY_ATTRIBUTE_Claim *
+GNUNET_IDENTITY_ATTRIBUTE_deserialize (const char* data,
+ size_t data_size)
+{
+ struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
+ struct Attribute *attr_ser;
+ size_t data_len;
+ size_t name_len;
+ char* write_ptr;
+
+ if (data_size < sizeof (struct Attribute))
+ return NULL;
+
+ attr_ser = (struct Attribute*)data;
+ data_len = ntohs (attr_ser->data_size);
+ name_len = ntohs (attr_ser->name_len);
+ attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim)
+ + data_len + name_len + 1);
+ attr->type = ntohs (attr_ser->attribute_type);
+ attr->version = ntohl (attr_ser->attribute_version);
+ attr->data_size = ntohs (attr_ser->data_size);
+
+ write_ptr = (char*)&attr[1];
+ GNUNET_memcpy (write_ptr,
+ &attr_ser[1],
+ name_len);
+ write_ptr[name_len] = '\0';
+ attr->name = write_ptr;
+
+ write_ptr += name_len + 1;
+ GNUNET_memcpy (write_ptr,
+ (char*)&attr_ser[1] + name_len,
+ attr->data_size);
+ attr->data = write_ptr;
+ return attr;
+
+}
+
+/* end of identity_attribute.c */