From 671f7c5fb4dcb596a2b6d065c2cd5f39be3fb431 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Wed, 7 Dec 2016 14:56:57 +0100 Subject: [PATCH] - add delegation resolution --- src/credential/gnunet-service-credential.c | 102 +++++++++++++++---- src/credential/plugin_gnsrecord_credential.c | 53 ++++++++-- src/credential/test_credential_verify.sh | 11 +- 3 files changed, 131 insertions(+), 35 deletions(-) diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c index 662c26a5e..bf85b1583 100644 --- a/src/credential/gnunet-service-credential.c +++ b/src/credential/gnunet-service-credential.c @@ -100,6 +100,11 @@ struct AttributeQueueEntry * Parent attribute delegation */ struct AttributeQueueEntry *parent; + + /** + * Trailing attribute context + */ + char *attr_trailer; }; @@ -364,40 +369,74 @@ start_backward_resolution (void* cls, const struct GNUNET_CREDENTIAL_AttributeRecordData *attr; struct CredentialRecordEntry *cred_pointer; struct AttributeQueueEntry *attr_entry; + char *expanded_attr; + char *check_attr; int i; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got %d attrs\n", rd_count); for (i=0; i < rd_count; i++) { if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type) continue; + attr = rd[i].data; + attr_entry = GNUNET_new (struct AttributeQueueEntry); + attr_entry->data_size = rd[i].data_size; + if (NULL != vrh->current_attribute && + NULL != vrh->current_attribute->attr_trailer) + { + if (rd[i].data_size == sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData)) + { + GNUNET_asprintf (&expanded_attr, + "%s", + vrh->current_attribute->attr_trailer); + + } else { + GNUNET_asprintf (&expanded_attr, + "%s.%s", + (char*)&attr[1], + vrh->current_attribute->attr_trailer); + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Expanded to %s\n", expanded_attr); + attr_entry->data_size += strlen (vrh->current_attribute->attr_trailer) + 1; + } else { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Not Expanding %s\n", (char*)&attr[1]); + } + attr_entry->data = GNUNET_malloc (attr_entry->data_size); + memcpy (attr_entry->data, + rd[i].data, + rd[i].data_size); + if (NULL != vrh->current_attribute && NULL != vrh->current_attribute->attr_trailer) + { + memcpy ((char*)&attr_entry->data[1], + expanded_attr, + strlen (expanded_attr)); + } + check_attr = (char*)&attr_entry->data[1]; + check_attr[attr_entry->data_size] = '\0'; + attr_entry->parent = vrh->current_attribute; + + GNUNET_CONTAINER_DLL_insert (vrh->attr_queue_head, + vrh->attr_queue_tail, + attr_entry); for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL; cred_pointer = cred_pointer->next){ cred = cred_pointer->data; - - attr_entry = GNUNET_new (struct AttributeQueueEntry); - - attr_entry->data = GNUNET_malloc (rd[i].data_size); - memcpy (attr_entry->data, - rd[i].data, - rd[i].data_size); - attr_entry->data_size = rd[i].data_size; - - attr_entry->parent = vrh->current_attribute; - - GNUNET_CONTAINER_DLL_insert (vrh->attr_queue_head, - vrh->attr_queue_tail, - attr_entry); - if(0 != memcmp (&attr->subject_key, &cred_pointer->data->issuer_key, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) continue; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Checking if %s matches %s\n", + (char*)&attr_entry->data[1], (char*)&cred[1]); - if (0 != strcmp ((char*)&attr[1], (char*)&cred[1])) + if (0 != strcmp ((char*)&attr_entry->data[1], (char*)&cred[1])) continue; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n"); vrh->credential = GNUNET_malloc (rd[i].data_size); @@ -417,9 +456,9 @@ start_backward_resolution (void* cls, //Start from next to head vrh->current_attribute = vrh->attr_queue_head; - if(vrh->current_attribute != NULL) + if(NULL == vrh->current_attribute) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n"); send_lookup_response (vrh); return; @@ -432,14 +471,32 @@ start_backward_resolution (void* cls, //Start with backward resolution + char issuer_attribute_name[strlen ((char*)&vrh->current_attribute->data[1])]; + char *lookup_attr; + strcpy (issuer_attribute_name, + (char*)&vrh->current_attribute->data[1]); + char *next_attr = strtok (issuer_attribute_name, "."); + GNUNET_asprintf (&lookup_attr, + "%s.gnu", + next_attr); + next_attr += strlen (next_attr) + 1; + vrh->current_attribute->attr_trailer = GNUNET_strdup (next_attr); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Looking up %s\n", lookup_attr); + if (NULL != vrh->current_attribute->attr_trailer) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s still to go...\n", vrh->current_attribute->attr_trailer); + vrh->lookup_request = GNUNET_GNS_lookup (gns, - (char*)&vrh->current_attribute->data[1], + lookup_attr, &vrh->current_attribute->data->subject_key, //issuer_key, GNUNET_GNSRECORD_TYPE_ATTRIBUTE, GNUNET_GNS_LO_DEFAULT, NULL, //shorten_key, always NULL &start_backward_resolution, vrh); + GNUNET_free (lookup_attr); } @@ -513,8 +570,6 @@ handle_credential_query (void* cls, } - GNUNET_break (0); //TODO remove when implemented - /** * Check for attributes from the issuer and follow the chain * till you get the required subject's attributes @@ -524,6 +579,9 @@ handle_credential_query (void* cls, vrh->issuer_attribute); strcpy (issuer_attribute_name + strlen (vrh->issuer_attribute), ".gnu"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Looking up %s\n", issuer_attribute_name); + //Start with backward resolution GNUNET_GNS_lookup (gns, issuer_attribute_name, diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c index 90ac393d0..ece4be1e3 100644 --- a/src/credential/plugin_gnsrecord_credential.c +++ b/src/credential/plugin_gnsrecord_credential.c @@ -65,10 +65,15 @@ credential_value_to_string (void *cls, sizeof (attr)); cdata = data; subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&attr.subject_key); - GNUNET_asprintf (&attr_str, - "%s.%s", - subject_pkey, - &cdata[sizeof (attr)]); + if (data_size == sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData)) + { + return subject_pkey; + } else { + GNUNET_asprintf (&attr_str, + "%s %s", + subject_pkey, + &cdata[sizeof (attr)]); + } GNUNET_free (subject_pkey); return attr_str; } @@ -82,7 +87,7 @@ credential_value_to_string (void *cls, char *signature; const char *expiration; - + if (data_size < sizeof (struct GNUNET_CREDENTIAL_CredentialRecordData)) return NULL; /* malformed */ memcpy (&cred, @@ -136,6 +141,41 @@ credential_string_to_value (void *cls, return GNUNET_SYSERR; switch (type) { + case GNUNET_GNSRECORD_TYPE_ATTRIBUTE: + { + struct GNUNET_CREDENTIAL_AttributeRecordData *attr; + char attr_str[253 + 1]; + char subject_pkey[52 + 1]; + int matches = 0; + matches = SSCANF (s, + "%s %s", + subject_pkey, + attr_str); + if (0 == matches) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Unable to parse ATTR record string `%s'\n"), + s); + return GNUNET_SYSERR; + + } + if (1 == matches) { + *data_size = sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData); + } else if (2 == matches) { + *data_size = sizeof (struct GNUNET_CREDENTIAL_AttributeRecordData) + strlen (attr_str) + 1; + } + *data = attr = GNUNET_malloc (*data_size); + GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, + strlen (subject_pkey), + &attr->subject_key); + if (NULL != attr_str) + GNUNET_memcpy (&attr[1], + attr_str, + strlen (attr_str)); + + + return GNUNET_OK; + } case GNUNET_GNSRECORD_TYPE_CREDENTIAL: { struct GNUNET_CREDENTIAL_CredentialRecordData *cred; @@ -183,7 +223,7 @@ credential_string_to_value (void *cls, cred->expiration = GNUNET_htonll (etime_abs.abs_value_us); cred->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); cred->purpose.size = htonl (strlen (name) + 1 + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + sizeof (uint64_t)); + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + sizeof (uint64_t)); GNUNET_free (sig); GNUNET_memcpy (&cred[1], name, @@ -207,6 +247,7 @@ static struct { uint32_t number; } name_map[] = { { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL }, + { "ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE }, { NULL, UINT32_MAX } }; diff --git a/src/credential/test_credential_verify.sh b/src/credential/test_credential_verify.sh index 6e5ba4647..ab3c78f41 100755 --- a/src/credential/test_credential_verify.sh +++ b/src/credential/test_credential_verify.sh @@ -31,7 +31,8 @@ TEST_ATTR="user" INTERMEDIATE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testintermediate | awk '{print $3}') SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}') ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}') -CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR -c test_credential_lookup.conf` +AUTHORITY_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testauthority | awk '{print $3}') +CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf` TEST_CREDENTIAL="t1" gnunet-namestore -p -z testsubject -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf @@ -43,17 +44,13 @@ AUTHORITY_ATTR="test" gnunet-namestore -p -z testauthority -a -n $AUTHORITY_ATTR -t ATTR -V "$INTERMEDIATE_KEY $INTERMEDIATE_ATTR.$TEST_ATTR" -e 5m -c test_credential_lookup.conf #TODO2 Add -z swich like in gnunet-gns -#RES_CRED=`$DO_TIMEOUT gnunet-credential --verify --issuer=$ISSUER_KEY --attribute="$TEST_ATTR" --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf` -valgrind gnunet-credential --verify --issuer=$AUTHORITY_KEY --attribute=$AUTHORITY_ATTR --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf +RES_CRED=`gnunet-credential --verify --issuer=$AUTHORITY_KEY --attribute=$AUTHORITY_ATTR --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf` #TODO cleanup properly gnunet-namestore -z testsubject -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf gnunet-arm -e -c test_credential_lookup.conf -#TODO3 proper test -exit 0 - -if [ "$RES_CRED" == "Ok!" ] +if [ "$RES_CRED" == "Successful." ] then exit 0 else -- 2.25.1