From d2634b1f96dfd55ae4daef294bb6c05d687354c8 Mon Sep 17 00:00:00 2001 From: Andreas Ebner Date: Tue, 25 Jun 2019 15:21:12 +0200 Subject: [PATCH] Handle all credential storage via credential service, prepared for subject side storage - new commandline parameters - new gns record type: DELEGATE for subject side storage - credential connection to namestore - store all credentials via credential service (replacing namestore) - stable, but experimental implementation, atm just using existing methods, next step: introduce own methods and replace/rename existing variables --- src/credential/Makefile.am | 1 + src/credential/gnunet-credential.c | 736 ++++++++++++++++--- src/credential/gnunet-service-credential.c | 231 +++--- src/credential/plugin_gnsrecord_credential.c | 387 ++++++---- src/credential/test_credential_own.sh | 103 +++ src/credential/test_credential_verify_and.sh | 7 +- src/include/gnunet_gnsrecord_lib.h | 2 +- 7 files changed, 1099 insertions(+), 368 deletions(-) create mode 100755 src/credential/test_credential_own.sh diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am index bc6c49deb..5b14b3def 100644 --- a/src/credential/Makefile.am +++ b/src/credential/Makefile.am @@ -42,6 +42,7 @@ gnunet_credential_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ $(top_builddir)/src/identity/libgnunetidentity.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ $(GN_LIBINTL) diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c index 0558ca5fc..35fa6ff8a 100644 --- a/src/credential/gnunet-credential.c +++ b/src/credential/gnunet-credential.c @@ -11,12 +11,12 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later - */ +*/ /** * @file gnunet-credential.c * @brief command line tool to access command line Credential service @@ -26,6 +26,7 @@ #include #include #include +#include #include "credential_misc.h" #include "credential_serialization.h" @@ -34,6 +35,16 @@ */ static const struct GNUNET_CONFIGURATION_Handle *cfg; +/** + * Handle to the namestore. + */ +static struct GNUNET_NAMESTORE_Handle *ns; + +/** + * Private key for the our zone. + */ +static struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey; + /** * EgoLookup */ @@ -120,6 +131,65 @@ static int create_cred; */ static int collect; +/** + * Create mode + */ +static int create_is; + +/** + * Create mode + */ +static int create_ss; + +/** + * Create mode + */ +static int sign_ss; + +/** + * Add mode + */ +static int add_iss; + +/** + * Signed issue credentials + */ +static char *extension; + +/** + * Queue entry for the 'add' operation. + */ +static struct GNUNET_NAMESTORE_QueueEntry *add_qe; + +/** + * Value in binary format. + */ +static void *data; + +/** + * Number of bytes in #data. + */ +static size_t data_size; + +/** + * Type string converted to DNS type value. + */ +static uint32_t type; + +/** + * Type of the record to add/remove, NULL to remove all. + */ +static char *typestring; +/** + * Expiration string converted to numeric value. + */ +static uint64_t etime; + +/** + * Is expiration time relative or absolute time? + */ +static int etime_is_rel = GNUNET_SYSERR; + /** * Task run on shutdown. Cleans up everything. * @@ -143,6 +213,21 @@ do_shutdown (void *cls) GNUNET_SCHEDULER_cancel (tt); tt = NULL; } + if (NULL != el) + { + GNUNET_IDENTITY_ego_lookup_cancel (el); + el = NULL; + } + if (NULL != add_qe) + { + GNUNET_NAMESTORE_cancel (add_qe); + add_qe = NULL; + } + if (NULL != ns) + { + GNUNET_NAMESTORE_disconnect (ns); + ns = NULL; + } } @@ -160,18 +245,18 @@ do_timeout (void *cls) static void handle_collect_result (void *cls, - unsigned int d_count, - struct GNUNET_CREDENTIAL_Delegation *dc, - unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cred) + unsigned int d_count, + struct GNUNET_CREDENTIAL_Delegation *dc, + unsigned int c_count, + struct GNUNET_CREDENTIAL_Credential *cred) { int i; - char*line; + char* line; verify_request = NULL; if (NULL != cred) { - for (i = 0; i < c_count; i++) + for (i=0;i DKCC5SMTBNV6W3VXDJ7A1N1YS6TRG7B3XC2S5N4HSXJEYYRFRCCG | D1NuT8hHEUbkCURo1lkcSPKhYiydhv4nMkV042kc9J4MgIhB2/fQKLgJUyuGlJKvYgXLf4jHXNRHJe+aCLG7jw== | 1561126006528100 + + //TODO: parse, wenn nicht als argument direkt geparsed werden kann + + char cmd_para[100]; + char para_str[1024]; + char *token; + char *tmp_str; + int matches = 0; + + tmp_str = GNUNET_strdup (extensionstring); + // use special strtok to match multiple characters + token = strtokm (tmp_str, "--"); + while (NULL != token) { + // also fills the variables if "regex"-like match + fprintf(stderr, "TOKEN: %s\n", token); + // match everything till =, ignore = (%*c), match everything including whitespaces (required for the extension parameter) + matches = SSCANF (token, "%[^=]%*c%[^\n]", cmd_para, para_str); + // string not well formatted + if (0 == matches) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ("Failed to parse to extensionstring.\n")); + GNUNET_SCHEDULER_shutdown (); + GNUNET_free (tmp_str); + return GNUNET_SYSERR; + } else { + fprintf(stderr,"Found command and parameter: %s %s\n", cmd_para, para_str); + // assign values to variables, topntail to remove trailing/leading " + if(strcmp(cmd_para, "ego") == 0) { + fprintf(stderr,"ego found and parsed\n"); + topntail(para_str); + ego_name = GNUNET_strdup(para_str); + } else if(strcmp(cmd_para, "attribute") == 0) { + fprintf(stderr,"issuer found and parsed\n"); + topntail(para_str); + issuer_attr = GNUNET_strdup(para_str); + } else if(strcmp(cmd_para, "subject") == 0) { + fprintf(stderr,"subject found and parsed\n"); + topntail(para_str); + subject_key = GNUNET_strdup(para_str); + } else if(strcmp(cmd_para, "ttl") == 0) { + fprintf(stderr,"ttl found and parsed\n"); + expiration = GNUNET_strdup(para_str); + } else if(strcmp(cmd_para, "extension") == 0) { + fprintf(stderr,"extension found and parsed\n"); + topntail(para_str); + extension = GNUNET_strdup(para_str); + } + } + token = strtokm (NULL, "--"); + } + GNUNET_free (tmp_str); + + //return GNUNET_SYSERR; + return GNUNET_OK; +} + +/** + * Parse expiration time. + * + * @param expirationstring text to parse + * @param etime_is_rel[out] set to #GNUNET_YES if time is relative + * @param etime[out] set to expiration time (abs or rel) + * @return #GNUNET_OK on success + */ +static int +parse_expiration (const char *expirationstring, + int *etime_is_rel, + uint64_t *etime) +{ + // TODO just copied from gnunet-namestore.c + struct GNUNET_TIME_Relative etime_rel; + struct GNUNET_TIME_Absolute etime_abs; + + if (0 == strcmp (expirationstring, + "never")) + { + *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; + *etime_is_rel = GNUNET_NO; + return GNUNET_OK; + } + if (GNUNET_OK == + GNUNET_STRINGS_fancy_time_to_relative (expirationstring, + &etime_rel)) + { + *etime_is_rel = GNUNET_YES; + *etime = etime_rel.rel_value_us; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Storing record with relative expiration time of %s\n", + GNUNET_STRINGS_relative_time_to_string (etime_rel, + GNUNET_NO)); + return GNUNET_OK; + } + if (GNUNET_OK == + GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, + &etime_abs)) + { + *etime_is_rel = GNUNET_NO; + *etime = etime_abs.abs_value_us; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Storing record with absolute expiration time of %s\n", + GNUNET_STRINGS_absolute_time_to_string (etime_abs)); + return GNUNET_OK; + } + return GNUNET_SYSERR; +} + +/** + * Function called if lookup fails. + */ +static void +error_cb (void *cls) +{ + // TODO: Better + fprintf(stderr, "In add_error_cb\n"); + GNUNET_SCHEDULER_shutdown (); + return; +} +static void +add_continuation (void *cls, + int32_t success, + const char *emsg) +{ + fprintf(stderr, "Start: add_continuation\n"); + + struct GNUNET_NAMESTORE_QueueEntry **qe = cls; + *qe = NULL; + + GNUNET_SCHEDULER_shutdown (); +} + +static void +get_existing_record (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const char *rec_name, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd) +{ + struct GNUNET_GNSRECORD_Data rdn[rd_count + 1]; + struct GNUNET_GNSRECORD_Data *rde; + + fprintf(stderr, "Start: get_existing_record\n"); + + fprintf(stderr, "count: %d\n", rd_count); + + + memset (rdn, 0, sizeof (struct GNUNET_GNSRECORD_Data)); + GNUNET_memcpy (&rdn[1], + rd, + rd_count * sizeof (struct GNUNET_GNSRECORD_Data)); + rde = &rdn[0]; + rde->data = data; + rde->data_size = data_size; + rde->record_type = type; + // TODO: flags + /*if (1 == is_shadow) + rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; + if (1 != is_public) + rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;*/ + rde->expiration_time = etime; + if (GNUNET_YES == etime_is_rel) + rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; + else if (GNUNET_NO != etime_is_rel) + rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; + GNUNET_assert (NULL != rec_name); + add_qe = GNUNET_NAMESTORE_records_store (ns, + &zone_pkey, + rec_name, + rd_count + 1, + rde, + &add_continuation, + &add_qe); + + return; +} + +static void +store_cb (void *cls, + const struct GNUNET_IDENTITY_Ego *ego) +{ + const struct GNUNET_CONFIGURATION_Handle *cfg = cls; + struct GNUNET_CRYPTO_EcdsaPublicKey pub; + + fprintf(stderr, "Start: store_cb\n"); + + ns = GNUNET_NAMESTORE_connect (cfg); + if (NULL == ns) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to namestore\n")); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // Key handling + fprintf(stderr, "Connected to ns\n"); + zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); + fprintf(stderr, "Got zone_pkey\n"); + // TODO rename to zone_pub? + GNUNET_CRYPTO_ecdsa_key_get_public (&zone_pkey, &pub); + + // Check relevant cmdline parameters + // name ⁼ issuer_attr + if (NULL == issuer_attr) + { + fprintf (stderr, "Missing option -attribute for operation 'create'.\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // TODO later, rename subject_key to subject + // value ⁼ subject_key + if (NULL == subject_key) + { + fprintf (stderr, "Missing option -subject for operation 'create'.'\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // String to value conversion for storage + if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, + subject_key, + &data, + &data_size)) + { + fprintf (stderr, "Value `%s' invalid for record type `%s'\n", + subject_key, + typestring); + GNUNET_SCHEDULER_shutdown (); + return; + } + fprintf (stderr, "Data size: `%lu'\n", data_size); + + // Take care of expiration + + if (NULL == expiration) + { + fprintf (stderr, "Missing option -e for operation 'create'\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (GNUNET_OK != parse_expiration (expiration, + &etime_is_rel, + &etime)) + { + fprintf (stderr, "Invalid time format `%s'\n", + expiration); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // Start lookup + add_qe = GNUNET_NAMESTORE_records_lookup (ns, + &zone_pkey, + issuer_attr, + &error_cb, + NULL, + &get_existing_record, + NULL); + return; +} + +static void +sign_cb (void *cls, + const struct GNUNET_IDENTITY_Ego *ego) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; + struct GNUNET_CREDENTIAL_Credential *crd; + struct GNUNET_TIME_Absolute etime_abs; + struct GNUNET_TIME_Relative etime_rel; + char *res; + + el = NULL; + + + // work on expiration time + if (NULL == expiration) + { + fprintf (stderr, "Please specify a TTL\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration, &etime_rel)) + { + etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel); + } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs)) + { + fprintf (stderr, "%s is not a valid ttl!\n", expiration); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // if contains a space - split it by the first space only - assume first token entry is subject_key + fprintf (stderr, "Start splitting\n"); + char *space; + int idx; + space = strchr(subject_key, ' '); + idx = (int)(space - subject_key); + + // TODO rename subject_key to subject + char *subject_pubkey_str = GNUNET_malloc(idx+1); + GNUNET_memcpy(subject_pubkey_str, subject_key, idx); + subject_pubkey_str[idx] = '\0'; + + fprintf(stderr, "idx: %d, str: %s\n", idx, subject_pubkey_str); + + // work on keys + privkey = GNUNET_IDENTITY_ego_get_private_key (ego); + + if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pubkey_str, + strlen (subject_pubkey_str), + &subject_pkey)) + { + fprintf (stderr, "Subject public key `%s' is not well-formed\n", subject_pubkey_str); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // Sign credential / TODO not credential but delegate (new method), not only pass subject_pkey but also subject_attr + // gnunet-credential --issue --ego=registrarb --subject=$ALICE_KEY --attribute=$REG_STUD_ATTR --ttl=5m -c test_credential_lookup.conf + // gnunet-credential --create --ego=epub --attribute="a" --subject="B b" --where="ss" -E 60m + // TODO: only signs subject_pkey at the moment, also requires subject_attr (or both in subject_key) + crd = GNUNET_CREDENTIAL_credential_issue (privkey, + &subject_pkey, + issuer_attr, + &etime_abs); + res = GNUNET_CREDENTIAL_credential_to_string (crd); + fprintf(stderr,"Dele: %s\n", res); + GNUNET_free (crd); + printf ("--ego=\"%s\" --attribute=\"%s\" --subject=\"%s\" --ttl=%s --extension=\"%s\"\n", ego_name, issuer_attr, subject_key, expiration, res); + + GNUNET_free_non_null (ego_name); + ego_name = NULL; + + GNUNET_SCHEDULER_shutdown (); +} /** * Main function that will be run. @@ -348,21 +811,102 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - cfg = c; + cfg = c; tt = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL); GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - if (GNUNET_YES == collect) - { + if (GNUNET_YES == create_is) { + fprintf(stderr, "Starting to create issuer side...\n"); + + if (NULL == ego_name) { + fprintf (stderr, "ego required\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + + type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE; + //TODO: Store normally (at issuer, for backward search) + // stuff from gnunet-namestore.c of namestore folder + fprintf (stderr, "Start: Store issuer side\n"); + el = GNUNET_IDENTITY_ego_lookup (cfg, + ego_name, + &store_cb, + (void *) cfg); + return; + } + + if (GNUNET_YES == create_ss) { + fprintf(stderr, "Starting to create subject side...\n"); + // check if "credential"/signed parameter filled + if (NULL == extension) { + fprintf (stderr, "'extension' required\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // parses all the passed parameters + parse_cmdl_param(extension); + + fprintf (stderr,"List of parsed attributes:\n"); + fprintf (stderr,"Ego: %s\n", ego_name); + fprintf (stderr,"Attribute: %s\n", issuer_attr); + fprintf (stderr,"Subject: %s\n", subject_key); + fprintf (stderr,"ttl: %s\n", expiration); + fprintf (stderr,"Extension: %s\n", extension); + + //TODO: subject key does not have to be returned, extension replaces it + //TODO: use own delegation type, implement string_to_value and value_to_string methods of plugin + //type = GNUNET_GNSRECORD_TYPE_DELEGATE; + type = GNUNET_GNSRECORD_TYPE_CREDENTIAL; + subject_key = extension; + fprintf (stderr, "Start: Store subject side\n"); + el = GNUNET_IDENTITY_ego_lookup (cfg, + ego_name, + &store_cb, + (void *) cfg); + + return; + } + + if (GNUNET_YES == sign_ss) { + fprintf(stderr, "Starting to sign subject side...\n"); + + if (NULL == ego_name) { + fprintf (stderr, "ego required\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + + if (NULL == subject_key) + { + fprintf (stderr, "Subject public key needed\n"); + GNUNET_SCHEDULER_shutdown (); + return; + + } + + //TODO: Sign like credential and return to store subject side + //TODO: Return everything as an input for the add + //TODO: Idee: Gleich add machen, statt return und neues add + fprintf (stderr, "Start: Sign, return and subject side store\n"); + el = GNUNET_IDENTITY_ego_lookup (cfg, + ego_name, + &sign_cb, + (void *) cfg); + return; + } + + if (GNUNET_YES == collect) { if (NULL == issuer_key) { fprintf (stderr, - _ ("Issuer public key not well-formed\n")); + _("Issuer public key not well-formed\n")); GNUNET_SCHEDULER_shutdown (); return; + } credential = GNUNET_CREDENTIAL_connect (cfg); @@ -370,22 +914,21 @@ run (void *cls, if (NULL == credential) { fprintf (stderr, - _ ("Failed to connect to CREDENTIAL\n")); + _("Failed to connect to CREDENTIAL\n")); GNUNET_SCHEDULER_shutdown (); return; } if (NULL == issuer_attr) { fprintf (stderr, - _ ("You must provide issuer the attribute\n")); + _("You must provide issuer the attribute\n")); GNUNET_SCHEDULER_shutdown (); return; } - if (NULL == ego_name) - { + if (NULL == ego_name) { fprintf (stderr, - _ ("ego required\n")); + _("ego required\n")); GNUNET_SCHEDULER_shutdown (); return; } @@ -394,14 +937,16 @@ run (void *cls, &identity_cb, (void *) cfg); return; - } + + } if (NULL == subject_key) { fprintf (stderr, - _ ("Subject public key needed\n")); + _("Subject public key needed\n")); GNUNET_SCHEDULER_shutdown (); return; + } if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key, @@ -409,19 +954,20 @@ run (void *cls, &subject_pkey)) { fprintf (stderr, - _ ("Subject public key `%s' is not well-formed\n"), + _("Subject public key `%s' is not well-formed\n"), subject_key); GNUNET_SCHEDULER_shutdown (); return; } - if (GNUNET_YES == verify) - { + + if (GNUNET_YES == verify) { if (NULL == issuer_key) { fprintf (stderr, - _ ("Issuer public key not well-formed\n")); + _("Issuer public key not well-formed\n")); GNUNET_SCHEDULER_shutdown (); return; + } if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key, @@ -429,7 +975,7 @@ run (void *cls, &issuer_pkey)) { fprintf (stderr, - _ ("Issuer public key `%s' is not well-formed\n"), + _("Issuer public key `%s' is not well-formed\n"), issuer_key); GNUNET_SCHEDULER_shutdown (); return; @@ -439,19 +985,19 @@ run (void *cls, if (NULL == credential) { fprintf (stderr, - _ ("Failed to connect to CREDENTIAL\n")); + _("Failed to connect to CREDENTIAL\n")); GNUNET_SCHEDULER_shutdown (); return; } - if ((NULL == issuer_attr) ||(NULL == subject_credential) ) + if (NULL == issuer_attr || NULL == subject_credential) { fprintf (stderr, - _ ("You must provide issuer and subject attributes\n")); + _("You must provide issuer and subject attributes\n")); GNUNET_SCHEDULER_shutdown (); return; } - // Subject credentials are comma separated + //Subject credentials are comma separated char *tmp = GNUNET_strdup (subject_credential); char *tok = strtok (tmp, ","); if (NULL == tok) @@ -464,60 +1010,58 @@ run (void *cls, } int count = 1; int i; - while (NULL != (tok = strtok (NULL, ","))) + while (NULL != (tok = strtok(NULL, ","))) count++; struct GNUNET_CREDENTIAL_Credential credentials[count]; struct GNUNET_CREDENTIAL_Credential *cred; GNUNET_free (tmp); tmp = GNUNET_strdup (subject_credential); tok = strtok (tmp, ","); - for (i = 0; i < count; i++) + for (i=0;iissuer_attribute); - tok = strtok (NULL, ","); + tok = strtok(NULL, ","); GNUNET_free (cred); } - verify_request = GNUNET_CREDENTIAL_verify (credential, - &issuer_pkey, - issuer_attr, // TODO argument - &subject_pkey, - count, - credentials, - &handle_verify_result, - NULL); - for (i = 0; i < count; i++) + verify_request = GNUNET_CREDENTIAL_verify(credential, + &issuer_pkey, + issuer_attr, //TODO argument + &subject_pkey, + count, + credentials, + &handle_verify_result, + NULL); + for (i=0;i. SPDX-License-Identifier: AGPL3.0-or-later - */ +*/ /** * @file credential/gnunet-service-credential.c * @brief GNUnet Credential Service (main service) @@ -225,6 +225,7 @@ struct DelegationSetQueueEntry */ struct VerifyRequestHandle { + /** * We keep these in a DLL. */ @@ -358,14 +359,12 @@ cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry) return; for (dq_entry = ds_entry->queue_entries_head; NULL != dq_entry; - dq_entry = ds_entry->queue_entries_head) - { + dq_entry = ds_entry->queue_entries_head) { GNUNET_CONTAINER_DLL_remove (ds_entry->queue_entries_head, ds_entry->queue_entries_tail, dq_entry); for (child = dq_entry->set_entries_head; NULL != child; - child = dq_entry->set_entries_head) - { + child = dq_entry->set_entries_head) { GNUNET_CONTAINER_DLL_remove (dq_entry->set_entries_head, dq_entry->set_entries_tail, child); @@ -378,13 +377,11 @@ cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry) GNUNET_free_non_null (ds_entry->issuer_attribute); GNUNET_free_non_null (ds_entry->unresolved_attribute_delegation); GNUNET_free_non_null (ds_entry->attr_trailer); - if (NULL != ds_entry->lookup_request) - { + if (NULL != ds_entry->lookup_request) { GNUNET_GNS_lookup_cancel (ds_entry->lookup_request); ds_entry->lookup_request = NULL; } - if (NULL != ds_entry->delegation_chain_entry) - { + if (NULL != ds_entry->delegation_chain_entry) { GNUNET_free_non_null (ds_entry->delegation_chain_entry->subject_attribute); GNUNET_free_non_null (ds_entry->delegation_chain_entry->issuer_attribute); GNUNET_free (ds_entry->delegation_chain_entry); @@ -396,18 +393,15 @@ static void cleanup_handle (struct VerifyRequestHandle *vrh) { struct CredentialRecordEntry *cr_entry; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n"); - if (NULL != vrh->lookup_request) - { + if (NULL != vrh->lookup_request) { GNUNET_GNS_lookup_cancel (vrh->lookup_request); vrh->lookup_request = NULL; } cleanup_delegation_set (vrh->root_set); GNUNET_free_non_null (vrh->issuer_attribute); for (cr_entry = vrh->cred_chain_head; NULL != vrh->cred_chain_head; - cr_entry = vrh->cred_chain_head) - { + cr_entry = vrh->cred_chain_head) { GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head, vrh->cred_chain_tail, cr_entry); @@ -424,25 +418,21 @@ shutdown_task (void *cls) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n"); - while (NULL != (vrh = vrh_head)) - { + while (NULL != (vrh = vrh_head)) { // CREDENTIAL_resolver_lookup_cancel (clh->lookup); GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh); cleanup_handle (vrh); } - if (NULL != gns) - { + if (NULL != gns) { GNUNET_GNS_disconnect (gns); gns = NULL; } - if (NULL != namestore) - { + if (NULL != namestore) { GNUNET_NAMESTORE_disconnect (namestore); namestore = NULL; } - if (NULL != statistics) - { + if (NULL != statistics) { GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); statistics = NULL; } @@ -463,16 +453,14 @@ send_lookup_response (struct VerifyRequestHandle *vrh) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n"); dce = vrh->delegation_chain_head; - for (uint32_t i = 0; i < vrh->delegation_chain_size; i++) - { + for (uint32_t i = 0; i < vrh->delegation_chain_size; i++) { dd[i].issuer_key = dce->issuer_key; dd[i].subject_key = dce->subject_key; dd[i].issuer_attribute = dce->issuer_attribute; dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1; dd[i].subject_attribute_len = 0; dd[i].subject_attribute = NULL; - if (NULL != dce->subject_attribute) - { + if (NULL != dce->subject_attribute) { dd[i].subject_attribute = dce->subject_attribute; dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1; } @@ -482,10 +470,8 @@ send_lookup_response (struct VerifyRequestHandle *vrh) /** * Remove all credentials not needed */ - for (cd = vrh->cred_chain_head; NULL != cd;) - { - if (cd->refcount > 0) - { + for (cd = vrh->cred_chain_head; NULL != cd;) { + if (cd->refcount > 0) { cd = cd->next; continue; } @@ -504,8 +490,7 @@ send_lookup_response (struct VerifyRequestHandle *vrh) * Append at the end of rmsg */ cd = vrh->cred_chain_head; - for (uint32_t i = 0; i < vrh->cred_chain_size; i++) - { + for (uint32_t i = 0; i < vrh->cred_chain_size; i++) { cred[i].issuer_key = cd->credential->issuer_key; cred[i].subject_key = cd->credential->subject_key; cred[i].issuer_attribute_len @@ -540,7 +525,7 @@ send_lookup_response (struct VerifyRequestHandle *vrh) vrh->cred_chain_size, cred, size, - (char *) &rmsg[1])); + (char *)&rmsg[1])); GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env); GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh); @@ -552,6 +537,13 @@ send_lookup_response (struct VerifyRequestHandle *vrh) GNUNET_NO); } +static void +test_resolution (void *cls, + uint32_t rd_count, + const struct GNUNET_GNSRECORD_Data *rd) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Yo, im Test und so\n"); +} static void backward_resolution (void *cls, @@ -568,16 +560,17 @@ backward_resolution (void *cls, char *expanded_attr; char *lookup_attribute; - current_set = cls; current_set->lookup_request = NULL; vrh = current_set->handle; vrh->pending_lookups--; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got %d attrs\n", rd_count); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# Issuer Att %s\n", current_set->issuer_attribute); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# Lookup Att %s\n", current_set->lookup_attribute); + // Each OR - for (uint32_t i = 0; i < rd_count; i++) - { + for (uint32_t i = 0; i < rd_count; i++) { if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type) continue; @@ -591,31 +584,29 @@ backward_resolution (void *cls, if (GNUNET_OK != GNUNET_CREDENTIAL_delegation_set_deserialize ( GNUNET_ntohll (sets->data_size), - (const char *) &sets[1], + (const char *)&sets[1], ntohl (sets->set_count), - set)) - { + set)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n"); continue; } dq_entry = GNUNET_new (struct DelegationQueueEntry); dq_entry->required_solutions = ntohl (sets->set_count); dq_entry->parent_set = current_set; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# New OR entry into queue\n"); + GNUNET_CONTAINER_DLL_insert (current_set->queue_entries_head, current_set->queue_entries_tail, dq_entry); // Each AND - for (uint32_t j = 0; j < ntohl (sets->set_count); j++) - { + for (uint32_t j = 0; j < ntohl (sets->set_count); j++) { ds_entry = GNUNET_new (struct DelegationSetQueueEntry); - if (NULL != current_set->attr_trailer) - { - if (0 == set[j].subject_attribute_len) - { + if (NULL != current_set->attr_trailer) { + if (0 == set[j].subject_attribute_len) { GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer); - } - else - { + + } else { GNUNET_asprintf (&expanded_attr, "%s.%s", set[j].subject_attribute, @@ -623,11 +614,8 @@ backward_resolution (void *cls, } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr); ds_entry->unresolved_attribute_delegation = expanded_attr; - } - else - { - if (0 != set[j].subject_attribute_len) - { + } else { + if (0 != set[j].subject_attribute_len) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not Expanding %s\n", set[j].subject_attribute); @@ -643,7 +631,7 @@ backward_resolution (void *cls, ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); GNUNET_memcpy (ds_entry->issuer_key, &set[j].subject_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); if (0 < set[j].subject_attribute_len) ds_entry->delegation_chain_entry->subject_attribute = GNUNET_strdup (set[j].subject_attribute); @@ -651,7 +639,12 @@ backward_resolution (void *cls, ds_entry->delegation_chain_entry->issuer_attribute = GNUNET_strdup (current_set->lookup_attribute); - ds_entry->parent_queue_entry = dq_entry; // current_delegation; + ds_entry->parent_queue_entry = dq_entry; // current_delegation; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# New AND DS entry into DQ queue\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# DS entry Issuer ATT %s\n", ds_entry->delegation_chain_entry->issuer_attribute); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# DS entry Subject ATT %s\n", ds_entry->delegation_chain_entry->subject_attribute); + GNUNET_CONTAINER_DLL_insert (dq_entry->set_entries_head, dq_entry->set_entries_tail, ds_entry); @@ -661,11 +654,12 @@ backward_resolution (void *cls, * Check if this delegation already matches one of our credentials */ for (cred_pointer = vrh->cred_chain_head; cred_pointer != NULL; - cred_pointer = cred_pointer->next) - { + cred_pointer = cred_pointer->next) { + // If key and attribute match credential continue and backtrack if (0 - != GNUNET_memcmp (&set->subject_key, - &cred_pointer->credential->issuer_key)) + != memcmp (&set->subject_key, + &cred_pointer->credential->issuer_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) continue; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking if %s matches %s\n", @@ -681,11 +675,10 @@ backward_resolution (void *cls, cred_pointer->refcount++; // Backtrack for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry; - tmp_set = tmp_set->parent_queue_entry->parent_set) - { + tmp_set = tmp_set->parent_queue_entry->parent_set) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# %s\n", tmp_set->unresolved_attribute_delegation); tmp_set->parent_queue_entry->required_solutions--; - if (NULL != tmp_set->delegation_chain_entry) - { + if (NULL != tmp_set->delegation_chain_entry) { vrh->delegation_chain_size++; GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head, vrh->delegation_chain_tail, @@ -695,8 +688,7 @@ backward_resolution (void *cls, break; } - if (NULL == tmp_set->parent_queue_entry) - { + if (NULL == tmp_set->parent_queue_entry) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "All solutions found\n"); // Found match send_lookup_response (vrh); @@ -713,9 +705,9 @@ backward_resolution (void *cls, issuer_attribute_name[strlen (ds_entry->unresolved_attribute_delegation) + 1]; strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# Issuer Att Name: %s\n", issuer_attribute_name); char *next_attr = strtok (issuer_attribute_name, "."); - if (NULL == next_attr) - { + if (NULL == next_attr) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse next attribute\n"); continue; @@ -723,12 +715,9 @@ backward_resolution (void *cls, GNUNET_asprintf (&lookup_attribute, "%s", next_attr); GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr); if (strlen (next_attr) - == strlen (ds_entry->unresolved_attribute_delegation)) - { + == strlen (ds_entry->unresolved_attribute_delegation)) { ds_entry->attr_trailer = NULL; - } - else - { + } else { next_attr += strlen (next_attr) + 1; ds_entry->attr_trailer = GNUNET_strdup (next_attr); } @@ -746,17 +735,24 @@ backward_resolution (void *cls, ds_entry->lookup_request = GNUNET_GNS_lookup (gns, lookup_attribute, - ds_entry->issuer_key, // issuer_key, + ds_entry->issuer_key, // issuer_key, GNUNET_GNSRECORD_TYPE_ATTRIBUTE, GNUNET_GNS_LO_DEFAULT, &backward_resolution, ds_entry); + /*GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Starting\n"); + GNUNET_GNS_lookup (gns, + GNUNET_GNS_EMPTY_LABEL_AT, + ds_entry->issuer_key, // subject_key, + GNUNET_GNSRECORD_TYPE_DELEGATE, + GNUNET_GNS_LO_DEFAULT, + &test_resolution, + ds_entry);*/ GNUNET_free (lookup_attribute); } } - if (0 == vrh->pending_lookups) - { + if (0 == vrh->pending_lookups) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n"); send_lookup_response (vrh); return; @@ -775,22 +771,20 @@ delegation_chain_resolution_start (void *cls) struct VerifyRequestHandle *vrh = cls; struct DelegationSetQueueEntry *ds_entry; struct CredentialRecordEntry *cr_entry; - vrh->lookup_request = NULL; - if (0 == vrh->cred_chain_size) - { + if (0 == vrh->cred_chain_size) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No credentials found\n"); send_lookup_response (vrh); return; } for (cr_entry = vrh->cred_chain_head; cr_entry != NULL; - cr_entry = cr_entry->next) - { + cr_entry = cr_entry->next) { if (0 - != GNUNET_memcmp (&cr_entry->credential->issuer_key, - &vrh->issuer_key)) + != memcmp (&cr_entry->credential->issuer_key, + &vrh->issuer_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) continue; if (0 != strcmp (cr_entry->credential->issuer_attribute, @@ -815,13 +809,15 @@ delegation_chain_resolution_start (void *cls) ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); GNUNET_memcpy (ds_entry->issuer_key, &vrh->issuer_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute); ds_entry->handle = vrh; ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute); vrh->root_set = ds_entry; vrh->pending_lookups = 1; // Start with backward resolution + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# Start Backward Resolution\n"); + ds_entry->lookup_request = GNUNET_GNS_lookup (gns, issuer_attribute_name, &vrh->issuer_key, // issuer_key, @@ -838,20 +834,17 @@ check_verify (void *cls, const struct VerifyMessage *v_msg) const char *attr; msg_size = ntohs (v_msg->header.size); - if (msg_size < sizeof(struct VerifyMessage)) - { + if (msg_size < sizeof (struct VerifyMessage)) { GNUNET_break (0); return GNUNET_SYSERR; } - if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) - { + if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) { GNUNET_break (0); return GNUNET_SYSERR; } - attr = (const char *) &v_msg[1]; + attr = (const char *)&v_msg[1]; - if (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) - { + if (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) { GNUNET_break (0); return GNUNET_SYSERR; } @@ -873,7 +866,7 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg) const char *utf_in; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n"); - utf_in = (const char *) &v_msg[1]; + utf_in = (const char *)&v_msg[1]; GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len)); issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0'; @@ -885,8 +878,7 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg) vrh->subject_key = v_msg->subject_key; vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); GNUNET_SERVICE_client_continue (vrh->client); - if (0 == strlen (issuer_attribute)) - { + if (0 == strlen (issuer_attribute)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n"); send_lookup_response (vrh); return; @@ -897,40 +889,37 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg) */ credentials_count = ntohl (v_msg->c_count); credential_data_size = ntohs (v_msg->header.size) - - sizeof(struct VerifyMessage) + - sizeof (struct VerifyMessage) - ntohs (v_msg->issuer_attribute_len) - 1; struct GNUNET_CREDENTIAL_Credential credentials[credentials_count]; memset (credentials, 0, - sizeof(struct GNUNET_CREDENTIAL_Credential) * credentials_count); - credential_data = (char *) &v_msg[1] + ntohs (v_msg->issuer_attribute_len) - + 1; + sizeof (struct GNUNET_CREDENTIAL_Credential) * credentials_count); + credential_data = (char *)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1; if (GNUNET_OK != GNUNET_CREDENTIAL_credentials_deserialize (credential_data_size, credential_data, credentials_count, - credentials)) - { + credentials)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize credentials!\n"); send_lookup_response (vrh); return; } - for (uint32_t i = 0; i < credentials_count; i++) - { + for (uint32_t i = 0; i < credentials_count; i++) { cr_entry = GNUNET_new (struct CredentialRecordEntry); cr_entry->credential - = GNUNET_malloc (sizeof(struct GNUNET_CREDENTIAL_Credential) + = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + credentials[i].issuer_attribute_len + 1); GNUNET_memcpy (cr_entry->credential, &credentials[i], - sizeof(struct GNUNET_CREDENTIAL_Credential)); + sizeof (struct GNUNET_CREDENTIAL_Credential)); GNUNET_memcpy (&cr_entry->credential[1], credentials[i].issuer_attribute, credentials[i].issuer_attribute_len); cr_entry->credential->issuer_attribute_len = credentials[i].issuer_attribute_len; - cr_entry->credential->issuer_attribute = (char *) &cr_entry->credential[1]; + cr_entry->credential->issuer_attribute = (char *)&cr_entry->credential[1]; GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head, vrh->cred_chain_tail, cr_entry); @@ -944,7 +933,6 @@ static void handle_cred_collection_error_cb (void *cls) { struct VerifyRequestHandle *vrh = cls; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got disconnected from namestore database.\n"); vrh->cred_collection_iter = NULL; @@ -955,7 +943,6 @@ static void collect_next (void *cls) { struct VerifyRequestHandle *vrh = cls; - vrh->collect_next_task = NULL; GNUNET_assert (NULL != vrh->cred_collection_iter); GNUNET_NAMESTORE_zone_iterator_next (vrh->cred_collection_iter, 1); @@ -975,15 +962,13 @@ handle_cred_collection_cb (void *cls, int cred_record_count; cred_record_count = 0; - for (uint32_t i = 0; i < rd_count; i++) - { + for (uint32_t i = 0; i < rd_count; i++) { if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type) continue; cred_record_count++; crd = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data, rd[i].data_size); - if (NULL == crd) - { + if (NULL == crd) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid credential found\n"); continue; } @@ -1001,7 +986,6 @@ static void handle_cred_collection_finished_cb (void *cls) { struct VerifyRequestHandle *vrh = cls; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting credentials.\n"); vrh->cred_collection_iter = NULL; delegation_chain_resolution_start (vrh); @@ -1019,7 +1003,7 @@ handle_collect (void *cls, const struct CollectMessage *c_msg) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n"); - utf_in = (const char *) &c_msg[1]; + utf_in = (const char *)&c_msg[1]; GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len)); @@ -1032,8 +1016,7 @@ handle_collect (void *cls, const struct CollectMessage *c_msg) GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key, &vrh->subject_key); vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); - if (0 == strlen (issuer_attribute)) - { + if (0 == strlen (issuer_attribute)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n"); send_lookup_response (vrh); return; @@ -1062,21 +1045,18 @@ check_collect (void *cls, const struct CollectMessage *c_msg) const char *attr; msg_size = ntohs (c_msg->header.size); - if (msg_size < sizeof(struct CollectMessage)) - { + if (msg_size < sizeof (struct CollectMessage)) { GNUNET_break (0); return GNUNET_SYSERR; } - if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) - { + if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) { GNUNET_break (0); return GNUNET_SYSERR; } - attr = (const char *) &c_msg[1]; + attr = (const char *)&c_msg[1]; - if (('\0' != attr[msg_size - sizeof(struct CollectMessage) - 1]) - || (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH)) - { + if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) + || (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH)) { GNUNET_break (0); return GNUNET_SYSERR; } @@ -1112,14 +1092,13 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *handle) { + gns = GNUNET_GNS_connect (c); - if (NULL == gns) - { + if (NULL == gns) { fprintf (stderr, _ ("Failed to connect to GNS\n")); } namestore = GNUNET_NAMESTORE_connect (c); - if (NULL == namestore) - { + if (NULL == namestore) { fprintf (stderr, _ ("Failed to connect to namestore\n")); } diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c index 269e558c2..a4c3a94e8 100644 --- a/src/credential/plugin_gnsrecord_credential.c +++ b/src/credential/plugin_gnsrecord_credential.c @@ -16,7 +16,7 @@ along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later - */ +*/ /** * @file credential/plugin_gnsrecord_credential.c @@ -46,79 +46,72 @@ static char * credential_value_to_string (void *cls, uint32_t type, const void *data, size_t data_size) { + const char *cdata; - switch (type) - { + switch (type) { case GNUNET_GNSRECORD_TYPE_ATTRIBUTE: { - struct GNUNET_CREDENTIAL_DelegationRecord sets; - char *attr_str; - char *subject_pkey; - char *tmp_str; - int i; - if (data_size < sizeof(struct GNUNET_CREDENTIAL_DelegationRecord)) - return NULL; /* malformed */ - GNUNET_memcpy (&sets, data, sizeof(sets)); - cdata = data; - struct GNUNET_CREDENTIAL_DelegationSet set[ntohl (sets.set_count)]; - if (GNUNET_OK != GNUNET_CREDENTIAL_delegation_set_deserialize ( - GNUNET_ntohll (sets.data_size), &cdata[sizeof(sets)], - ntohl (sets.set_count), set)) - return NULL; - - for (i = 0; i < ntohl (sets.set_count); i++) - { - subject_pkey = + struct GNUNET_CREDENTIAL_DelegationRecord sets; + char *attr_str; + char *subject_pkey; + char *tmp_str; + int i; + if (data_size < sizeof (struct GNUNET_CREDENTIAL_DelegationRecord)) + return NULL; /* malformed */ + + GNUNET_memcpy (&sets, data, sizeof (sets)); + cdata = data; + + struct GNUNET_CREDENTIAL_DelegationSet set[ntohl (sets.set_count)]; + if (GNUNET_OK != GNUNET_CREDENTIAL_delegation_set_deserialize ( + GNUNET_ntohll (sets.data_size), &cdata[sizeof (sets)], + ntohl (sets.set_count), set)) + return NULL; + + for (i = 0; i < ntohl (sets.set_count); i++) { + subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&set[i].subject_key); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%d len attr\n", - set[i].subject_attribute_len); - if (0 == set[i].subject_attribute_len) - { - if (0 == i) - { - GNUNET_asprintf (&attr_str, "%s", subject_pkey); - } - else - { - GNUNET_asprintf (&tmp_str, "%s,%s", attr_str, subject_pkey); - GNUNET_free (attr_str); - attr_str = tmp_str; - } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%d len attr\n", + set[i].subject_attribute_len); + if (0 == set[i].subject_attribute_len) { + if (0 == i) { + GNUNET_asprintf (&attr_str, "%s", subject_pkey); + } else { + GNUNET_asprintf (&tmp_str, "%s,%s", attr_str, subject_pkey); + GNUNET_free (attr_str); + attr_str = tmp_str; } - else - { - if (0 == i) - { - GNUNET_asprintf (&attr_str, "%s %s", subject_pkey, - set[i].subject_attribute); - } - else - { - GNUNET_asprintf (&tmp_str, "%s,%s %s", attr_str, subject_pkey, - set[i].subject_attribute); - GNUNET_free (attr_str); - attr_str = tmp_str; - } + } else { + if (0 == i) { + GNUNET_asprintf (&attr_str, "%s %s", subject_pkey, + set[i].subject_attribute); + } else { + GNUNET_asprintf (&tmp_str, "%s,%s %s", attr_str, subject_pkey, + set[i].subject_attribute); + GNUNET_free (attr_str); + attr_str = tmp_str; } - GNUNET_free (subject_pkey); } - return attr_str; + GNUNET_free (subject_pkey); } - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "############### attr str: %s \n", attr_str); + //DEBUG ############### attr str: BKX50FK9QYNTFGPR6647CDASM63G21NEJC02QP58NHN7B7M8TKT0 student + return attr_str; + } case GNUNET_GNSRECORD_TYPE_CREDENTIAL: { - struct GNUNET_CREDENTIAL_Credential *cred; - char *cred_str; - - cred = GNUNET_CREDENTIAL_credential_deserialize (data, data_size); - cred_str = GNUNET_CREDENTIAL_credential_to_string (cred); - GNUNET_free (cred); - return cred_str; - } + struct GNUNET_CREDENTIAL_Credential *cred; + char *cred_str; - case GNUNET_GNSRECORD_TYPE_POLICY: { - return GNUNET_strndup (data, data_size); - } + cred = GNUNET_CREDENTIAL_credential_deserialize (data, data_size); + cred_str = GNUNET_CREDENTIAL_credential_to_string (cred); + GNUNET_free (cred); + return cred_str; + } + case GNUNET_GNSRECORD_TYPE_DELEGATE: { + printf("####################################vts\n"); + return GNUNET_strndup (data, data_size); + } default: return NULL; } @@ -142,107 +135,203 @@ credential_string_to_value (void *cls, uint32_t type, const char *s, { if (NULL == s) return GNUNET_SYSERR; - switch (type) - { + switch (type) { case GNUNET_GNSRECORD_TYPE_ATTRIBUTE: { - struct GNUNET_CREDENTIAL_DelegationRecord *sets; - char attr_str[253 + 1]; - char subject_pkey[52 + 1]; - char *token; - char *tmp_str; - int matches = 0; - int entries; - size_t tmp_data_size; - int i; - - tmp_str = GNUNET_strdup (s); - token = strtok (tmp_str, ","); - entries = 0; - tmp_data_size = 0; - *data_size = sizeof(struct GNUNET_CREDENTIAL_DelegationRecord); - while (NULL != token) - { - matches = sscanf (token, "%s %s", subject_pkey, attr_str); - if (0 == matches) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Unable to parse ATTR record string `%s'\n"), s); - GNUNET_free (tmp_str); - return GNUNET_SYSERR; - } - if (1 == matches) - { - tmp_data_size += sizeof(struct GNUNET_CREDENTIAL_DelegationRecordSet); - } - else if (2 == matches) - { - tmp_data_size += sizeof(struct GNUNET_CREDENTIAL_DelegationRecordSet) - + strlen (attr_str) + 1; - } - entries++; - token = strtok (NULL, ","); - } - GNUNET_free (tmp_str); - tmp_str = GNUNET_strdup (s); - token = strtok (tmp_str, ","); - if (NULL == token) - { + printf ("Start: string_to_value attribute\n"); + + struct GNUNET_CREDENTIAL_DelegationRecord *sets; + char attr_str[253 + 1]; + char subject_pkey[52 + 1]; + char *token; + char *tmp_str; + int matches = 0; + int entries; + size_t tmp_data_size; + int i; + + tmp_str = GNUNET_strdup (s); + token = strtok (tmp_str, ","); + entries = 0; + tmp_data_size = 0; + *data_size = sizeof (struct GNUNET_CREDENTIAL_DelegationRecord); + while (NULL != token) { + // also fills the variables subject_pley and attr_str if "regex"-like match + matches = SSCANF (token, "%s %s", subject_pkey, attr_str); + + if (0 == matches) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _ ("Unable to parse ATTR record string `%s'\n"), s); GNUNET_free (tmp_str); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed string %s\n", s); return GNUNET_SYSERR; } - struct GNUNET_CREDENTIAL_DelegationSet set[entries]; - memset (set, 0, sizeof(struct GNUNET_CREDENTIAL_DelegationSet) * entries); - for (i = 0; i < entries; i++) - { - matches = sscanf (token, "%s %s", subject_pkey, attr_str); - GNUNET_CRYPTO_ecdsa_public_key_from_string ( - subject_pkey, strlen (subject_pkey), &set[i].subject_key); - if (2 == matches) - { - set[i].subject_attribute_len = strlen (attr_str) + 1; - set[i].subject_attribute = GNUNET_strdup (attr_str); - } - token = strtok (NULL, ","); + + entries++; + token = strtok (NULL, ","); + } + GNUNET_free (tmp_str); + + tmp_str = GNUNET_strdup (s); + token = strtok (tmp_str, ","); + if (NULL == token) { + GNUNET_free (tmp_str); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed string %s\n", s); + return GNUNET_SYSERR; + } + + struct GNUNET_CREDENTIAL_DelegationSet set[entries]; + // sets memory to be 0, starting at *set for the size of struct * entries + memset (set, 0, sizeof (struct GNUNET_CREDENTIAL_DelegationSet) * entries); + for (i = 0; i < entries; i++) { + matches = SSCANF (token, "%s %s", subject_pkey, attr_str); + + // sets the public key for the set entry + GNUNET_CRYPTO_ecdsa_public_key_from_string ( + subject_pkey, strlen (subject_pkey), &set[i].subject_key); + + // If not just key, also set subject attribute (Not A.a <- B but A.a <- B.b) + if (2 == matches) { + set[i].subject_attribute_len = strlen (attr_str) + 1; + set[i].subject_attribute = GNUNET_strdup (attr_str); } - tmp_data_size = GNUNET_CREDENTIAL_delegation_set_get_size (entries, set); + // If more entries, then token string can take the next entry (separated by ',') by calling strtok again + token = strtok (NULL, ","); + } + tmp_data_size = GNUNET_CREDENTIAL_delegation_set_get_size (entries, set); + + if (-1 == tmp_data_size) { + GNUNET_free (tmp_str); + return GNUNET_SYSERR; + } + *data_size += tmp_data_size; + *data = sets = GNUNET_malloc (*data_size); + GNUNET_CREDENTIAL_delegation_set_serialize (entries, set, tmp_data_size, + (char *)&sets[1]); + for (i = 0; i < entries; i++) { + if (0 != set[i].subject_attribute_len) + GNUNET_free ((char *)set[i].subject_attribute); + } + sets->set_count = htonl (entries); + sets->data_size = GNUNET_htonll (tmp_data_size); + + GNUNET_free (tmp_str); + return GNUNET_OK; + } + case GNUNET_GNSRECORD_TYPE_CREDENTIAL: { + printf ("Start: string_to_value credential\n"); - if (-1 == tmp_data_size) - { + struct GNUNET_CREDENTIAL_Credential *cred; + cred = GNUNET_CREDENTIAL_credential_from_string (s); + + *data_size = GNUNET_CREDENTIAL_credential_serialize (cred, (char **)data); + return GNUNET_OK; + } + case GNUNET_GNSRECORD_TYPE_DELEGATE: { + printf ("Start: string_to_value delegate\n"); + + char* tmp_str; + char* token; + int matches = 0; + int entries = 0; + size_t tmp_data_size = 0; + char issuer_attr_str[253 + 1], subject_attr_str[253 + 1]; + char issuer_pkey[52 + 1], subject_pkey[52 + 1]; + int i; + + // Split AND + tmp_str = GNUNET_strdup (s); + // Split string by ',' and first entry stored in token + token = strtok (tmp_str, ","); + // TODO: Use of this except for entry counting and format checking (why tmp_data size in the function above?) + while(NULL != token) { + printf("DEL############### tokenX %s\n", token); + + // TODO: only for type A.a <- B.b, missing other types, especially with multiple roles on the right side + // Alles splitten mit "%s %s <- %s %s ..." oder lieber "%s %s <- %s" und das dem lookup überlassen? Dann aber feld größe unknown + + // Match with string and fill variables + matches = SSCANF (token, "%s %s <- %s %s", issuer_pkey, issuer_attr_str, subject_pkey, subject_attr_str); + printf("DEL############### issuerpkey %s, issueratt %s, subjectpkey %s, subjectattr %s\n", + issuer_pkey, issuer_attr_str, subject_pkey, subject_attr_str); + + // Doesn't match string, DEL record string wrong formatted, throw error + if (2 >= matches) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _ ("Unable to parse DEL record string `%s'\n"), s); GNUNET_free (tmp_str); return GNUNET_SYSERR; } - *data_size += tmp_data_size; - *data = sets = GNUNET_malloc (*data_size); - GNUNET_CREDENTIAL_delegation_set_serialize (entries, set, tmp_data_size, - (char *) &sets[1]); - for (i = 0; i < entries; i++) - { - if (0 != set[i].subject_attribute_len) - GNUNET_free ((char *) set[i].subject_attribute); + + printf("DEL############### matches %d\n", matches); + if (3 == matches) { + // Type A.a <- B + printf("DEL############### A.a <-B found\n"); + } + if (4 == matches) { + printf("DEL############### A.a <- B.b found\n"); } - sets->set_count = htonl (entries); - sets->data_size = GNUNET_htonll (tmp_data_size); + // Get next entry of tmp_str (pointer still saved), store entry in token, NULL if no more entries + token = strtok(NULL, ","); + entries++; + } + // TODO fill tmp_data_size (but what's that) + + tmp_str = GNUNET_strdup (s); + token = strtok (tmp_str, ","); + if (NULL == token) { GNUNET_free (tmp_str); - return GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed string %s\n", s); + return GNUNET_SYSERR; } - case GNUNET_GNSRECORD_TYPE_CREDENTIAL: { - struct GNUNET_CREDENTIAL_Credential *cred; - cred = GNUNET_CREDENTIAL_credential_from_string (s); + // TODO own GNUNET_CREDENTIAL_Delegation struct (when I know the format) + struct GNUNET_CREDENTIAL_Delegation set[entries]; + // sets memory to be 0, starting at *set for the size of struct * entries + memset (set, 0, sizeof (struct GNUNET_CREDENTIAL_Delegation) * entries); + + for (i = 0; i < entries; i++) { + matches = SSCANF (token, "%s %s <- %s %s", issuer_pkey, issuer_attr_str, subject_pkey, subject_attr_str); + + // Set public keys of issuer and subject + GNUNET_CRYPTO_ecdsa_public_key_from_string ( + issuer_pkey, strlen (issuer_pkey), &set[i].issuer_key); + GNUNET_CRYPTO_ecdsa_public_key_from_string ( + subject_pkey, strlen (subject_pkey), &set[i].subject_key); + + // Set issuer attribute, always present + set[i].issuer_attribute_len = strlen (issuer_attr_str) + 1; + set[i].issuer_attribute = GNUNET_strdup (issuer_attr_str); + + if (4 == matches) { + // A.a <- B.b + set[i].subject_attribute_len = strlen (subject_attr_str) + 1; + set[i].subject_attribute = GNUNET_strdup (subject_attr_str); + } - *data_size = GNUNET_CREDENTIAL_credential_serialize (cred, - (char **) data); - return GNUNET_OK; + // If more entries, then token string can take the next entry (separated by ',') by calling strtok again + token = strtok (NULL, ","); } + //TODO: own method + //tmp_data_size = GNUNET_CREDENTIAL_delegation_set_get_size (entries, set); - case GNUNET_GNSRECORD_TYPE_POLICY: { - *data_size = strlen (s); - *data = GNUNET_strdup (s); - return GNUNET_OK; + if (-1 == tmp_data_size) { + GNUNET_free (tmp_str); + return GNUNET_SYSERR; } + //TODO: serialize + + + + + + + + + *data_size = strlen (s); + *data = GNUNET_strdup (s); + return GNUNET_OK; + } default: return GNUNET_SYSERR; } @@ -257,10 +346,10 @@ static struct { const char *name; uint32_t number; -} name_map[] = { { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL }, - { "ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE }, - { "POLICY", GNUNET_GNSRECORD_TYPE_POLICY }, - { NULL, UINT32_MAX } }; +} name_map[] = {{"CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL}, + {"ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE}, + {"DEL", GNUNET_GNSRECORD_TYPE_DELEGATE}, + {NULL, UINT32_MAX}}; /** diff --git a/src/credential/test_credential_own.sh b/src/credential/test_credential_own.sh new file mode 100755 index 000000000..a5f567511 --- /dev/null +++ b/src/credential/test_credential_own.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT + +LOCATION=$(which gnunet-config) +if [ -z $LOCATION ] +then + LOCATION="gnunet-config" +fi +$LOCATION --version 1> /dev/null +if test $? != 0 +then + echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" + exit 77 +fi + +rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` + +# (1) EPub.discount <- EOrg.preferred +# (2) EOrg.preferred <- StateU.student +# (3) StateU.student <- RegistrarB.student +# (4) RegistrarB.student <- Alice + + +which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30" +gnunet-arm -s -c test_credential_lookup.conf +gnunet-identity -C epub -c test_credential_lookup.conf +gnunet-identity -C eorg -c test_credential_lookup.conf +gnunet-identity -C stateu -c test_credential_lookup.conf +gnunet-identity -C registrarb -c test_credential_lookup.conf +gnunet-identity -C alice -c test_credential_lookup.conf + +EPUB_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep epub | awk '{print $3}') +EORG_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep eorg | awk '{print $3}') +STATEU_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep stateu | awk '{print $3}') +REGISTRARB_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep registrarb | awk '{print $3}') +ALICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep alice | awk '{print $3}') + + +DISC_ATTR="discount" +PREF_ATTR="preferred" +STATE_STUD_ATTR="student" +REG_STUD_ATTR="student" +END_ATTR="end" + +TEST_CREDENTIAL="mygnunetcreds" +# Test for forward search (0) StateU.student -> EOrg.end +# gnunet-namestore -p -z eorg -a -n "@" -t DEL -V "$STATEU_KEY $STATE_STUD_ATTR <- $EORG_KEY $END_ATTR" -e 60m -c test_credential_lookup.conf +# gnunet-namestore -D -z eorg + +# Alternative Format that is being implemented at the moment: +# Issuerside: +# gnunet-credential --create --ego=A --attribute="a" --subject="B.b" --where="is" + gnunet-credential --createIssuerSide --ego=epub --attribute="aasds" --subject="$EORG_KEY basd" --ttl=60m + SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="asd" --subject="$EORG_KEY basd" --ttl=60m` + echo $SIGNED + gnunet-credential --createSubjectSide --extension "$SIGNED" +# Subjectside: +# X = gnunet-credential --create -e E -a "a" -s "B.b" -w ss +# gnunet-credential --add -e E -x X + +# (1) EPub assigns the attribute "discount" to all entities that have been assigned "preferred" by EOrg +gnunet-namestore -p -z epub -a -n $DISC_ATTR -t ATTR -V "$EORG_KEY $PREF_ATTR" -e 5m -c test_credential_lookup.conf +gnunet-namestore -D -z epub + +# (2) EOrg assigns the attribute "preferred" to all entities that have been assigned "student" by StateU +gnunet-namestore -p -z eorg -a -n $PREF_ATTR -t ATTR -V "$STATEU_KEY $STATE_STUD_ATTR" -e 5m -c test_credential_lookup.conf + +# (3) StateU assigns the attribute "student" to all entities that have been asssigned "student" by RegistrarB +gnunet-namestore -p -z stateu -a -n $STATE_STUD_ATTR -t ATTR -V "$REGISTRARB_KEY $REG_STUD_ATTR" -e 5m -c test_credential_lookup.conf + +# (4) RegistrarB issues Alice the credential "student" +CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=registrarb --subject=$ALICE_KEY --attribute=$REG_STUD_ATTR --ttl=5m -c test_credential_lookup.conf` + +# Alice stores the credential under "mygnunetcreds" +gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf + +# Starting to resolve +echo "+++++Starting Collect" + +CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$EPUB_KEY --attribute=$DISC_ATTR --ego=alice -c test_credential_lookup.conf | paste -d, -s` +echo $CREDS +echo gnunet-credential --verify --issuer=$EPUB_KEY --attribute=$DISC_ATTR --subject=$ALICE_KEY --credential=\'$CREDS\' -c test_credential_lookup.conf + +RES_CRED=`gnunet-credential --verify --issuer=$EPUB_KEY --attribute=$DISC_ATTR --subject=$ALICE_KEY --credential="$CREDS" -c test_credential_lookup.conf` + + +# Cleanup properly +gnunet-namestore -z alice -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf +gnunet-namestore -z epub -d -n $DISC_ATTR -t ATTR -c test_credential_lookup.conf +gnunet-namestore -z eorg -d -n $PREF_ATTR -t ATTR -c test_credential_lookup.conf +gnunet-namestore -z stateu -d -n $STATE_STUD_ATTR -t ATTR -c test_credential_lookup.conf +gnunet-arm -e -c test_credential_lookup.conf + +if [ "$RES_CRED" != "Failed." ] +then + # TODO: replace echo -e bashism + echo -e "${RES_CRED}" + exit 0 +else + echo "FAIL: Failed to verify credential $RES_CRED." + exit 1 +fi + diff --git a/src/credential/test_credential_verify_and.sh b/src/credential/test_credential_verify_and.sh index fa0ab34e1..aaabcd753 100755 --- a/src/credential/test_credential_verify_and.sh +++ b/src/credential/test_credential_verify_and.sh @@ -17,8 +17,8 @@ rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` # (1) Service.user -> GNU.project.member # (2) GNU.project -> GNUnet -# (3) GNUnet.member -> GNUnet.developer and GNUnet.user -# (4) GNUnet.developer -> Alice +# (3) GNUnet.member -> GNUnet.developer and (4)GNUnet.user +# (5) GNUnet.developer -> Alice which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 30" @@ -73,10 +73,9 @@ gnunet-arm -e -c test_credential_lookup.conf if [ "$RES_CRED" != "Failed." ] then - # TODO: echo -e bashism echo -e "${RES_CRED}" exit 0 else echo "FAIL: Failed to verify credential $RES_CRED." exit 1 -fi +fi \ No newline at end of file diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index f5b2f0dd1..ea91f9eb9 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h @@ -114,7 +114,7 @@ extern "C" { /** * Record type for policies */ -#define GNUNET_GNSRECORD_TYPE_POLICY 65548 +#define GNUNET_GNSRECORD_TYPE_DELEGATE 65548 /** * Record type for reverse lookups -- 2.25.1