From 4aae05d2af2c2bba36bdd9199f75c45117f40d0b Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Fri, 7 Feb 2020 21:15:59 +0100 Subject: [PATCH] add expiration --- src/include/gnunet_reclaim_lib.h | 15 ++- src/include/gnunet_reclaim_plugin.h | 39 +++++++- src/include/gnunet_reclaim_service.h | 3 +- src/reclaim/gnunet-reclaim.c | 6 +- src/reclaim/gnunet-service-reclaim.c | 11 +- src/reclaim/plugin_reclaim_attestation_jwt.c | 100 +++++++++++++++++-- src/reclaim/plugin_rest_openid_connect.c | 3 +- src/reclaim/plugin_rest_reclaim.c | 21 +++- src/reclaim/reclaim.h | 5 - src/reclaim/reclaim_api.c | 18 +--- src/reclaim/reclaim_attestation.c | 49 ++++++++- 11 files changed, 216 insertions(+), 54 deletions(-) diff --git a/src/include/gnunet_reclaim_lib.h b/src/include/gnunet_reclaim_lib.h index 6d3503950..54d284f3c 100644 --- a/src/include/gnunet_reclaim_lib.h +++ b/src/include/gnunet_reclaim_lib.h @@ -262,7 +262,8 @@ struct GNUNET_RECLAIM_AttestationListEntry */ struct GNUNET_RECLAIM_Attribute * GNUNET_RECLAIM_attribute_new (const char *attr_name, - const struct GNUNET_RECLAIM_Identifier *attestation, + const struct + GNUNET_RECLAIM_Identifier *attestation, uint32_t type, const void *data, size_t data_size); @@ -489,7 +490,6 @@ GNUNET_RECLAIM_attestation_list_deserialize (const char *data, size_t data_size); - /** * @param attestation the attestation to serialize * @return the required buffer size @@ -593,8 +593,17 @@ GNUNET_RECLAIM_attestation_typename_to_number (const char *typename); * @return corresponding number, UINT32_MAX on error */ struct GNUNET_RECLAIM_AttributeList* -GNUNET_RECLAIM_attestation_get_attributes (const struct GNUNET_RECLAIM_Attestation *attest); +GNUNET_RECLAIM_attestation_get_attributes (const struct + GNUNET_RECLAIM_Attestation *attest); + +char* +GNUNET_RECLAIM_attestation_get_issuer (const struct + GNUNET_RECLAIM_Attestation *attest); +int +GNUNET_RECLAIM_attestation_get_expiration (const struct + GNUNET_RECLAIM_Attestation *attest, + struct GNUNET_TIME_Absolute *exp); #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/include/gnunet_reclaim_plugin.h b/src/include/gnunet_reclaim_plugin.h index d42ac9502..992ad0cc3 100644 --- a/src/include/gnunet_reclaim_plugin.h +++ b/src/include/gnunet_reclaim_plugin.h @@ -166,17 +166,40 @@ typedef const char *(*GNUNET_RECLAIM_AttestationNumberToTypenameFunction) ( uint32_t type); /** - * Function called to convert a type number (i.e. 1) to the - * corresponding type string + * Function called to extract attributes from an attestation * * @param cls closure - * @param type number of a type to convert - * @return corresponding typestring, NULL on error + * @param attest the attestation object + * @return an attribute list */ typedef struct GNUNET_RECLAIM_AttributeList *(*GNUNET_RECLAIM_AttestationGetAttributesFunction) ( void *cls, const struct GNUNET_RECLAIM_Attestation *attest); +/** + * Function called to get the issuer of the attestation (as string) + * + * @param cls closure + * @param attest the attestation object + * @return corresponding issuer string + */ +typedef char *(*GNUNET_RECLAIM_AttestationGetIssuerFunction) ( + void *cls, + const struct GNUNET_RECLAIM_Attestation *attest); + +/** + * Function called to get the expiration of the attestation + * + * @param cls closure + * @param attest the attestation object + * @param where to write the value + * @return GNUNET_OK if successful + */ +typedef int (*GNUNET_RECLAIM_AttestationGetExpirationFunction) ( + void *cls, + const struct GNUNET_RECLAIM_Attestation *attest, + struct GNUNET_TIME_Absolute *expiration); + /** @@ -248,7 +271,15 @@ struct GNUNET_RECLAIM_AttestationPluginFunctions */ GNUNET_RECLAIM_AttestationGetAttributesFunction get_attributes; + /** + * Attesation issuer. + */ + GNUNET_RECLAIM_AttestationGetIssuerFunction get_issuer; + /** + * Expiration. + */ + GNUNET_RECLAIM_AttestationGetExpirationFunction get_expiration; }; diff --git a/src/include/gnunet_reclaim_service.h b/src/include/gnunet_reclaim_service.h index c63ed0100..813bc1a59 100644 --- a/src/include/gnunet_reclaim_service.h +++ b/src/include/gnunet_reclaim_service.h @@ -143,8 +143,7 @@ typedef void (*GNUNET_RECLAIM_AttributeTicketResult) ( */ typedef void (*GNUNET_RECLAIM_AttestationResult) ( void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - const struct GNUNET_RECLAIM_Attestation *attestation, - const struct GNUNET_RECLAIM_AttributeList *attributes); + const struct GNUNET_RECLAIM_Attestation *attestation); /** diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c index cb9a87e37..e7ee814b6 100644 --- a/src/reclaim/gnunet-reclaim.c +++ b/src/reclaim/gnunet-reclaim.c @@ -650,8 +650,7 @@ attest_iter_finished (void *cls) static void attest_iter_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - const struct GNUNET_RECLAIM_Attestation *attest, - const struct GNUNET_RECLAIM_AttributeList *attrs) + const struct GNUNET_RECLAIM_Attestation *attest) { char *attest_str; char *attr_str; @@ -675,6 +674,8 @@ attest_iter_cb (void *cls, attest_str, attest_type, id); + struct GNUNET_RECLAIM_AttributeList *attrs = + GNUNET_RECLAIM_attestation_get_attributes (attest); if (NULL != attrs) { fprintf (stdout, @@ -692,6 +693,7 @@ attest_iter_cb (void *cls, "\t %s: %s\n", ale->attribute->name, attr_str); GNUNET_free (attr_str); } + GNUNET_RECLAIM_attribute_list_destroy (attrs); } GNUNET_free (id); } diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index ddfe05556..b617d0ec3 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -1865,7 +1865,6 @@ attest_iter_finished (void *cls) env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT); arm->id = htonl (ai->request_id); arm->attestation_len = htons (0); - arm->attributes_len = htons (0); GNUNET_MQ_send (ai->client->mq, env); GNUNET_CONTAINER_DLL_remove (ai->client->attest_iter_head, ai->client->attest_iter_tail, @@ -1908,10 +1907,8 @@ attest_iter_cb (void *cls, struct Iterator *ai = cls; struct GNUNET_MQ_Envelope *env; struct AttestationResultMessage *arm; - struct GNUNET_RECLAIM_AttributeList *attrs; struct GNUNET_RECLAIM_Attestation *att; char *data_tmp; - size_t attrs_size; if ((rd_count != 1) || (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION != rd->record_type)) @@ -1921,24 +1918,18 @@ attest_iter_cb (void *cls, } att = GNUNET_RECLAIM_attestation_deserialize (rd->data, rd->data_size); - attrs = GNUNET_RECLAIM_attestation_get_attributes (att); - attrs_size = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n", label); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTESTATION_RESULT message\n"); env = GNUNET_MQ_msg_extra (arm, - rd->data_size + attrs_size, + rd->data_size, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT); arm->id = htonl (ai->request_id); arm->attestation_len = htons (rd->data_size); - arm->attributes_len = htons (attrs_size); GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity); data_tmp = (char *) &arm[1]; GNUNET_memcpy (data_tmp, rd->data, rd->data_size); - data_tmp += rd->data_size; - GNUNET_RECLAIM_attribute_list_serialize (attrs, - data_tmp); GNUNET_MQ_send (ai->client->mq, env); } diff --git a/src/reclaim/plugin_reclaim_attestation_jwt.c b/src/reclaim/plugin_reclaim_attestation_jwt.c index 8a67b18cd..ec31584d5 100644 --- a/src/reclaim/plugin_reclaim_attestation_jwt.c +++ b/src/reclaim/plugin_reclaim_attestation_jwt.c @@ -142,12 +142,12 @@ jwt_number_to_typename (void *cls, uint32_t type) return jwt_attest_name_map[i].name; } + /** * Parse a JWT and return the respective claim value as Attribute * + * @param cls the plugin * @param attest the jwt attestation - * @param claim the name of the claim in the JWT - * * @return a GNUNET_RECLAIM_Attribute, containing the new value */ struct GNUNET_RECLAIM_AttributeList * @@ -163,6 +163,7 @@ jwt_parse_attributes (void *cls, json_t *json_val; json_error_t *json_err = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", attest->data); if (GNUNET_RECLAIM_ATTESTATION_TYPE_JWT != attest->type) return NULL; attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); @@ -170,27 +171,112 @@ jwt_parse_attributes (void *cls, jwt_string = GNUNET_strdup (attest->data); const char *jwt_body = strtok (jwt_string, delim); jwt_body = strtok (NULL, delim); - GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body), - (void **) &decoded_jwt); + GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), + (void **) &decoded_jwt); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", decoded_jwt); + GNUNET_assert (NULL != decoded_jwt); json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); const char *key; json_t *value; json_object_foreach (json_val, key, value) { + if (0 == strcmp ("iss", key)) + continue; + if (0 == strcmp ("exp", key)) + continue; + if (0 == strcmp ("iat", key)) + continue; + if (0 == strcmp ("nbf", key)) + continue; + if (0 == strcmp ("aud", key)) + continue; val_str = json_dumps (value, JSON_ENCODE_ANY); GNUNET_RECLAIM_attribute_list_add (attrs, key, NULL, - GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING,//FIXME + GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING,// FIXME val_str, strlen (val_str)); GNUNET_free (val_str); } GNUNET_free (jwt_string); - //FIXME needed?? return attrs; } +/** + * Parse a JWT and return the issuer + * + * @param cls the plugin + * @param attest the jwt attestation + * @return a string, containing the isser + */ +char * +jwt_get_issuer (void *cls, + const struct GNUNET_RECLAIM_Attestation *attest) +{ + const char *jwt_body; + char *jwt_string; + char delim[] = "."; + char *issuer = NULL; + char *decoded_jwt; + json_t *issuer_json; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n"); + json_t *json_val; + json_error_t *json_err = NULL; + + if (GNUNET_RECLAIM_ATTESTATION_TYPE_JWT != attest->type) + return NULL; + jwt_string = GNUNET_strdup (attest->data); + jwt_body = strtok (jwt_string, delim); + jwt_body = strtok (NULL, delim); + GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), + (void **) &decoded_jwt); + json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); + issuer_json = json_object_get (json_val, "iss"); + if ((NULL == issuer_json) || (! json_is_string (issuer_json))) + return NULL; + issuer = GNUNET_strdup (json_string_value (issuer_json)); + GNUNET_free (jwt_string); + return issuer; +} + + +/** + * Parse a JWT and return the expiration + * + * @param cls the plugin + * @param attest the jwt attestation + * @return a string, containing the isser + */ +int +jwt_get_expiration (void *cls, + const struct GNUNET_RECLAIM_Attestation *attest, + struct GNUNET_TIME_Absolute *exp) +{ + const char *jwt_body; + char *jwt_string; + char delim[] = "."; + char *decoded_jwt; + json_t *exp_json; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n"); + json_t *json_val; + json_error_t *json_err = NULL; + + if (GNUNET_RECLAIM_ATTESTATION_TYPE_JWT != attest->type) + return GNUNET_NO; + jwt_string = GNUNET_strdup (attest->data); + jwt_body = strtok (jwt_string, delim); + jwt_body = strtok (NULL, delim); + GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), + (void **) &decoded_jwt); + json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); + exp_json = json_object_get (json_val, "exp"); + if ((NULL == exp_json) || (! json_is_integer (exp_json))) + return GNUNET_SYSERR; + exp->abs_value_us = json_integer_value (exp_json) * 1000 * 1000; + GNUNET_free (jwt_string); + return GNUNET_OK; +} /** @@ -210,6 +296,8 @@ libgnunet_plugin_reclaim_attestation_jwt_init (void *cls) api->typename_to_number = &jwt_typename_to_number; api->number_to_typename = &jwt_number_to_typename; api->get_attributes = &jwt_parse_attributes; + api->get_issuer = &jwt_get_issuer; + api->get_expiration = &jwt_get_expiration; return api; } diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 3e138f259..14a96ed19 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -988,8 +988,7 @@ oidc_attest_collect_finished_cb (void *cls) static void oidc_attest_collect (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - const struct GNUNET_RECLAIM_Attestation *attest, - const struct GNUNET_RECLAIM_AttributeList *attrs) + const struct GNUNET_RECLAIM_Attestation *attest) { struct RequestHandle *handle = cls; struct GNUNET_RECLAIM_AttributeListEntry *le; diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index 8b3aee8ba..780a184d2 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -621,21 +621,24 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, static void attest_collect (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - const struct GNUNET_RECLAIM_Attestation *attest, - const struct GNUNET_RECLAIM_AttributeList *attrs) + const struct GNUNET_RECLAIM_Attestation *attest) { struct RequestHandle *handle = cls; + struct GNUNET_RECLAIM_AttributeList *attrs; struct GNUNET_RECLAIM_AttributeListEntry *ale; + struct GNUNET_TIME_Absolute exp; json_t *attr_obj; json_t *attest_obj; const char *type; char *tmp_value; char *id_str; + char *issuer; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation: %s\n", attest->name); - + attrs = GNUNET_RECLAIM_attestation_get_attributes (attest); + issuer = GNUNET_RECLAIM_attestation_get_issuer (attest); tmp_value = GNUNET_RECLAIM_attestation_value_to_string (attest->type, attest->data, attest->data_size); @@ -644,10 +647,21 @@ attest_collect (void *cls, json_object_set_new (attest_obj, "name", json_string (attest->name)); type = GNUNET_RECLAIM_attestation_number_to_typename (attest->type); json_object_set_new (attest_obj, "type", json_string (type)); + if (NULL != issuer) + { + json_object_set_new (attest_obj, "issuer", json_string (issuer)); + GNUNET_free (issuer); + } + if (GNUNET_OK == GNUNET_RECLAIM_attestation_get_expiration (attest, + &exp)) + { + json_object_set_new (attest_obj, "expiration", json_integer (exp.abs_value_us)); + } id_str = GNUNET_STRINGS_data_to_string_alloc (&attest->id, sizeof(attest->id)); json_object_set_new (attest_obj, "id", json_string (id_str)); GNUNET_free (tmp_value); + GNUNET_free (id_str); if (NULL != attrs) { json_t *attr_arr = json_array (); @@ -673,6 +687,7 @@ attest_collect (void *cls, json_object_set_new (attest_obj, "attributes", attr_arr); } json_array_append_new (handle->resp_object, attest_obj); + GNUNET_RECLAIM_attribute_list_destroy (attrs); GNUNET_RECLAIM_get_attestations_next (handle->attest_it); } diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h index 2cd07e861..7b5d7ab19 100644 --- a/src/reclaim/reclaim.h +++ b/src/reclaim/reclaim.h @@ -178,11 +178,6 @@ struct AttestationResultMessage */ uint16_t attestation_len GNUNET_PACKED; - /** - * Length of serialized attribute data - */ - uint16_t attributes_len GNUNET_PACKED; - /** * always zero (for alignment) */ diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index 8558b19df..b863789a2 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -779,14 +779,11 @@ static int check_attestation_result (void *cls, const struct AttestationResultMessage *msg) { size_t msg_len; - size_t attr_len; size_t attest_len; msg_len = ntohs (msg->header.size); attest_len = ntohs (msg->attestation_len); - attr_len = ntohs (msg->attributes_len); - if (msg_len != sizeof(struct AttestationResultMessage) - + attr_len + attest_len) + if (msg_len != sizeof(struct AttestationResultMessage) + attest_len) { GNUNET_break (0); return GNUNET_SYSERR; @@ -809,14 +806,11 @@ handle_attestation_result (void *cls, const struct static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy; struct GNUNET_RECLAIM_Handle *h = cls; struct GNUNET_RECLAIM_AttestationIterator *it; - struct GNUNET_RECLAIM_AttributeList *attrs; struct GNUNET_RECLAIM_Operation *op; size_t att_len; - size_t attrs_len; uint32_t r_id = ntohl (msg->id); att_len = ntohs (msg->attestation_len); - attrs_len = ntohs (msg->attributes_len); LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attestation result.\n"); @@ -847,7 +841,7 @@ handle_attestation_result (void *cls, const struct if (NULL != op) { if (NULL != op->at_cb) - op->at_cb (op->cls, NULL, NULL, NULL); + op->at_cb (op->cls, NULL, NULL); GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); free_op (op); } @@ -857,22 +851,18 @@ handle_attestation_result (void *cls, const struct { struct GNUNET_RECLAIM_Attestation *att; att = GNUNET_RECLAIM_attestation_deserialize ((char *) &msg[1], att_len); - char *read_ptr = ((char *) &msg[1]) + att_len; - attrs = GNUNET_RECLAIM_attribute_list_deserialize (read_ptr, attrs_len); if (NULL != it) { if (NULL != it->proc) - it->proc (it->proc_cls, &msg->identity, att, attrs); + it->proc (it->proc_cls, &msg->identity, att); } else if (NULL != op) { if (NULL != op->at_cb) - op->at_cb (op->cls, &msg->identity, att, attrs); + op->at_cb (op->cls, &msg->identity, att); } GNUNET_free (att); - if (NULL != attrs) - GNUNET_RECLAIM_attribute_list_destroy (attrs); return; } GNUNET_assert (0); diff --git a/src/reclaim/reclaim_attestation.c b/src/reclaim/reclaim_attestation.c index 961c6ede4..66da8e74a 100644 --- a/src/reclaim/reclaim_attestation.c +++ b/src/reclaim/reclaim_attestation.c @@ -501,8 +501,10 @@ GNUNET_RECLAIM_attestation_deserialize (const char *data, size_t data_size) return attestation; } + struct GNUNET_RECLAIM_AttributeList* -GNUNET_RECLAIM_attestation_get_attributes (const struct GNUNET_RECLAIM_Attestation *attest) +GNUNET_RECLAIM_attestation_get_attributes (const struct + GNUNET_RECLAIM_Attestation *attest) { unsigned int i; struct Plugin *plugin; @@ -512,9 +514,50 @@ GNUNET_RECLAIM_attestation_get_attributes (const struct GNUNET_RECLAIM_Attestati { plugin = attest_plugins[i]; if (NULL != - (ret = plugin->api->get_attributes (plugin->api->cls, - attest))) + (ret = plugin->api->get_attributes (plugin->api->cls, + attest))) return ret; } return NULL; } + + +char* +GNUNET_RECLAIM_attestation_get_issuer (const struct + GNUNET_RECLAIM_Attestation *attest) +{ + unsigned int i; + struct Plugin *plugin; + char *ret; + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = attest_plugins[i]; + if (NULL != + (ret = plugin->api->get_issuer (plugin->api->cls, + attest))) + return ret; + } + return NULL; +} + + +int +GNUNET_RECLAIM_attestation_get_expiration (const struct + GNUNET_RECLAIM_Attestation *attest, + struct GNUNET_TIME_Absolute* exp) +{ + unsigned int i; + struct Plugin *plugin; + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = attest_plugins[i]; + if (GNUNET_OK != plugin->api->get_expiration (plugin->api->cls, + attest, + exp)) + continue; + return GNUNET_OK; + } + return GNUNET_SYSERR; +} -- 2.25.1