*/
#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR 65554
+/**
+ * Record type for reclaim attestation references
+ */
+#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF 65555
+
/**
* Flags that can be set for a record.
*/
#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT 979
+#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE 980
+
/**************************************************
*
* ABD MESSAGE TYPES
const void *data;
};
+/**
+ * A reference to an Attestatiom.
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE
+{
+ /**
+ * ID
+ */
+ uint64_t id;
+
+ /**
+ * Referenced ID of Attestation
+ */
+ uint64_t id_attest;
+
+ /**
+ * The name of the attribute/attestation reference value. Note "name" must never be individually
+ * free'd
+ */
+ const char *name;
+
+ /**
+ * The name of the attribute/attestation reference value. Note "name" must never be individually
+ * free'd
+ */
+ const char *reference_value;
+};
+
/**
* A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
*/
uint32_t
GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename);
+/**
+ * Create a new attestation reference.
+ *
+ * @param attr_name the referenced claim name
+ * @param ref_value the claim name in the attestation
+ * @return the new reference
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
+ const char *ref_value);
+
+
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the reference to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+ const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr);
+
+/**
+ * Serialize a reference
+ *
+ * @param attr the reference to serialize
+ * @param result the serialized reference
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize (
+ const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+ char *result);
+
+/**
+ * Deserialize a reference
+ *
+ * @param data the serialized reference
+ * @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_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t data_size);
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
*/
typedef void (*GNUNET_RECLAIM_AttributeResult) (
void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
- const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+ const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest);
GNUNET_RECLAIM_AttributeResult proc, void *proc_cls,
GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls);
+/**
+ * Store an attestation reference. If the reference is already present,
+ * it is replaced with the new reference.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey private key of the identity
+ * @param attr the reference value
+ * @param exp_interval the relative expiration interval for the reference
+ * @param cont continuation to call when done
+ * @param cont_cls closure for @a cont
+ * @return handle to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_store (
+ struct GNUNET_RECLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+ const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+ const struct GNUNET_TIME_Relative *exp_interval,
+ GNUNET_RECLAIM_ContinuationWithStatus cont,
+ void *cont_cls);
/**
* Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
return attr;
}
+/**
+ * Create a new attestation reference.
+ *
+ * @param attr_name the referenced claim name
+ * @param ref_value the claim name in the attestation
+ * @return the new reference
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
+ const char *ref_value)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+ char *write_ptr;
+ char *attr_name_tmp = GNUNET_strdup (attr_name);
+ char *ref_value_tmp = GNUNET_strdup (ref_value);
+
+ GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
+ GNUNET_STRINGS_utf8_tolower (ref_value, ref_value_tmp);
+
+ attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE)
+ + strlen (attr_name_tmp) + strlen (ref_value_tmp) + 2);
+
+ write_ptr = (char *) &attr[1];
+ GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
+ attr->name = write_ptr;
+
+ write_ptr = (char *) &attr[1];
+ GNUNET_memcpy (write_ptr, ref_value_tmp, strlen (ref_value_tmp) + 1);
+ attr->reference_value = write_ptr;
+
+ GNUNET_free (attr_name_tmp);
+ GNUNET_free (ref_value_tmp);
+ return attr;
+}
+
/**
* Add a new attribute to a claim list
*
return attr;
}
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the reference to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+ const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr)
+{
+ return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
+ attr->reference_value);
+}
+
+
+/**
+ * Serialize a reference
+ *
+ * @param attr the reference to serialize
+ * @param result the serialized reference
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize (
+ const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+ char *result)
+{
+ size_t name_len;
+ size_t refval_len;
+ struct Attestation_Reference *attr_ser;
+ char *write_ptr;
+ attr_ser = (struct Attestation_Reference *) result;
+ attr_ser->reference_id = GNUNET_htonll (attr->id);
+ attr_ser->attestation_id = GNUNET_htonll (attr->id_attest);
+ name_len = strlen (attr->name);
+ refval_len = strlen (attr->reference_value);
+ attr_ser->name_len = htons (name_len);
+ attr_ser->ref_value_len = htons (refval_len);
+ write_ptr = (char *) &attr_ser[1];
+ GNUNET_memcpy (write_ptr, attr->name, name_len);
+ write_ptr += name_len;
+ GNUNET_memcpy (write_ptr, attr->reference_value, refval_len);
+
+ return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
+ attr->reference_value);
+}
+
+/**
+ * Deserialize a reference
+ *
+ * @param data the serialized reference
+ * @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_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t data_size)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+ struct Attestation_Reference *attr_ser;
+ size_t name_len;
+ size_t refval_len;
+ char *write_ptr;
+
+ if (data_size < sizeof(struct Attestation_Reference))
+ return NULL;
+ attr_ser = (struct Attestation_Reference *) data;
+ name_len = ntohs (attr_ser->name_len);
+ refval_len = ntohs (attr_ser->ref_value_len);
+ if (data_size < sizeof(struct Attestation_Reference) + refval_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_REFERENCE)
+ + refval_len + name_len + 2);
+
+ attr->id = GNUNET_ntohll (attr_ser->reference_id);
+ attr->id_attest = GNUNET_ntohll (attr_ser->attestation_id);
+
+ 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, refval_len);
+ write_ptr[refval_len] = '\0';
+ attr->reference_value = write_ptr;
+ return attr;
+}
/* end of reclaim_attribute.c */
// followed by data_size Attestation value data
};
+/**
+ * Serialized attestation reference
+ */
+struct Attestation_Reference
+{
+ /**
+ * Reference ID
+ */
+ uint64_t reference_id;
+
+ /**
+ * The ID of the referenced attestation
+ */
+ uint64_t attestation_id;
+
+ /**
+ * Claim Name length
+ */
+ uint32_t name_len;
+
+ /**
+ * Length of the referenced value
+ */
+ uint32_t ref_value_len;
+
+
+ // followed by the name and referenced value
+};
+
#endif
*attr = 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_ref (void *cls, json_t *root, struct
+ GNUNET_JSON_Specification *spec)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+ const char *name_str = NULL;
+ const char *ref_val_str = NULL;
+ const char *ref_id_str = NULL;
+ const char *id_str = NULL;
+ int unpack_state;
+
+ 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 reference
+ unpack_state = json_unpack (root,
+ "{s:s, s?s, s:s, s:s!}",
+ "name",
+ &name_str,
+ "id",
+ &id_str,
+ "ref_id",
+ &ref_id_str,
+ "ref_value",
+ &ref_val_str);
+ if ((0 != unpack_state) || (NULL == name_str) || (NULL == ref_val_str) ||
+ (NULL == ref_id_str))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Error json object has a wrong format!\n");
+ return GNUNET_SYSERR;
+ }
+
+ attr = GNUNET_RECLAIM_ATTESTATION_reference_new (name_str, ref_val_str);
+
+ attr->id = 0;
+
+ if ((NULL == ref_id_str) || (0 == strlen (ref_id_str)))
+ attr->id_attest = 0;
+ else
+ GNUNET_STRINGS_string_to_data (ref_id_str,
+ strlen (ref_id_str),
+ &attr->id_attest,
+ sizeof(uint64_t));
+
+ *(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) 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_ref (void *cls, struct GNUNET_JSON_Specification *spec)
+{
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr;
+
+ attr = (struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr;
+ if (NULL != *attr)
+ {
+ GNUNET_free (*attr);
+ *attr = NULL;
+ }
+}
+
+/**
+ * JSON Specification for Reclaim attestation references.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest_ref (struct
+ GNUNET_RECLAIM_ATTESTATION_REFERENCE
+ **attr)
+{
+ struct GNUNET_JSON_Specification ret = { .parser = &parse_attest_ref,
+ .cleaner = &clean_attest_ref,
+ .cls = NULL,
+ .field = NULL,
+ .ptr = attr,
+ .ptr_size = 0,
+ .size_ptr = NULL };
+
+ *attr = NULL;
+ return ret;
+}
\ No newline at end of file
struct GNUNET_JSON_Specification
GNUNET_RECLAIM_JSON_spec_claim_attest (struct
GNUNET_RECLAIM_ATTESTATION_Claim **attr);
+
+ /**
+ * JSON Specification for Reclaim attestation references.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
+ * @return JSON Specification
+ */
+ struct GNUNET_JSON_Specification
+ GNUNET_RECLAIM_JSON_spec_claim_attest_ref(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr);
case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF:
return GNUNET_STRINGS_data_to_string_alloc (data, data_size);
default:
case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF:
return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size);
default:
{ "RECLAIM_OIDC_CLIENT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT },
{ "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT },
{ "RECLAIM_TICKET", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET },
+ { "RECLAIM_ATTEST_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF },
{ NULL, UINT32_MAX }
};
}
+static void
+add_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
+ const char *url,
+ void *cls)
+{
+ struct RequestHandle *handle = cls;
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
+ const char *identity;
+ struct EgoEntry *ego_entry;
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attribute;
+ struct GNUNET_TIME_Relative exp;
+ char term_data[handle->rest_handle->data_size + 1];
+ json_t *data_json;
+ json_error_t err;
+ struct GNUNET_JSON_Specification attrspec[] =
+ { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attribute),
+ GNUNET_JSON_spec_end () };
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding an attestation reference for %s.\n",
+ handle->url);
+ if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+ "reference/") + 1 >= strlen (
+ handle->url))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+ identity = handle->url + strlen (
+ GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/") + 1;
+ for (ego_entry = handle->ego_head; NULL != ego_entry;
+ ego_entry = ego_entry->next)
+ if (0 == strcmp (identity, ego_entry->identifier))
+ break;
+ if (NULL == ego_entry)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
+ return;
+ }
+ identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+ if (0 >= handle->rest_handle->data_size)
+ {
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+
+ term_data[handle->rest_handle->data_size] = '\0';
+ GNUNET_memcpy (term_data,
+ handle->rest_handle->data,
+ handle->rest_handle->data_size);
+ data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+ json_decref (data_json);
+ if (NULL == attribute)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to parse attestation reference from %s\n",
+ term_data);
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+ /**
+ * New ID for attribute
+ */
+ if (0 == attribute->id)
+ attribute->id = attribute->id_attest;
+ handle->idp = GNUNET_RECLAIM_connect (cfg);
+ exp = GNUNET_TIME_UNIT_HOURS;
+ handle->idp_op = GNUNET_RECLAIM_attestation_reference_store (handle->idp,
+ identity_priv,
+ attribute,
+ &exp,
+ &finished_cont,
+ handle);
+ GNUNET_JSON_parse_free (attrspec);
+}
+
+
static void
add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
const char *url,
void *cls)
{
+ struct RequestHandle *handle = cls;
+ /* Check for substring "reference" */
+ if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+ handle->url))
+ {
+ if ( strncmp ("reference/", (handle->url + strlen (
+ GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+ + 1), strlen (
+ "reference/")) == 0)
+ {
+ add_attestation_ref_cont (con_handle,url,cls);
+ return;
+ }
+ }
const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
const char *identity;
- struct RequestHandle *handle = cls;
struct EgoEntry *ego_entry;
struct GNUNET_RECLAIM_ATTESTATION_Claim *attribute;
struct GNUNET_TIME_Relative exp;
return op;
}
+/**
+ * Store an attestation reference. If the reference is already present,
+ * it is replaced with the new reference.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey private key of the identity
+ * @param attr the reference value
+ * @param exp_interval the relative expiration interval for the reference
+ * @param cont continuation to call when done
+ * @param cont_cls closure for @a cont
+ * @return handle to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_store (
+ struct GNUNET_RECLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+ const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+ const struct GNUNET_TIME_Relative *exp_interval,
+ GNUNET_RECLAIM_ContinuationWithStatus cont,
+ void *cont_cls)
+{
+ struct GNUNET_RECLAIM_Operation *op;
+ struct AttributeStoreMessage *sam;
+ size_t attr_len;
+ op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+ op->h = h;
+ op->as_cb = cont;
+ op->cls = cont_cls;
+ op->r_id = h->r_id_gen++;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+ attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
+ op->env = GNUNET_MQ_msg_extra (sam,
+ attr_len,
+ GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE);
+ sam->identity = *pkey;
+ sam->id = htonl (op->r_id);
+ sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
+
+ GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &sam[1]);
+
+ sam->attr_len = htons (attr_len);
+ if (NULL != h->mq)
+ GNUNET_MQ_send_copy (h->mq, op->env);
+ return op;
+}
+
+
/**
* List all attributes for a local identity.
* This MUST lock the `struct GNUNET_RECLAIM_Handle`