From 93cd93a1330fb38add615f797ac9a87fc252ff98 Mon Sep 17 00:00:00 2001 From: Andreas Ebner Date: Sat, 3 Aug 2019 13:01:22 +0200 Subject: Updated fw/bw algo, collect, and verify (still some things left to do) - collect/verify now use delegate instead of credential - parameter in api messages to indicate the direction of the resolution - fw algo sets delegation_chain and ref_count on solution find - namestore lookup instead of iteration to get all delegates from starting/goal subject --- src/credential/credential.h | 12 + src/credential/credential_api.c | 73 ++-- src/credential/credential_serialization.c | 23 +- src/credential/credential_serialization.h | 150 ++++---- src/credential/gnunet-credential.c | 16 +- src/credential/gnunet-service-credential.c | 596 +++++++++++++++++++---------- src/credential/test_credential_own.sh | 21 +- src/include/gnunet_credential_service.h | 73 ++-- 8 files changed, 573 insertions(+), 391 deletions(-) diff --git a/src/credential/credential.h b/src/credential/credential.h index 9de137275..97fdfecbf 100644 --- a/src/credential/credential.h +++ b/src/credential/credential.h @@ -29,6 +29,8 @@ GNUNET_NETWORK_STRUCT_BEGIN +enum direction{Backward, Forward, Bidirectional}; + /** * Message from client to Credential service to collect credentials. */ @@ -54,6 +56,11 @@ struct CollectMessage */ uint16_t issuer_attribute_len; + /** + * Direction of the resolution algo + */ + uint16_t resolution_algo; + /** * Unique identifier for this request (for key collisions). */ @@ -93,6 +100,11 @@ struct VerifyMessage */ uint16_t issuer_attribute_len; + /** + * Direction of the resolution algo + */ + uint16_t resolution_algo; + /** * Unique identifier for this request (for key collisions). */ diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c index 3cbaf6c21..7323d3b1c 100644 --- a/src/credential/credential_api.c +++ b/src/credential/credential_api.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 credential/credential_api.c * @brief library to access the CREDENTIAL service @@ -35,13 +35,14 @@ #include "gnunet_identity_service.h" -#define LOG(kind, ...) GNUNET_log_from (kind, "credential-api", __VA_ARGS__) +#define LOG(kind,...) GNUNET_log_from (kind, "credential-api",__VA_ARGS__) /** * Handle to a verify request */ struct GNUNET_CREDENTIAL_Request { + /** * DLL */ @@ -76,6 +77,7 @@ struct GNUNET_CREDENTIAL_Request * request id */ uint32_t r_id; + }; @@ -84,6 +86,7 @@ struct GNUNET_CREDENTIAL_Request */ struct GNUNET_CREDENTIAL_Handle { + /** * Configuration to use. */ @@ -118,6 +121,7 @@ struct GNUNET_CREDENTIAL_Handle * Request Id generator. Incremented by one for each request. */ uint32_t r_id_gen; + }; @@ -159,8 +163,8 @@ force_reconnect (struct GNUNET_CREDENTIAL_Handle *handle) = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff, - &reconnect_task, - handle); + &reconnect_task, + handle); } @@ -191,7 +195,7 @@ static int check_result (void *cls, const struct DelegationChainResultMessage *vr_msg) { - // TODO + //TODO return GNUNET_OK; } @@ -209,11 +213,12 @@ handle_result (void *cls, struct GNUNET_CREDENTIAL_Handle *handle = cls; uint32_t r_id = ntohl (vr_msg->id); struct GNUNET_CREDENTIAL_Request *vr; - size_t mlen = ntohs (vr_msg->header.size) - sizeof(*vr_msg); + size_t mlen = ntohs (vr_msg->header.size) - sizeof (*vr_msg); uint32_t d_count = ntohl (vr_msg->d_count); uint32_t c_count = ntohl (vr_msg->c_count); struct GNUNET_CREDENTIAL_Delegation d_chain[d_count]; - struct GNUNET_CREDENTIAL_Credential creds[c_count]; + //TODO rename creds + struct GNUNET_CREDENTIAL_Delegate creds[c_count]; GNUNET_CREDENTIAL_CredentialResultProcessor proc; void *proc_cls; @@ -233,9 +238,7 @@ handle_result (void *cls, GNUNET_free (vr); GNUNET_assert (GNUNET_OK == GNUNET_CREDENTIAL_delegation_chain_deserialize (mlen, - (const - char*) &vr_msg - [1], + (const char*) &vr_msg[1], d_count, d_chain, c_count, @@ -246,10 +249,8 @@ handle_result (void *cls, 0, NULL, 0, - NULL); // TODO - } - else - { + NULL); // TODO + } else { proc (proc_cls, d_count, d_chain, @@ -362,7 +363,7 @@ GNUNET_CREDENTIAL_request_cancel (struct GNUNET_CREDENTIAL_Request *lr) /** * Performs attribute collection. - * Collects all credentials of subject to fulfill the + * Collects all credentials of subject to fulfill the * attribute, if possible * * @param handle handle to the Credential service @@ -375,11 +376,9 @@ GNUNET_CREDENTIAL_request_cancel (struct GNUNET_CREDENTIAL_Request *lr) */ struct GNUNET_CREDENTIAL_Request* GNUNET_CREDENTIAL_collect (struct GNUNET_CREDENTIAL_Handle *handle, - const struct - GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, - const struct - GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls) { @@ -394,12 +393,12 @@ GNUNET_CREDENTIAL_collect (struct GNUNET_CREDENTIAL_Handle *handle, return NULL; } - // DEBUG LOG + //DEBUG LOG LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to collect `%s' in CREDENTIAL\n", issuer_attribute); nlen = strlen (issuer_attribute) + 1; - if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(*vr)) + if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr)) { GNUNET_break (0); return NULL; @@ -414,8 +413,11 @@ GNUNET_CREDENTIAL_collect (struct GNUNET_CREDENTIAL_Handle *handle, GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT); c_msg->id = htonl (vr->r_id); c_msg->subject_key = *subject_key; - c_msg->issuer_key = *issuer_key; - c_msg->issuer_attribute_len = htons (strlen (issuer_attribute)); + c_msg->issuer_key = *issuer_key; + c_msg->issuer_attribute_len = htons(strlen(issuer_attribute)); + //c_msg->resolution_algo = htons(Backward); + c_msg->resolution_algo = htons(Forward); + GNUNET_memcpy (&c_msg[1], issuer_attribute, strlen (issuer_attribute)); @@ -449,11 +451,9 @@ struct GNUNET_CREDENTIAL_Request* GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, - const struct - GNUNET_CRYPTO_EcdsaPublicKey *subject_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, uint32_t credential_count, - const struct - GNUNET_CREDENTIAL_Credential *credentials, + const struct GNUNET_CREDENTIAL_Delegate *credentials, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls) { @@ -463,7 +463,7 @@ GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, size_t nlen; size_t clen; - if ((NULL == issuer_attribute)||(NULL == credentials)) + if (NULL == issuer_attribute || NULL == credentials) { GNUNET_break (0); return NULL; @@ -472,12 +472,12 @@ GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, clen = GNUNET_CREDENTIAL_credentials_get_size (credential_count, credentials); - // DEBUG LOG + //DEBUG LOG LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to verify `%s' in CREDENTIAL\n", issuer_attribute); nlen = strlen (issuer_attribute) + 1 + clen; - if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(*vr)) + if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr)) { GNUNET_break (0); return NULL; @@ -492,16 +492,19 @@ GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY); v_msg->id = htonl (vr->r_id); v_msg->subject_key = *subject_key; - v_msg->c_count = htonl (credential_count); - v_msg->issuer_key = *issuer_key; - v_msg->issuer_attribute_len = htons (strlen (issuer_attribute)); + v_msg->c_count = htonl(credential_count); + v_msg->issuer_key = *issuer_key; + v_msg->issuer_attribute_len = htons(strlen(issuer_attribute)); + //v_msg->resolution_algo = htons(Backward); + v_msg->resolution_algo = htons(Forward); + GNUNET_memcpy (&v_msg[1], issuer_attribute, strlen (issuer_attribute)); GNUNET_CREDENTIAL_credentials_serialize (credential_count, credentials, clen, - ((char*) &v_msg[1]) + ((char*)&v_msg[1]) + strlen (issuer_attribute) + 1); GNUNET_CONTAINER_DLL_insert (handle->request_head, handle->request_tail, diff --git a/src/credential/credential_serialization.c b/src/credential/credential_serialization.c index b14ec26f2..4f3b11450 100644 --- a/src/credential/credential_serialization.c +++ b/src/credential/credential_serialization.c @@ -149,12 +149,12 @@ GNUNET_CREDENTIAL_delegation_set_deserialize ( size_t GNUNET_CREDENTIAL_credentials_get_size ( unsigned int c_count, - const struct GNUNET_CREDENTIAL_Credential *cd) + const struct GNUNET_CREDENTIAL_Delegate *cd) { unsigned int i; size_t ret; - ret = sizeof (struct CredentialEntry) * (c_count); + ret = sizeof (struct DelegateEntry) * (c_count); for (i = 0; i < c_count; i++) { @@ -175,11 +175,11 @@ GNUNET_CREDENTIAL_credentials_get_size ( ssize_t GNUNET_CREDENTIAL_credentials_serialize ( unsigned int c_count, - const struct GNUNET_CREDENTIAL_Credential *cd, + const struct GNUNET_CREDENTIAL_Delegate *cd, size_t dest_size, char *dest) { - struct CredentialEntry c_rec; + struct DelegateEntry c_rec; unsigned int i; size_t off; @@ -192,7 +192,7 @@ GNUNET_CREDENTIAL_credentials_serialize ( c_rec.signature = cd[i].signature; c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); c_rec.purpose.size = - htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - + htonl ((sizeof (struct DelegateEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us); if (off + sizeof (c_rec) > dest_size) @@ -225,9 +225,9 @@ GNUNET_CREDENTIAL_credentials_deserialize ( size_t len, const char *src, unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cd) + struct GNUNET_CREDENTIAL_Delegate *cd) { - struct CredentialEntry c_rec; + struct DelegateEntry c_rec; unsigned int i; size_t off; @@ -247,6 +247,7 @@ GNUNET_CREDENTIAL_credentials_deserialize ( return GNUNET_SYSERR; cd[i].issuer_attribute = &src[off]; off += cd[i].issuer_attribute_len; + cd[i].subject_attribute_len = 0; } return GNUNET_OK; } @@ -267,7 +268,7 @@ GNUNET_CREDENTIAL_delegation_chain_get_size ( unsigned int d_count, const struct GNUNET_CREDENTIAL_Delegation *dd, unsigned int c_count, - const struct GNUNET_CREDENTIAL_Credential *cd) + const struct GNUNET_CREDENTIAL_Delegate *cd) { unsigned int i; size_t ret; @@ -299,7 +300,7 @@ GNUNET_CREDENTIAL_delegation_chain_serialize ( unsigned int d_count, const struct GNUNET_CREDENTIAL_Delegation *dd, unsigned int c_count, - const struct GNUNET_CREDENTIAL_Credential *cd, + const struct GNUNET_CREDENTIAL_Delegate *cd, size_t dest_size, char *dest) { @@ -358,7 +359,7 @@ GNUNET_CREDENTIAL_delegation_chain_deserialize ( unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *dd, unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cd) + struct GNUNET_CREDENTIAL_Delegate *cd) { struct ChainEntry rec; unsigned int i; @@ -460,8 +461,6 @@ GNUNET_CREDENTIAL_credential_deserialize (const char *data, size_t data_size) return cred; } -//TODO own file for delegate de/serialization - int GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *dele, char **data) diff --git a/src/credential/credential_serialization.h b/src/credential/credential_serialization.h index ebeae0d89..072beb44e 100644 --- a/src/credential/credential_serialization.h +++ b/src/credential/credential_serialization.h @@ -11,17 +11,17 @@ 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 credential/credential_serialization.h - * @brief API to serialize and deserialize delegation chains + * @brief API to serialize and deserialize delegation chains * and credentials * @author Martin Schanzenbach */ @@ -43,8 +43,7 @@ */ size_t GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count, - const struct - GNUNET_CREDENTIAL_DelegationSet *dsr); + const struct GNUNET_CREDENTIAL_DelegationSet *dsr); /** * Serizalize the given delegation record entries @@ -57,8 +56,7 @@ GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count, */ ssize_t GNUNET_CREDENTIAL_delegation_set_serialize (unsigned int d_count, - const struct - GNUNET_CREDENTIAL_DelegationSet *dsr, + const struct GNUNET_CREDENTIAL_DelegationSet *dsr, size_t dest_size, char *dest); @@ -76,79 +74,69 @@ int GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len, const char *src, unsigned int d_count, - struct - GNUNET_CREDENTIAL_DelegationSet * - dsr); - -/** - * Calculate how many bytes we will need to serialize - * the given delegation chain and credential - * - * @param d_count number of delegation chain entries - * @param dd array of #GNUNET_CREDENTIAL_Delegation - * @param c_count number of credential entries - * @param cd a #GNUNET_CREDENTIAL_Credential - * @return the required size to serialize - */ -size_t -GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count, - const struct - GNUNET_CREDENTIAL_Delegation *dd, - unsigned int c_count, - const struct - GNUNET_CREDENTIAL_Credential *cd); - -/** - * Serizalize the given delegation chain entries and credential - * - * @param d_count number of delegation chain entries - * @param dd array of #GNUNET_CREDENTIAL_Delegation - * @param c_count number of credential entries - * @param cd a #GNUNET_CREDENTIAL_Credential - * @param dest_size size of the destination - * @param dest where to store the result - * @return the size of the data, -1 on failure - */ -ssize_t -GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count, - const struct - GNUNET_CREDENTIAL_Delegation *dd, - unsigned int c_count, - const struct - GNUNET_CREDENTIAL_Credential *cd, - size_t dest_size, - char *dest); - - -/** - * Deserialize the given destination - * - * @param len size of the serialized delegation chain and cred - * @param src the serialized data - * @param d_count the number of delegation chain entries - * @param dd where to put the delegation chain entries - * @param c_count number of credential entries - * @param cd where to put the credential data - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -int -GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len, - const char *src, - unsigned int d_count, - struct - GNUNET_CREDENTIAL_Delegation *dd, - unsigned int c_count, - struct - GNUNET_CREDENTIAL_Credential *cd); -size_t -GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count, - const struct - GNUNET_CREDENTIAL_Credential *cd); + struct GNUNET_CREDENTIAL_DelegationSet *dsr); + + /** + * Calculate how many bytes we will need to serialize + * the given delegation chain and credential + * + * @param d_count number of delegation chain entries + * @param dd array of #GNUNET_CREDENTIAL_Delegation + * @param c_count number of credential entries + * @param cd a #GNUNET_CREDENTIAL_Credential + * @return the required size to serialize + */ + size_t + GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count, + const struct GNUNET_CREDENTIAL_Delegation *dd, + unsigned int c_count, + const struct GNUNET_CREDENTIAL_Delegate *cd); + + /** + * Serizalize the given delegation chain entries and credential + * + * @param d_count number of delegation chain entries + * @param dd array of #GNUNET_CREDENTIAL_Delegation + * @param c_count number of credential entries + * @param cd a #GNUNET_CREDENTIAL_Credential + * @param dest_size size of the destination + * @param dest where to store the result + * @return the size of the data, -1 on failure + */ + ssize_t + GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count, + const struct GNUNET_CREDENTIAL_Delegation *dd, + unsigned int c_count, + const struct GNUNET_CREDENTIAL_Delegate *cd, + size_t dest_size, + char *dest); + + + /** + * Deserialize the given destination + * + * @param len size of the serialized delegation chain and cred + * @param src the serialized data + * @param d_count the number of delegation chain entries + * @param dd where to put the delegation chain entries + * @param c_count number of credential entries + * @param cd where to put the credential data + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ + int + GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len, + const char *src, + unsigned int d_count, + struct GNUNET_CREDENTIAL_Delegation *dd, + unsigned int c_count, + struct GNUNET_CREDENTIAL_Delegate *cd); + size_t + GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count, + const struct GNUNET_CREDENTIAL_Delegate *cd); ssize_t GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count, - const struct - GNUNET_CREDENTIAL_Credential *cd, + const struct GNUNET_CREDENTIAL_Delegate *cd, size_t dest_size, char *dest); @@ -157,17 +145,15 @@ int GNUNET_CREDENTIAL_credentials_deserialize (size_t len, const char *src, unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential * - cd); + struct GNUNET_CREDENTIAL_Delegate *cd); int -GNUNET_CREDENTIAL_credential_serialize (struct - GNUNET_CREDENTIAL_Credential *cred, +GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred, char **data); struct GNUNET_CREDENTIAL_Credential* -GNUNET_CREDENTIAL_credential_deserialize (const char*data, +GNUNET_CREDENTIAL_credential_deserialize (const char* data, size_t data_size); int diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c index 55a4653fb..64f5c5a5f 100644 --- a/src/credential/gnunet-credential.c +++ b/src/credential/gnunet-credential.c @@ -254,7 +254,7 @@ handle_collect_result (void *cls, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *dc, unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cred) + struct GNUNET_CREDENTIAL_Delegate *cred) { int i; char *line; @@ -264,10 +264,12 @@ handle_collect_result (void *cls, { for (i = 0; i < c_count; i++) { - line = GNUNET_CREDENTIAL_credential_to_string (&cred[i]); + line = GNUNET_CREDENTIAL_delegate_to_string (&cred[i]); printf ("%s\n", line); GNUNET_free (line); } + } else { + printf("Received NULL\n"); } @@ -280,7 +282,7 @@ handle_verify_result (void *cls, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *dc, unsigned int c_count, - struct GNUNET_CREDENTIAL_Credential *cred) + struct GNUNET_CREDENTIAL_Delegate *cred) { int i; char *iss_key; @@ -886,17 +888,17 @@ run (void *cls, int i; while (NULL != (tok = strtok (NULL, ","))) count++; - struct GNUNET_CREDENTIAL_Credential credentials[count]; - struct GNUNET_CREDENTIAL_Credential *cred; + struct GNUNET_CREDENTIAL_Delegate credentials[count]; + struct GNUNET_CREDENTIAL_Delegate *cred; GNUNET_free (tmp); tmp = GNUNET_strdup (subject_credential); tok = strtok (tmp, ","); for (i = 0; i < count; i++) { - cred = GNUNET_CREDENTIAL_credential_from_string (tok); + cred = GNUNET_CREDENTIAL_delegate_from_string (tok); GNUNET_memcpy (&credentials[i], cred, - sizeof (struct GNUNET_CREDENTIAL_Credential)); + sizeof (struct GNUNET_CREDENTIAL_Delegate)); credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute); tok = strtok (NULL, ","); GNUNET_free (cred); diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c index d7f6e34d5..da43334df 100644 --- a/src/credential/gnunet-service-credential.c +++ b/src/credential/gnunet-service-credential.c @@ -105,6 +105,32 @@ struct CredentialRecordEntry struct GNUNET_CREDENTIAL_Credential *credential; }; +/** + * DLL for record + */ +struct DelegateRecordEntry +{ + /** + * DLL + */ + struct DelegateRecordEntry *next; + + /** + * DLL + */ + struct DelegateRecordEntry *prev; + + /** + * Number of references in delegation chains + */ + uint32_t refcount; + + /** + * Payload + */ + struct GNUNET_CREDENTIAL_Delegate *delegate; +}; + /** * DLL used for delegations * Used for OR delegations @@ -291,6 +317,21 @@ struct VerifyRequestHandle */ uint32_t cred_chain_size; + /** + * Credential DLL + */ + struct DelegateRecordEntry *del_chain_head; + + /** + * Credential DLL + */ + struct DelegateRecordEntry *del_chain_tail; + + /** + * Credential DLL size + */ + uint32_t del_chain_size; + /** * Root Delegation Set */ @@ -311,11 +352,21 @@ struct VerifyRequestHandle */ uint64_t pending_lookups; + /** + * Direction of the resolution algo + */ + enum direction resolution_algo; + /** * Credential iterator */ struct GNUNET_NAMESTORE_ZoneIterator *cred_collection_iter; + /** + * Credential iterator + */ + struct GNUNET_NAMESTORE_QueueEntry *dele_qe; + /** * Collect task */ @@ -446,9 +497,11 @@ send_lookup_response (struct VerifyRequestHandle *vrh) struct DelegationChainResultMessage *rmsg; struct DelegationChainEntry *dce; struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size]; - struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size]; - struct CredentialRecordEntry *cd; - struct CredentialRecordEntry *tmp; + //TODO rename cred/cd + //TODO rename all methods using credential + struct GNUNET_CREDENTIAL_Delegate cred[vrh->del_chain_size]; + struct DelegateRecordEntry *cd; + struct DelegateRecordEntry *tmp; size_t size; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n"); @@ -467,43 +520,40 @@ send_lookup_response (struct VerifyRequestHandle *vrh) dce = dce->next; } - /** - * Remove all credentials not needed - */ - for (cd = vrh->cred_chain_head; NULL != cd;) { + // Remove all not needed credentials + for (cd = vrh->del_chain_head; NULL != cd;) { if (cd->refcount > 0) { cd = cd->next; continue; } tmp = cd; cd = cd->next; - GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head, - vrh->cred_chain_tail, + GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head, + vrh->del_chain_tail, tmp); - GNUNET_free (tmp->credential); + GNUNET_free (tmp->delegate); GNUNET_free (tmp); - vrh->cred_chain_size--; + vrh->del_chain_size--; } /** * Get serialized record data * Append at the end of rmsg */ - cd = vrh->cred_chain_head; - 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; + cd = vrh->del_chain_head; + for (uint32_t i = 0; i < vrh->del_chain_size; i++) { + cred[i].issuer_key = cd->delegate->issuer_key; + cred[i].subject_key = cd->delegate->subject_key; cred[i].issuer_attribute_len - = strlen (cd->credential->issuer_attribute) + 1; - cred[i].issuer_attribute = cd->credential->issuer_attribute; - cred[i].expiration = cd->credential->expiration; - cred[i].signature = cd->credential->signature; + = strlen (cd->delegate->issuer_attribute) + 1; + cred[i].issuer_attribute = cd->delegate->issuer_attribute; + cred[i].expiration = cd->delegate->expiration; + cred[i].signature = cd->delegate->signature; cd = cd->next; } - size - = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size, + size = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size, dd, - vrh->cred_chain_size, + vrh->del_chain_size, cred); env = GNUNET_MQ_msg_extra (rmsg, size, @@ -511,9 +561,9 @@ send_lookup_response (struct VerifyRequestHandle *vrh) // Assign id so that client can find associated request rmsg->id = vrh->request_id; rmsg->d_count = htonl (vrh->delegation_chain_size); - rmsg->c_count = htonl (vrh->cred_chain_size); + rmsg->c_count = htonl (vrh->del_chain_size); - if (0 < vrh->cred_chain_size) + if (0 < vrh->del_chain_size) rmsg->cred_found = htonl (GNUNET_YES); else rmsg->cred_found = htonl (GNUNET_NO); @@ -522,7 +572,7 @@ send_lookup_response (struct VerifyRequestHandle *vrh) -1 != GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size, dd, - vrh->cred_chain_size, + vrh->del_chain_size, cred, size, (char *)&rmsg[1])); @@ -537,12 +587,72 @@ send_lookup_response (struct VerifyRequestHandle *vrh) GNUNET_NO); } +static char* +partial_match(char *tmp_trail, char *tmp_subattr, char *parent_trail, char *issuer_attribute) +{ + char *saveptr1, *saveptr2; + char *trail_token; + char *sub_token; + char *attr_trailer; + + // tok both, parent->attr_trailer and del->sub_attr to see how far they match, + // take rest of parent trailer (only when del->sub_attr token is null), and + // create new/actual trailer with del->iss_attr + trail_token = strtok_r (tmp_trail, ".", &saveptr1); + sub_token = strtok_r (tmp_subattr, ".", &saveptr2); + while (NULL != trail_token && NULL != sub_token) + { + if(0 == strcmp(trail_token,sub_token)) + { + // good, matches, remove + } else { + // not relevant for solving the chain, end for iteration here + return NULL; + } + + trail_token = strtok_r (NULL, ".", &saveptr1); + sub_token = strtok_r (NULL, ".", &saveptr2); + } + // skip this entry and go to next for if: + // 1. at some point the attr of the trailer and the subject dont match + // 2. the trailer is NULL, but the subject has more attributes + // Reason: This will lead to "startzone.attribute" but we're looking for a solution + // for "<- startzone" + if(NULL == trail_token) + { + return NULL; + } + + // do not have to check sub_token == NULL, if both would be NULL + // at the same time, the complete match part above should have triggered already + + // otherwise, above while only ends when sub_token == NULL + GNUNET_asprintf (&attr_trailer, + "%s", + trail_token); + trail_token = strtok_r (NULL, ".", &saveptr1); + while(NULL != trail_token) + { + GNUNET_asprintf (&attr_trailer, + "%s.%s", + parent_trail, + trail_token); + trail_token = strtok_r (NULL, ".", &saveptr1); + + } + GNUNET_asprintf (&attr_trailer, + "%s.%s", + issuer_attribute, + attr_trailer); + return attr_trailer; +} + static void test_resolution (void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW:Got %d entries\n", rd_count); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count); struct VerifyRequestHandle *vrh; struct DelegationSetQueueEntry *current_set; @@ -554,9 +664,7 @@ test_resolution (void *cls, current_set->lookup_request = NULL; vrh = current_set->handle; vrh->pending_lookups--; - //GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW:current set %s\n", current_set->issuer_attribute); - // Loop record entries for (uint32_t i = 0; i < rd_count; i++) { if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type) @@ -566,10 +674,6 @@ test_resolution (void *cls, struct GNUNET_CREDENTIAL_Delegate *del; del = GNUNET_CREDENTIAL_delegate_deserialize(rd[i].data, rd[i].data_size); - // TODO parse subject and issuer attributes which are required for algo solving - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW:iss %s %s\n", GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->issuer_key), del->issuer_attribute); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW:sub %s %s\n", GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->subject_key), del->subject_attribute); - // Start: Create DQ Entry dq_entry = GNUNET_new (struct DelegationQueueEntry); // AND delegations are not possible, only 1 solution @@ -594,15 +698,13 @@ test_resolution (void *cls, // 2. partial match: replace // 3. new solution: replace, add trailer - //GNUNET_assert(NULL != current_set->attr_trailer); - // TODO only during test + // At resolution chain start trailer of parent is NULL if (NULL == current_set->attr_trailer) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW: trailer null\n"); // for (5) F.c <- G, remember .c when going upwards ds_entry->attr_trailer = GNUNET_strdup(del->issuer_attribute); } else { if (0 == del->subject_attribute_len){ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW: new solution\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: New solution\n"); // new solution // create new trailer del->issuer_attribute, ds_entry->attr_trailer GNUNET_asprintf (&ds_entry->attr_trailer, @@ -610,76 +712,33 @@ test_resolution (void *cls, del->issuer_attribute, current_set->attr_trailer); } else if(0 == strcmp(del->subject_attribute, current_set->attr_trailer)){ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW: complete match\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Complete match\n"); // complete match // new trailer == issuer attribute (e.g. (5) to (4)) // TODO memleak, free trailer before ds_entry->attr_trailer = GNUNET_strdup(del->issuer_attribute); } else { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW: partial match\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Partial match\n"); // partial match - // TODO problem when checking with contains: attr = disco or attr = disc both say success - // ==> therefore: split and check the single attributes - // replace/remove partial match trailer and add the new one - - char *saveptr1, *saveptr2; - char *trail_token; - char *sub_token; - char *tmp_trail = GNUNET_strdup (current_set->attr_trailer); - char *tmp_subattr = GNUNET_strdup (del->subject_attribute); - - // tok both, parent->attr_trailer and del->sub_attr to see how far they match, - // take rest of parent trailer (only when del->sub_attr token is null), and - // create new/actual trailer with del->iss_attr - trail_token = strtok_r (tmp_trail, ".", &saveptr1); - sub_token = strtok_r (tmp_subattr, ".", &saveptr2); - while (NULL != trail_token && NULL != sub_token) - { - if(0 == strcmp(trail_token,sub_token)) - { - // good, matches, remove - } else { - // not relevant for solving the chain, end function here - // TODO how to end this correctly? just return? - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW:throwing %s %s\n", trail_token, sub_token); - - // TODO break zum nächsten for - //return; - } - - trail_token = strtok_r (NULL, ".", &saveptr1); - sub_token = strtok_r (NULL, ".", &saveptr2); - } - if(NULL == trail_token) - { - //TODO error, can't happen - } - // do not have to check sub_token == NULL, if both would be NULL - // at the same time, the complete match part above should have triggered already - - // otherwise, above while only ends when sub_token == NULL - GNUNET_asprintf (&ds_entry->attr_trailer, - "%s", - trail_token); - trail_token = strtok_r (NULL, ".", &saveptr1); - while(NULL != trail_token) - { - GNUNET_asprintf (&ds_entry->attr_trailer, - "%s.%s", - current_set->attr_trailer, - trail_token); - trail_token = strtok_r (NULL, ".", &saveptr1); - - } - GNUNET_asprintf (&ds_entry->attr_trailer, - "%s.%s", - del->issuer_attribute, - ds_entry->attr_trailer); - + char *trail = partial_match(GNUNET_strdup (current_set->attr_trailer), + GNUNET_strdup (del->subject_attribute), + current_set->attr_trailer, + GNUNET_strdup (del->issuer_attribute)); + + // if null: skip this record entry (reasons: mismatch or overmatch, both not relevant) + if(NULL == trail) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entry not relevant, discarding: %s.%s <- %s.%s\n", + GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->issuer_key), + del->issuer_attribute, + GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->subject_key), + del->subject_attribute); + continue; + } else + ds_entry->attr_trailer = trail; } } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "-----------FW: new tailer %s\n", ds_entry->attr_trailer); + // Start: Credential Chain Entry // issuer key is subject key, who needs to be contacted to resolve this (forward, therefore subject) @@ -699,27 +758,75 @@ test_resolution (void *cls, // current delegation as parent ds_entry->parent_queue_entry = dq_entry; - // TODO verify if end is reached: - // what is required? Only issuer key/attr and attr_trailer new == 0 + // Check for solution + // if: issuer key we looking for + if (0 == memcmp (&del->issuer_key, + &vrh->issuer_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) + { + // if: issuer attr we looking for + if (0 == strcmp (del->issuer_attribute, + vrh->issuer_attribute)) + { + // if: complete match, meaning new trailer == issuer attr + if(0 == strcmp (vrh->issuer_attribute, ds_entry->attr_trailer)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found: Solution\n"); + + // Add to delegation_chain + struct DelegationSetQueueEntry *tmp_set; + for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry; + tmp_set = tmp_set->parent_queue_entry->parent_set) { + if (NULL != tmp_set->delegation_chain_entry) { + vrh->delegation_chain_size++; + GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head, + vrh->delegation_chain_tail, + tmp_set->delegation_chain_entry); + } + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "tmpentrylast %s %s\n", + GNUNET_CRYPTO_ecdsa_public_key_to_string(&vrh->delegation_chain_head->subject_key), + vrh->delegation_chain_head->subject_attribute); + + // Increase refcount for this delegate + for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head; del_entry != NULL; del_entry = del_entry->next) { + if (0 == memcmp (&del_entry->delegate->issuer_key, + &vrh->delegation_chain_head->subject_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) + { + if (0 == strcmp (del_entry->delegate->issuer_attribute, + vrh->delegation_chain_head->subject_attribute)) + { + del_entry->refcount++; + } + } + } + + send_lookup_response (vrh); + return; + } + } + } - // TODO until good verify check: fixed number of lookups - //vrh->pending_lookups++; + // Starting a new GNS lookup + vrh->pending_lookups++; ds_entry->handle = vrh; - const struct GNUNET_CRYPTO_EcdsaPublicKey *kkey = &del->issuer_key; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "-----------FW: Starting AGAIN %s\n",GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->issuer_key)); - if (0 == vrh->pending_lookups) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n"); - return; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Starting to look up trailer %s in zone %s\n", ds_entry->attr_trailer, GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->issuer_key)); + GNUNET_GNS_lookup (gns, GNUNET_GNS_EMPTY_LABEL_AT, - kkey, // subject_key, + &del->issuer_key, GNUNET_GNSRECORD_TYPE_DELEGATE, GNUNET_GNS_LO_DEFAULT, &test_resolution, ds_entry); + } + if (0 == vrh->pending_lookups) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n"); + send_lookup_response (vrh); + return; } } @@ -730,7 +837,7 @@ backward_resolution (void *cls, { struct VerifyRequestHandle *vrh; const struct GNUNET_CREDENTIAL_DelegationRecord *sets; - struct CredentialRecordEntry *cred_pointer; + struct DelegateRecordEntry *del_pointer; struct DelegationSetQueueEntry *current_set; struct DelegationSetQueueEntry *ds_entry; struct DelegationSetQueueEntry *tmp_set; @@ -742,10 +849,6 @@ backward_resolution (void *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++) { @@ -819,10 +922,6 @@ backward_resolution (void *cls, 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); @@ -831,26 +930,26 @@ 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) { + for (del_pointer = vrh->del_chain_head; del_pointer != NULL; + del_pointer = del_pointer->next) { // If key and attribute match credential continue and backtrack if (0 != memcmp (&set->subject_key, - &cred_pointer->credential->issuer_key, + &del_pointer->delegate->issuer_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) continue; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking if %s matches %s\n", ds_entry->unresolved_attribute_delegation, - cred_pointer->credential->issuer_attribute); + del_pointer->delegate->issuer_attribute); if (0 != strcmp (ds_entry->unresolved_attribute_delegation, - cred_pointer->credential->issuer_attribute)) + del_pointer->delegate->issuer_attribute)) continue; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n"); - cred_pointer->refcount++; + del_pointer->refcount++; // Backtrack for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry; tmp_set = tmp_set->parent_queue_entry->parent_set) { @@ -910,24 +1009,15 @@ backward_resolution (void *cls, vrh->pending_lookups++; ds_entry->handle = vrh; - /*ds_entry->lookup_request + ds_entry->lookup_request = GNUNET_GNS_lookup (gns, lookup_attribute, 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 %s\n", GNUNET_CRYPTO_ecdsa_public_key_to_string(ds_entry->issuer_key)); - vrh->pending_lookups = 5; - ds_entry->lookup_request - = GNUNET_GNS_lookup (gns, - GNUNET_GNS_EMPTY_LABEL_AT, - ds_entry->issuer_key, // issuer_key, - GNUNET_GNSRECORD_TYPE_DELEGATE, - GNUNET_GNS_LO_DEFAULT, - &test_resolution, ds_entry); + GNUNET_free (lookup_attribute); } } @@ -950,27 +1040,25 @@ delegation_chain_resolution_start (void *cls) { struct VerifyRequestHandle *vrh = cls; struct DelegationSetQueueEntry *ds_entry; - struct CredentialRecordEntry *cr_entry; + struct DelegateRecordEntry *del_entry; vrh->lookup_request = NULL; - if (0 == vrh->cred_chain_size) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No credentials found\n"); + if (0 == vrh->del_chain_size) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegates found\n"); send_lookup_response (vrh); return; } - for (cr_entry = vrh->cred_chain_head; cr_entry != NULL; - cr_entry = cr_entry->next) { - if (0 - != memcmp (&cr_entry->credential->issuer_key, + for (del_entry = vrh->del_chain_head; del_entry != NULL; + del_entry = del_entry->next) { + if (0 != memcmp (&del_entry->delegate->issuer_key, &vrh->issuer_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) continue; - if (0 - != strcmp (cr_entry->credential->issuer_attribute, + if (0 != strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute)) continue; - cr_entry->refcount++; + del_entry->refcount++; // Found match prematurely send_lookup_response (vrh); return; @@ -1005,18 +1093,91 @@ delegation_chain_resolution_start (void *cls) GNUNET_GNS_LO_DEFAULT, &backward_resolution, ds_entry); - //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Starting %s\n", GNUNET_CRYPTO_ecdsa_public_key_to_string(&vrh->issuer_key)); - - // TODO we start with example (5) F.c <- G - // => attr_trailer = c - //ds_entry->attr_trailer = "c"; - /*ds_entry->lookup_request = GNUNET_GNS_lookup (gns, - GNUNET_GNS_EMPTY_LABEL_AT, - &vrh->issuer_key, // subject_key, - GNUNET_GNSRECORD_TYPE_DELEGATE, - GNUNET_GNS_LO_DEFAULT, - &test_resolution, - ds_entry);*/ +} + +static void +delegation_chain_fw_resolution_start (void *cls) +{ + struct VerifyRequestHandle *vrh = cls; + struct DelegationSetQueueEntry *ds_entry; + struct DelegateRecordEntry *del_entry; + + vrh->lookup_request = NULL; + // set to 0 and increase on each lookup: for fw multiple lookups (may be) started + vrh->pending_lookups = 0; + + //TODO no pre-check with vrh->dele_chain_bla if match issuer_key + //otherwise: start mutliple lookups for each vrh->dele_chain + // A.a <- ... + // X.x <- C + // Y.y <- C + // wenn X.x oder Y.y nicht == A.a dann starte bei X und bei Y + + // bei backward: check every cred entry if match issuer key + // otherwise: start at issuer and go down till match + // A.a <- ... + // X.x <- C + // Y.y <- C + // wenn X.x oder Y.y nicht == A.a dann starte von A + if (0 == vrh->del_chain_size) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegations found\n"); + send_lookup_response (vrh); + return; + } + + // Check if one of the delegations of the subject already match + for (del_entry = vrh->del_chain_head; del_entry != NULL; del_entry = del_entry->next) { + if (0 != memcmp (&del_entry->delegate->issuer_key, + &vrh->issuer_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) + continue; + if (0 != strcmp (del_entry->delegate->issuer_attribute, + vrh->issuer_attribute)) + continue; + del_entry->refcount++; + // Found match prematurely + send_lookup_response (vrh); + return; + } + + // None match, therefore start for every delegation found a lookup chain + // Return and end collect process on first chain iss <-> sub found + + // ds_entry created belongs to the first lookup, vrh still has the + // issuer+attr we look for + for (del_entry = vrh->del_chain_head; del_entry != NULL; del_entry = del_entry->next) { + //char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1]; + //strcpy (issuer_attribute_name, vrh->issuer_attribute); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Looking for %s.%s\n", + GNUNET_CRYPTO_ecdsa_public_key_to_string(&del_entry->delegate->issuer_key), del_entry->delegate->issuer_attribute); + + ds_entry = GNUNET_new (struct DelegationSetQueueEntry); + ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); + // TODO: new ds_entry struct with subject_key (or one for both with contact_key or sth) + GNUNET_memcpy (ds_entry->issuer_key, + &del_entry->delegate->subject_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); + //ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute); + ds_entry->attr_trailer = GNUNET_strdup(del_entry->delegate->issuer_attribute); + ds_entry->handle = vrh; + // TODO: no lookup attribute for forward? + //ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute); + + vrh->root_set = ds_entry; + vrh->pending_lookups ++; + // Start with forward resolution + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "# Start Forward Resolution\n"); + + ds_entry->lookup_request = GNUNET_GNS_lookup (gns, + GNUNET_GNS_EMPTY_LABEL_AT, + &del_entry->delegate->issuer_key, // issuer_key, + GNUNET_GNSRECORD_TYPE_DELEGATE, + GNUNET_GNS_LO_DEFAULT, + &test_resolution, + ds_entry); + } } static int @@ -1048,7 +1209,7 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg) { struct VerifyRequestHandle *vrh; struct GNUNET_SERVICE_Client *client = cls; - struct CredentialRecordEntry *cr_entry; + struct DelegateRecordEntry *del_entry; uint32_t credentials_count; uint32_t credential_data_size; char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; @@ -1069,24 +1230,24 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg) vrh->issuer_key = v_msg->issuer_key; vrh->subject_key = v_msg->subject_key; vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); + vrh->resolution_algo = ntohs(v_msg->resolution_algo); + GNUNET_SERVICE_client_continue (vrh->client); if (0 == strlen (issuer_attribute)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n"); send_lookup_response (vrh); return; } - /** - * First, collect credentials - * TODO: cleanup! - */ + + // Parse delegates from verifaction message credentials_count = ntohl (v_msg->c_count); credential_data_size = ntohs (v_msg->header.size) - sizeof (struct VerifyMessage) - ntohs (v_msg->issuer_attribute_len) - 1; - struct GNUNET_CREDENTIAL_Credential credentials[credentials_count]; + struct GNUNET_CREDENTIAL_Delegate credentials[credentials_count]; memset (credentials, 0, - sizeof (struct GNUNET_CREDENTIAL_Credential) * credentials_count); + sizeof (struct GNUNET_CREDENTIAL_Delegate) * 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, @@ -1098,27 +1259,37 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg) return; } + // Prepare vrh delegation chain for later validation 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) + del_entry = GNUNET_new (struct DelegateRecordEntry); + del_entry->delegate + = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + credentials[i].issuer_attribute_len + 1); - GNUNET_memcpy (cr_entry->credential, + GNUNET_memcpy (del_entry->delegate, &credentials[i], - sizeof (struct GNUNET_CREDENTIAL_Credential)); - GNUNET_memcpy (&cr_entry->credential[1], + sizeof (struct GNUNET_CREDENTIAL_Delegate)); + GNUNET_memcpy (&del_entry->delegate[1], credentials[i].issuer_attribute, credentials[i].issuer_attribute_len); - cr_entry->credential->issuer_attribute_len + del_entry->delegate->issuer_attribute_len = credentials[i].issuer_attribute_len; - 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); - vrh->cred_chain_size++; + del_entry->delegate->issuer_attribute = (char *)&del_entry->delegate[1]; + GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head, + vrh->del_chain_tail, + del_entry); + vrh->del_chain_size++; } - delegation_chain_resolution_start (vrh); + // Switch resolution algo + if(Backward == vrh->resolution_algo){ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "+++++++++++++++++backward\n"); + delegation_chain_resolution_start (vrh); + } else if (Forward == vrh->resolution_algo){ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "+++++++++++++++++forward\n"); + delegation_chain_fw_resolution_start (vrh); + } else{ + //TODO + } } static void @@ -1132,55 +1303,56 @@ handle_cred_collection_error_cb (void *cls) } static void -collect_next (void *cls) +handle_cred_collection_finished_cb (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); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting credentials.\n"); + vrh->cred_collection_iter = NULL; + if(Backward == vrh->resolution_algo){ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "+++++++++++++++++backward\n"); + delegation_chain_resolution_start (vrh); + } else if (Forward == vrh->resolution_algo){ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "+++++++++++++++++forward\n"); + delegation_chain_fw_resolution_start (vrh); + } else{ + //TODO + } } - static void -handle_cred_collection_cb (void *cls, +tmp_handle_cred_collection_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct VerifyRequestHandle *vrh = cls; - struct GNUNET_CREDENTIAL_Credential *crd; - struct CredentialRecordEntry *cr_entry; + struct GNUNET_CREDENTIAL_Delegate *del; + struct DelegateRecordEntry *del_entry; int cred_record_count; - cred_record_count = 0; + vrh->dele_qe = NULL; + + //TODO not all, only private and with sub_attr_len == 0 for (uint32_t i = 0; i < rd_count; i++) { - if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type) + if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type) continue; cred_record_count++; - crd - = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data, rd[i].data_size); - if (NULL == crd) { + del = GNUNET_CREDENTIAL_delegate_deserialize (rd[i].data, rd[i].data_size); + if (NULL == del) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid credential found\n"); continue; } - cr_entry = GNUNET_new (struct CredentialRecordEntry); - cr_entry->credential = crd; - GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head, - vrh->cred_chain_tail, - cr_entry); - vrh->cred_chain_size++; + del_entry = GNUNET_new (struct DelegateRecordEntry); + del_entry->delegate = del; + GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head, + vrh->del_chain_tail, + del_entry); + vrh->del_chain_size++; } - vrh->collect_next_task = GNUNET_SCHEDULER_add_now (&collect_next, vrh); -} - -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); + // No need to collect next, should have all already + //vrh->collect_next_task = GNUNET_SCHEDULER_add_now (&collect_next, vrh); + handle_cred_collection_finished_cb(vrh); } static void @@ -1207,6 +1379,7 @@ handle_collect (void *cls, const struct CollectMessage *c_msg) vrh->issuer_key = c_msg->issuer_key; GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key, &vrh->subject_key); vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); + vrh->resolution_algo = ntohs(c_msg->resolution_algo); if (0 == strlen (issuer_attribute)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n"); @@ -1217,7 +1390,8 @@ handle_collect (void *cls, const struct CollectMessage *c_msg) /** * First, get attribute from subject */ - vrh->cred_collection_iter = GNUNET_NAMESTORE_zone_iteration_start ( + // TODO NAMESTORE_lookup auf empty label statt iteration, iteration genutzt da nicht wusste welches label + /*vrh->cred_collection_iter = GNUNET_NAMESTORE_zone_iteration_start ( namestore, &c_msg->subject_key, &handle_cred_collection_error_cb, @@ -1225,7 +1399,15 @@ handle_collect (void *cls, const struct CollectMessage *c_msg) &handle_cred_collection_cb, vrh, &handle_cred_collection_finished_cb, - vrh); + vrh);*/ + //TODO rename tmp_handle_... and test_resolution.. + vrh->dele_qe = GNUNET_NAMESTORE_records_lookup (namestore, + &c_msg->subject_key, + GNUNET_GNS_EMPTY_LABEL_AT, + &handle_cred_collection_error_cb, + vrh, + &tmp_handle_cred_collection_cb, + vrh); GNUNET_SERVICE_client_continue (vrh->client); } diff --git a/src/credential/test_credential_own.sh b/src/credential/test_credential_own.sh index 23935c75a..19dd686a9 100755 --- a/src/credential/test_credential_own.sh +++ b/src/credential/test_credential_own.sh @@ -68,10 +68,14 @@ gnunet-namestore -D -z e SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=e --attribute="c" --subject="$FKEY c" --ttl="2019-12-12 10:00:00"` gnunet-credential --createSubjectSide --ego=f --import "$SIGNED" +SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=e --attribute="k" --subject="$FKEY c.k" --ttl="2019-12-12 10:00:00"` +gnunet-credential --createSubjectSide --ego=f --import "$SIGNED" gnunet-namestore -D -z f SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=f --attribute="c" --subject="$GKEY" --ttl="2019-12-12 10:00:00"` gnunet-credential --createSubjectSide --ego=g --import "$SIGNED" +SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=a --attribute="c" --subject="$GKEY" --ttl="2019-12-12 10:00:00"` +gnunet-credential --createSubjectSide --ego=g --import "$SIGNED" gnunet-namestore -D -z g @@ -114,18 +118,23 @@ gnunet-namestore -p -z stateu -a -n $STATE_STUD_ATTR -t ATTR -V "$REGISTRARB_KEY 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 +#gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf + +SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=registrarb --attribute="$REG_STUD_ATTR" --subject="$ALICE_KEY" --ttl="2019-12-12 10:00:00"` +gnunet-credential --createSubjectSide --ego=alice --import "$SIGNED" # Starting to resolve echo "+++++Starting Collect" -CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$EPUB_KEY --attribute="random" --ego=alice -c test_credential_lookup.conf | paste -d, -s` -#CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$EPUB_KEY --attribute=$DISC_ATTR --ego=alice -c test_credential_lookup.conf | paste -d, -s` +CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$AKEY --attribute="a" --ego=g -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 +echo gnunet-credential --verify --issuer=$AKEY --attribute="a" --subject=$GKEY --credential=\'$CREDS\' -c test_credential_lookup.conf +RES_CRED=`gnunet-credential --verify --issuer=$AKEY --attribute="a" --subject=$GKEY --credential="$CREDS" -c test_credential_lookup.conf` -RES_CRED=`gnunet-credential --verify --issuer=$EPUB_KEY --attribute="random" --subject=$ALICE_KEY --credential="$CREDS" -c test_credential_lookup.conf` -#RES_CRED=`gnunet-credential --verify --issuer=$GKEY --attribute=$DISC_ATTR --subject=$ALICE_KEY --credential="$CREDS" -c test_credential_lookup.conf` +#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 diff --git a/src/include/gnunet_credential_service.h b/src/include/gnunet_credential_service.h index 7b179e99f..b64bb350c 100644 --- a/src/include/gnunet_credential_service.h +++ b/src/include/gnunet_credential_service.h @@ -11,7 +11,7 @@ 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 . @@ -56,26 +56,27 @@ struct GNUNET_CREDENTIAL_Handle; struct GNUNET_CREDENTIAL_Request; /* - * Enum used for checking whether the issuer has the authority to issue credentials or is just a subject - */ -enum GNUNET_CREDENTIAL_CredentialFlags -{ - // Subject had credentials before, but have been revoked now +* Enum used for checking whether the issuer has the authority to issue credentials or is just a subject +*/ +enum GNUNET_CREDENTIAL_CredentialFlags { + + //Subject had credentials before, but have been revoked now GNUNET_CREDENTIAL_FLAG_REVOKED=0, - // Subject flag indicates that the subject is a holder of this credential and may present it as such + //Subject flag indicates that the subject is a holder of this credential and may present it as such GNUNET_CREDENTIAL_FLAG_SUBJECT=1, - // Issuer flag is used to signify that the subject is allowed to issue this credential and delegate issuance + //Issuer flag is used to signify that the subject is allowed to issue this credential and delegate issuance GNUNET_CREDENTIAL_FLAG_ISSUER=2 + }; GNUNET_NETWORK_STRUCT_BEGIN /** * The attribute delegation record */ -struct GNUNET_CREDENTIAL_DelegationRecord -{ +struct GNUNET_CREDENTIAL_DelegationRecord { + /** * Number of delegation sets in this record */ @@ -94,8 +95,8 @@ struct GNUNET_CREDENTIAL_DelegationRecord /** * The attribute delegation record */ -struct GNUNET_CREDENTIAL_DelegationRecordSet -{ +struct GNUNET_CREDENTIAL_DelegationRecordSet { + /** * Public key of the subject this attribute was delegated to */ @@ -113,8 +114,8 @@ GNUNET_NETWORK_STRUCT_END /** * The attribute delegation record */ -struct GNUNET_CREDENTIAL_DelegationSet -{ +struct GNUNET_CREDENTIAL_DelegationSet { + /** * Public key of the subject this attribute was delegated to */ @@ -132,8 +133,8 @@ struct GNUNET_CREDENTIAL_DelegationSet /** * A delegation */ -struct GNUNET_CREDENTIAL_Delegation -{ +struct GNUNET_CREDENTIAL_Delegation { + /** * The issuer of the delegation */ @@ -169,8 +170,8 @@ struct GNUNET_CREDENTIAL_Delegation /** * A credential */ -struct GNUNET_CREDENTIAL_Credential -{ +struct GNUNET_CREDENTIAL_Credential { + /** * The issuer of the credential */ @@ -200,6 +201,7 @@ struct GNUNET_CREDENTIAL_Credential * The attribute */ const char *issuer_attribute; + }; /** @@ -280,16 +282,10 @@ GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle); * @param credential the credentials */ typedef void (*GNUNET_CREDENTIAL_CredentialResultProcessor) (void *cls, - unsigned int - d_count, - struct - GNUNET_CREDENTIAL_Delegation - *delegation_chain, - unsigned int - c_count, - struct - GNUNET_CREDENTIAL_Credential - *credential); + unsigned int d_count, + struct GNUNET_CREDENTIAL_Delegation *delegation_chain, + unsigned int c_count, + struct GNUNET_CREDENTIAL_Delegate *credential); /** * Iterator called on obtained result for an attribute delegation. @@ -309,8 +305,7 @@ typedef void (*GNUNET_CREDENTIAL_DelegateResultProcessor) (void *cls, * @param result the record data that can be handed to the subject */ typedef void (*GNUNET_CREDENTIAL_RemoveDelegateResultProcessor) (void *cls, - uint32_t - success); + uint32_t success); /** @@ -335,21 +330,17 @@ struct GNUNET_CREDENTIAL_Request* GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, - const struct - GNUNET_CRYPTO_EcdsaPublicKey *subject_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, uint32_t credential_count, - const struct - GNUNET_CREDENTIAL_Credential *credentials, + const struct GNUNET_CREDENTIAL_Delegate *credentials, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls); struct GNUNET_CREDENTIAL_Request* GNUNET_CREDENTIAL_collect (struct GNUNET_CREDENTIAL_Handle *handle, - const struct - GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, - const struct - GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls); @@ -388,8 +379,7 @@ struct GNUNET_CREDENTIAL_Request * GNUNET_CREDENTIAL_remove_delegation (struct GNUNET_CREDENTIAL_Handle *handle, struct GNUNET_IDENTITY_Ego *issuer, const char *attribute, - GNUNET_CREDENTIAL_RemoveDelegateResultProcessor - proc, + GNUNET_CREDENTIAL_RemoveDelegateResultProcessor proc, void *proc_cls); @@ -404,8 +394,7 @@ GNUNET_CREDENTIAL_remove_delegation (struct GNUNET_CREDENTIAL_Handle *handle, * @return handle to the queued request */ struct GNUNET_CREDENTIAL_Credential* -GNUNET_CREDENTIAL_credential_issue (const struct - GNUNET_CRYPTO_EcdsaPrivateKey *issuer, +GNUNET_CREDENTIAL_credential_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, struct GNUNET_CRYPTO_EcdsaPublicKey *subject, const char *attribute, struct GNUNET_TIME_Absolute *expiration); -- cgit v1.2.3