*/
#define GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING 1
+/**
+* No value attestation.
+*/
+#define GNUNET_RECLAIM_ATTESTATION_TYPE_NONE 0
+
+/**
+* A JSON Web Token attestation.
+*/
+#define GNUNET_RECLAIM_ATTESTATION_TYPE_JWT 1
/**
* An attribute.
const void *data;
};
+/**
+ * An attestation.
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim
+{
+ /**
+ * ID
+ */
+ uint64_t id;
+
+ /**
+ * Type/Format of Claim
+ */
+ uint32_t type;
+
+ /**
+ * Version
+ */
+ uint32_t version;
+
+ /**
+ * The name of the attribute. Note "name" must never be individually
+ * free'd
+ */
+ const char *name;
+
+ /**
+ * Number of bytes in @e data.
+ */
+ size_t data_size;
+
+ /**
+ * Binary value stored as attribute value. Note: "data" must never
+ * be individually 'malloc'ed, but instead always points into some
+ * existing data area.
+ */
+ const void *data;
+};
/**
* A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
const char *
GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type);
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the attestation to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
+ const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr);
+
+
+/**
+ * Serialize an attestation
+ *
+ * @param attr the attestation to serialize
+ * @param result the serialized attestation
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize (
+ const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+ char *result);
+
+
+/**
+ * Deserialize an attestation
+ *
+ * @param data the serialized attestation
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size);
+
+
+/**
+ * Create a new attestation.
+ *
+ * @param attr_name the attestation name
+ * @param type the attestation type
+ * @param data the attestation value
+ * @param data_size the attestation value size
+ * @return the new attestation
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
+ uint32_t type,
+ const void *data,
+ size_t data_size);
+
+/**
+ * Convert the 'claim' of an attestation to a string
+ *
+ * @param type the type of attestation
+ * @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_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
+ const void *data,
+ size_t data_size);
+
+/**
+ * Convert human-readable version of a 'claim' of an attestation 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_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
+ const char *s,
+ void **data,
+ size_t *data_size);
+
+/**
+ * Convert an attestation type number to the corresponding attestation type string
+ *
+ * @param type number of a type
+ * @return corresponding typestring, NULL on error
+ */
+const char *
+GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type);
+
+/**
+ * Convert an attestation type name to the corresponding number
+ *
+ * @param typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+uint32_t
+GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename);
#if 0 /* keep Emacsens' auto-indent happy */
{
* Number to typename.
*/
GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename;
+
+ /**
+* Attestation Conversion to string.
+*/
+ GNUNET_RECLAIM_ATTRIBUTE_ValueToStringFunction value_to_string_attest;
+
+ /**
+ * Attestation Conversion to binary.
+ */
+ GNUNET_RECLAIM_ATTRIBUTE_StringToValueFunction string_to_value_attest;
+
+ /**
+ * Attestation Typename to number.
+ */
+ GNUNET_RECLAIM_ATTRIBUTE_TypenameToNumberFunction typename_to_number_attest;
+
+ /**
+ * Attestation Number to typename.
+ */
+ GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename_attest;
+
};
}
}
+/**
+ * Convert the 'value' of an attestation to a string.
+ *
+ * @param cls closure, unused
+ * @param type type of the attestation
+ * @param data value in binary encoding
+ * @param data_size number of bytes in @a data
+ * @return NULL on error, otherwise human-readable representation of the value
+ */
+static char *
+gnuid_value_to_string_attest (void *cls,
+ uint32_t type,
+ const void *data,
+ size_t data_size)
+{
+ switch (type)
+ {
+ case GNUNET_RECLAIM_ATTESTATION_TYPE_JWT:
+ return GNUNET_strndup (data, data_size);
+
+ default:
+ return NULL;
+ }
+}
+
+
+/**
+ * Convert human-readable version of a 'value' of an attestation to the binary
+ * representation.
+ *
+ * @param cls closure, unused
+ * @param type type of the attestation
+ * @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
+ */
+static int
+gnuid_string_to_value_attest (void *cls,
+ uint32_t type,
+ const char *s,
+ void **data,
+ size_t *data_size)
+{
+ if (NULL == s)
+ return GNUNET_SYSERR;
+ switch (type)
+ {
+ case GNUNET_RECLAIM_ATTESTATION_TYPE_JWT:
+ *data = GNUNET_strdup (s);
+ *data_size = strlen (s);
+ return GNUNET_OK;
+
+ default:
+ return GNUNET_SYSERR;
+ }
+}
/**
* Mapping of attribute type numbers to human-readable
} gnuid_name_map[] = { { "STRING", GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING },
{ NULL, UINT32_MAX } };
+/**
+ * Mapping of attribute type numbers to human-readable
+ * attribute type names.
+ */
+static struct
+{
+ const char *name;
+ uint32_t number;
+} gnuid_attest_name_map[] = { { "STRING",
+ GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING },
+ { NULL, UINT32_MAX } };
/**
* Convert a type name to the corresponding number.
return gnuid_name_map[i].name;
}
+/**
+ * Convert a type name to the corresponding number.
+ *
+ * @param cls closure, unused
+ * @param gnuid_typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+static uint32_t
+gnuid_typename_to_number_attest (void *cls, const char *gnuid_typename)
+{
+ unsigned int i;
+
+ i = 0;
+ while ((NULL != gnuid_attest_name_map[i].name) &&
+ (0 != strcasecmp (gnuid_typename, gnuid_attest_name_map[i].name)))
+ i++;
+ return gnuid_attest_name_map[i].number;
+}
+
+/**
+ * Convert a type number (i.e. 1) to the corresponding type string
+ *
+ * @param cls closure, unused
+ * @param type number of a type to convert
+ * @return corresponding typestring, NULL on error
+ */
+static const char *
+gnuid_number_to_typename (void *cls, uint32_t type)
+{
+ unsigned int i;
+
+ i = 0;
+ while ((NULL != gnuid_attest_name_map[i].name) && (type !=
+ gnuid_attest_name_map[i].
+ number))
+ i++;
+ return gnuid_attest_name_map[i].name;
+}
/**
* Entry point for the plugin.
api->string_to_value = &gnuid_string_to_value;
api->typename_to_number = &gnuid_typename_to_number;
api->number_to_typename = &gnuid_number_to_typename;
+ api->value_to_string_attest = &gnuid_value_to_string_attest;
+ api->string_to_value_attest = &gnuid_string_to_value_attest;
+ api->typename_to_number_attest = &gnuid_typename_to_number_attest;
+ api->number_to_typename_attest = &gnuid_number_to_typename_attest;
return api;
}
return NULL;
}
+/**
+ * Convert an attestation type name to the corresponding number
+ *
+ * @param typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+uint32_t
+GNUNET_RECLAIM_ATTESTATION_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_attest (plugin->api->cls,
+ typename)))
+ return ret;
+ }
+ return UINT32_MAX;
+}
+
+/**
+ * Convert an attestation type number to the corresponding attestation type string
+ *
+ * @param type number of a type
+ * @return corresponding typestring, NULL on error
+ */
+const char *
+GNUNET_RECLAIM_ATTESTATION_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_attest (plugin->api->cls, type)))
+ return ret;
+ }
+ return NULL;
+}
+/**
+ * Convert human-readable version of a 'claim' of an attestation 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_RECLAIM_ATTESTATION_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_attest (plugin->api->cls,
+ type,
+ s,
+ data,
+ data_size))
+ return GNUNET_OK;
+ }
+ return GNUNET_SYSERR;
+}
+
+
+/**
+ * Convert the 'claim' of an attestation to a string
+ *
+ * @param type the type of attestation
+ * @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_RECLAIM_ATTESTATION_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_attest (plugin->api->cls,
+ type,
+ data,
+ data_size)))
+ return ret;
+ }
+ return NULL;
+}
/**
* Create a new attribute.
return attr;
}
+/**
+ * Create a new attestation.
+ *
+ * @param attr_name the attestation name
+ * @param type the attestation type
+ * @param data the attestation value
+ * @param data_size the attestation value size
+ * @return the new attestation
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
+ uint32_t type,
+ const void *data,
+ size_t data_size)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+ char *write_ptr;
+ char *attr_name_tmp = GNUNET_strdup (attr_name);
+
+ GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
+
+ attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
+ + strlen (attr_name_tmp) + 1 + data_size);
+ attr->type = type;
+ attr->data_size = data_size;
+ attr->version = 0;
+ write_ptr = (char *) &attr[1];
+ GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
+ attr->name = write_ptr;
+ write_ptr += strlen (attr->name) + 1;
+ GNUNET_memcpy (write_ptr, data, data_size);
+ attr->data = write_ptr;
+ GNUNET_free (attr_name_tmp);
+ return attr;
+}
/**
* Add a new attribute to a claim list
return attr;
}
+
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the attestation to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
+ const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr)
+{
+ return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
+}
+
+/**
+ * Serialize an attestation
+ *
+ * @param attr the attestation to serialize
+ * @param result the serialized attestation
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize (
+ const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+ char *result)
+{
+ size_t data_len_ser;
+ size_t name_len;
+ struct Attestation *attr_ser;
+ char *write_ptr;
+
+ attr_ser = (struct Attestation *) result;
+ attr_ser->attestation_type = htons (attr->type);
+ attr_ser->attestation_type = htonl (attr->version);
+ attr_ser->attestation_type = GNUNET_htonll (attr->id);
+ 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 Attestation) + strlen (attr->name) + attr->data_size;
+}
+
+/**
+ * Deserialize an attestation
+ *
+ * @param data the serialized attestation
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+ struct Attestation *attr_ser;
+ size_t data_len;
+ size_t name_len;
+ char *write_ptr;
+
+ if (data_size < sizeof(struct Attestation))
+ return NULL;
+
+ attr_ser = (struct Attestation *) data;
+ data_len = ntohs (attr_ser->data_size);
+ name_len = ntohs (attr_ser->name_len);
+ if (data_size < sizeof(struct Attestation) + data_len + name_len)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Buffer too small to deserialize\n");
+ return NULL;
+ }
+ attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
+ + data_len + name_len + 1);
+ attr->type = ntohs (attr_ser->attestation_type);
+ attr->version = ntohl (attr_ser->attestation_version);
+ attr->id = GNUNET_ntohll (attr_ser->attestation_id);
+ attr->data_size = data_len;
+
+ 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 reclaim_attribute.c */
// followed by data_size Attribute value data
};
+/**
+ * Serialized attestation claim
+ */
+struct Attestation
+{
+ /**
+ * Attestation type
+ */
+ uint32_t attestation_type;
+
+ /**
+ * Attestation version
+ */
+ uint32_t attestation_version;
+
+ /**
+ * Attestation ID
+ */
+ uint64_t attestation_id;
+
+ /**
+ * Name length
+ */
+ uint32_t name_len;
+
+ /**
+ * Data size
+ */
+ uint32_t data_size;
+
+ // followed by data_size Attestation value data
+};
+
#endif
*ticket = NULL;
return ret;
}
+
+/**
+ * Parse given JSON object to an attestation claim
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static int
+parse_attest (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+ const char *name_str = NULL;
+ const char *val_str = NULL;
+ const char *type_str = NULL;
+ const char *id_str = NULL;
+ char *data;
+ int unpack_state;
+ uint32_t type;
+ size_t data_size;
+
+ GNUNET_assert (NULL != root);
+
+ if (! json_is_object (root))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Error json is not array nor object!\n");
+ return GNUNET_SYSERR;
+ }
+ // interpret single attribute
+ unpack_state = json_unpack (root,
+ "{s:s, s?s, s:s, s:s!}",
+ "name",
+ &name_str,
+ "id",
+ &id_str,
+ "type",
+ &type_str,
+ "value",
+ &val_str);
+ if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
+ (NULL == type_str))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Error json object has a wrong format!\n");
+ return GNUNET_SYSERR;
+ }
+ type = GNUNET_RECLAIM_ATTESTATION_typename_to_number (type_str);
+ if (GNUNET_SYSERR ==
+ (GNUNET_RECLAIM_ATTESTATION_string_to_value (type,
+ val_str,
+ (void **) &data,
+ &data_size)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute value invalid!\n");
+ return GNUNET_SYSERR;
+ }
+ attr = GNUNET_RECLAIM_ATTESTATION_claim_new (name_str, type, data, data_size);
+ if ((NULL == id_str) || (0 == strlen (id_str)))
+ attr->id = 0;
+ else
+ GNUNET_STRINGS_string_to_data (id_str,
+ strlen (id_str),
+ &attr->id,
+ sizeof(uint64_t));
+
+ *(struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr = attr;
+ return GNUNET_OK;
+}
+
+/**
+ * Cleanup data left from parsing RSA public key.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_attest (void *cls, struct GNUNET_JSON_Specification *spec)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_Claim **attr;
+
+ attr = (struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr;
+ if (NULL != *attr)
+ {
+ GNUNET_free (*attr);
+ *attr = NULL;
+ }
+}
+/**
+ * JSON Specification for Reclaim attestation claims.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest (struct
+ GNUNET_RECLAIM_ATTESTATION_Claim **attr)
+{
+ struct GNUNET_JSON_Specification ret = { .parser = &parse_attest,
+ .cleaner = &clean_attest,
+ .cls = NULL,
+ .field = NULL,
+ .ptr = attr,
+ .ptr_size = 0,
+ .size_ptr = NULL };
+
+ *attr = NULL;
+ return ret;
+}
*/
struct GNUNET_JSON_Specification
GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket);
+
+/**
+ * JSON Specification for Reclaim attestation claims.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest (struct
+ GNUNET_RECLAIM_ATTESTATION_Claim **attr);