From 5091edcec16455febee99afec20e0ffe6cc59c21 Mon Sep 17 00:00:00 2001 From: Andreas Ebner Date: Tue, 9 Jul 2019 17:53:33 +0200 Subject: Cleanup, additional input checks, renaming, simplification: - introducing own GNUNET_SIGNATURE_PURPOSE_DELEGATE - renaming of cred/crd in delegation_misc.c - renamed extension cmd para to import - changed subject key/attr parsing from memcpy/malloc to strtok - only allow to create delegates to expire absolute not relative (prevent reusing created delegation signatures) - check subject key and reuse expiration of import/signed delegation - replaced strdup() part of delegation_misc.c and credential_serialization.c with pointers - uncommented return after detection of unverifyable signatures --- src/credential/Makefile.am | 2 +- src/credential/credential.h | 43 ++++++ src/credential/credential_api.c | 1 - src/credential/credential_serialization.c | 85 +++++------ src/credential/delegate.h | 79 ---------- src/credential/delegate_misc.c | 114 ++++++++------- src/credential/gnunet-credential.c | 233 +++++++++++++++--------------- src/credential/test_credential_own.sh | 16 +- src/include/gnunet_signatures.h | 4 + 9 files changed, 267 insertions(+), 310 deletions(-) delete mode 100644 src/credential/delegate.h (limited to 'src') diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am index 7d9ab4bea..d7d8964eb 100644 --- a/src/credential/Makefile.am +++ b/src/credential/Makefile.am @@ -69,7 +69,7 @@ gnunet_service_credential_LDADD = \ libgnunetcredential_la_SOURCES = \ - credential_api.c credential.h deleagte.h\ + credential_api.c credential.h\ credential_serialization.c \ credential_serialization.h \ credential_misc.c \ diff --git a/src/credential/credential.h b/src/credential/credential.h index 3d76bbf4f..9de137275 100644 --- a/src/credential/credential.h +++ b/src/credential/credential.h @@ -210,6 +210,49 @@ struct CredentialEntry */ }; +struct DelegateEntry +{ + + /** + * The signature for this credential by the issuer + */ + struct GNUNET_CRYPTO_EcdsaSignature signature; + + /** + * Signature meta + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Public key of the issuer + */ + struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; + + /** + * Public key of the subject this credential was issued to + */ + struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; + + /** + * Expiration time of this credential + */ + uint64_t expiration GNUNET_PACKED; + + /** + * Issuer subject attribute length + */ + uint32_t issuer_attribute_len; + + /** + * Issuer attribute length + */ + uint32_t subject_attribute_len; + + /** + * Followed by the subject attribute string + */ +}; + GNUNET_NETWORK_STRUCT_END diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c index be5ff25ae..3cbaf6c21 100644 --- a/src/credential/credential_api.c +++ b/src/credential/credential_api.c @@ -30,7 +30,6 @@ #include "gnunet_protocols.h" #include "gnunet_signatures.h" #include "credential.h" -#include "delegate.h" #include "credential_serialization.h" #include "gnunet_credential_service.h" #include "gnunet_identity_service.h" diff --git a/src/credential/credential_serialization.c b/src/credential/credential_serialization.c index 95b29a49c..4e461c654 100644 --- a/src/credential/credential_serialization.c +++ b/src/credential/credential_serialization.c @@ -31,7 +31,6 @@ #include "gnunet_credential_service.h" #include "gnunet_signatures.h" #include "credential.h" -#include "delegate.h" /** * Calculate how many bytes we will need to serialize @@ -480,7 +479,7 @@ GNUNET_CREDENTIAL_credential_deserialize (const char*data, //TODO own file for delegate de/serialization int -GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred, +GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *dele, char **data) { size_t size; @@ -488,46 +487,47 @@ GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred, int attr_len; // +1 for \0 - if (0 == cred->subject_attribute_len){ - attr_len = cred->issuer_attribute_len + 1; + if (0 == dele->subject_attribute_len){ + attr_len = dele->issuer_attribute_len + 1; } else { - attr_len = cred->issuer_attribute_len + cred->subject_attribute_len + 1; + attr_len = dele->issuer_attribute_len + dele->subject_attribute_len + 2; } size = sizeof (struct DelegateEntry) + attr_len; char tmp_str[attr_len]; - GNUNET_memcpy(tmp_str, cred->issuer_attribute, cred->issuer_attribute_len); - if (0 != cred->subject_attribute_len){ - GNUNET_memcpy(tmp_str + cred->issuer_attribute_len, cred->subject_attribute, cred->subject_attribute_len); + GNUNET_memcpy(tmp_str, dele->issuer_attribute, dele->issuer_attribute_len); + if (0 != dele->subject_attribute_len){ + tmp_str[dele->issuer_attribute_len] = '\0'; + GNUNET_memcpy(tmp_str + dele->issuer_attribute_len + 1, dele->subject_attribute, dele->subject_attribute_len); } tmp_str[attr_len - 1] = '\0'; *data = GNUNET_malloc (size); cdata = (struct DelegateEntry*)*data; - cdata->subject_key = cred->subject_key; - cdata->issuer_key = cred->issuer_key; - cdata->expiration = GNUNET_htonll (cred->expiration.abs_value_us); - cdata->signature = cred->signature; - cdata->issuer_attribute_len = htonl (cred->issuer_attribute_len + 1); - if (0 == cred->subject_attribute_len){ + cdata->subject_key = dele->subject_key; + cdata->issuer_key = dele->issuer_key; + cdata->expiration = GNUNET_htonll (dele->expiration.abs_value_us); + cdata->signature = dele->signature; + cdata->issuer_attribute_len = htonl (dele->issuer_attribute_len + 1); + if (0 == dele->subject_attribute_len){ cdata->subject_attribute_len = htonl (0); } else { - cdata->subject_attribute_len = htonl (cred->subject_attribute_len + 1); + cdata->subject_attribute_len = htonl (dele->subject_attribute_len + 1); } - cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); + cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE); cdata->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); GNUNET_memcpy (&cdata[1], tmp_str, attr_len); - if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, + if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_DELEGATE, &cdata->purpose, &cdata->signature, &cdata->issuer_key)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n"); - //return NULL; + return 0; } return size; } @@ -536,62 +536,49 @@ struct GNUNET_CREDENTIAL_Delegate* GNUNET_CREDENTIAL_delegate_deserialize (const char* data, size_t data_size) { - struct GNUNET_CREDENTIAL_Delegate *cred; + struct GNUNET_CREDENTIAL_Delegate *dele; struct DelegateEntry *cdata; char *attr_combo_str; if (data_size < sizeof (struct DelegateEntry)) return NULL; cdata = (struct DelegateEntry*)data; - if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, + if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_DELEGATE, &cdata->purpose, &cdata->signature, &cdata->issuer_key)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n"); - //return NULL; + return NULL; } attr_combo_str = (char*)&cdata[1]; int iss_len = ntohl(cdata->issuer_attribute_len); int sub_len = ntohl(cdata->subject_attribute_len); int attr_combo_len = iss_len + sub_len; - - cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_combo_len); - cred->issuer_key = cdata->issuer_key; - cred->subject_key = cdata->subject_key; - GNUNET_memcpy (&cred[1], + dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_combo_len); + + dele->issuer_key = cdata->issuer_key; + dele->subject_key = cdata->subject_key; + GNUNET_memcpy (&dele[1], attr_combo_str, attr_combo_len); - cred->signature = cdata->signature; + dele->signature = cdata->signature; - // Parse the combo attribute string, split into issuer and subject + // Set the pointers for the attributes + dele->issuer_attribute = (char*)&dele[1]; + dele->issuer_attribute_len = iss_len; + dele->subject_attribute_len = sub_len; if(0 == sub_len){ - cred->issuer_attribute = attr_combo_str; - cred->issuer_attribute_len = attr_combo_len; - cred->subject_attribute = '\0'; - cred->subject_attribute_len = 0; + dele->subject_attribute = NULL; } else { - // -1: array index starts from 0 - char *tmp_str = GNUNET_malloc(iss_len); - GNUNET_memcpy(tmp_str, attr_combo_str, iss_len - 1); - tmp_str[iss_len] = '\0'; - cred->issuer_attribute = strdup(tmp_str); - cred->issuer_attribute_len = iss_len; - GNUNET_free(tmp_str); - - // -1: both times, starting from 0 - tmp_str = GNUNET_malloc(sub_len); - GNUNET_memcpy(tmp_str, attr_combo_str + iss_len - 1, sub_len - 1); - tmp_str[sub_len] = '\0'; - cred->subject_attribute = strdup(tmp_str); - cred->subject_attribute_len = sub_len; - GNUNET_free(tmp_str); + dele->subject_attribute = (char*)&dele[1] + iss_len; + } - cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration); + dele->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration); - return cred; + return dele; } /* end of credential_serialization.c */ diff --git a/src/credential/delegate.h b/src/credential/delegate.h deleted file mode 100644 index e1bf112ef..000000000 --- a/src/credential/delegate.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2012-2013 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - 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/delegate.h - * @brief IPC messages between CREDENTIAL API and CREDENTIAL service - * @author Martin Schanzenbach - */ -#ifndef DELEGATE_H -#define DELEGATE_H - -#include "gnunet_credential_service.h" - -GNUNET_NETWORK_STRUCT_BEGIN - -struct DelegateEntry -{ - - /** - * The signature for this credential by the issuer - */ - struct GNUNET_CRYPTO_EcdsaSignature signature; - - /** - * Signature meta - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Public key of the issuer - */ - struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; - - /** - * Public key of the subject this credential was issued to - */ - struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; - - /** - * Expiration time of this credential - */ - uint64_t expiration GNUNET_PACKED; - - /** - * Issuer subject attribute length - */ - uint32_t issuer_attribute_len; - - /** - * Issuer attribute length - */ - uint32_t subject_attribute_len; - - /** - * Followed by the subject attribute string - */ -}; - - -GNUNET_NETWORK_STRUCT_END - -#endif - diff --git a/src/credential/delegate_misc.c b/src/credential/delegate_misc.c index d900ccd1f..5dd8609d6 100644 --- a/src/credential/delegate_misc.c +++ b/src/credential/delegate_misc.c @@ -30,7 +30,7 @@ #include "gnunet_constants.h" #include "gnunet_credential_service.h" #include "gnunet_signatures.h" -#include "delegate.h" +#include "credential.h" #include char* @@ -74,7 +74,7 @@ GNUNET_CREDENTIAL_delegate_to_string (const struct GNUNET_CREDENTIAL_Delegate *c struct GNUNET_CREDENTIAL_Delegate* GNUNET_CREDENTIAL_delegate_from_string (const char* s) { - struct GNUNET_CREDENTIAL_Delegate *cred; + struct GNUNET_CREDENTIAL_Delegate *dele; size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; if (enclen % 5 > 0) enclen += 5 - enclen % 5; @@ -118,44 +118,46 @@ GNUNET_CREDENTIAL_delegate_from_string (const char* s) if(strcmp(sub_attr,"") == 0) { attr_len = strlen (iss_attr) + 1; } else { - attr_len = strlen (iss_attr) + strlen(sub_attr) + 1; + attr_len = strlen (iss_attr) + strlen(sub_attr) + 2; } - cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len); + dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len); char tmp_str[attr_len]; GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr)); if(strcmp(sub_attr,"") != 0) { - GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr)); + tmp_str[strlen(iss_attr)] = '\0'; + GNUNET_memcpy(tmp_str + strlen(iss_attr) + 1, sub_attr, strlen(sub_attr)); } tmp_str[attr_len - 1] = '\0'; GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, strlen (subject_pkey), - &cred->subject_key); + &dele->subject_key); GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey, strlen (issuer_pkey), - &cred->issuer_key); + &dele->issuer_key); GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode (signature, strlen (signature), (char**)&sig)); - cred->signature = *sig; - cred->expiration = etime_abs; + dele->signature = *sig; + dele->expiration = etime_abs; GNUNET_free (sig); - GNUNET_memcpy (&cred[1], + + GNUNET_memcpy (&dele[1], tmp_str, attr_len); - cred->issuer_attribute_len = strlen (iss_attr); - cred->issuer_attribute = strdup(iss_attr); + dele->issuer_attribute = (char*)&dele[1]; + dele->issuer_attribute_len = strlen (iss_attr); if(strcmp(sub_attr,"") == 0) { - cred->subject_attribute_len = 0; - cred->subject_attribute = '\0'; + dele->subject_attribute = NULL; + dele->subject_attribute_len = 0; } else { - cred->subject_attribute_len = strlen (sub_attr); - cred->subject_attribute = strdup(sub_attr); + dele->subject_attribute = (char*)&dele[1] + strlen(iss_attr) + 1; + dele->subject_attribute_len = strlen (sub_attr); } - return cred; + return dele; } /** @@ -163,7 +165,7 @@ GNUNET_CREDENTIAL_delegate_from_string (const char* s) * * @param issuer the ego that should be used to issue the attribute * @param subject the subject of the attribute - * @param attribute the name of the attribute + * @param iss_attr the name of the attribute * @return handle to the queued request */ @@ -174,8 +176,8 @@ GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *is const char *sub_attr, struct GNUNET_TIME_Absolute *expiration) { - struct DelegateEntry *crd; - struct GNUNET_CREDENTIAL_Delegate *cred; + struct DelegateEntry *del; + struct GNUNET_CREDENTIAL_Delegate *dele; size_t size; int attr_len; @@ -183,68 +185,76 @@ GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *is // +1 for \0 attr_len = strlen (iss_attr) + 1; } else { - attr_len = strlen (iss_attr) + strlen(sub_attr) + 1; + // +2 for both strings need to be terminated with \0 + attr_len = strlen (iss_attr) + strlen(sub_attr) + 2; } size = sizeof (struct DelegateEntry) + attr_len; char tmp_str[attr_len]; GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr)); if (NULL != sub_attr){ - GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr)); + tmp_str[strlen(iss_attr)] = '\0'; + GNUNET_memcpy(tmp_str + strlen(iss_attr) + 1, sub_attr, strlen(sub_attr)); } tmp_str[attr_len - 1] = '\0'; - - crd = GNUNET_malloc (size); - crd->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); - crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); + + del = GNUNET_malloc (size); + del->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); + del->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE); GNUNET_CRYPTO_ecdsa_key_get_public (issuer, - &crd->issuer_key); - crd->subject_key = *subject; - crd->expiration = GNUNET_htonll (expiration->abs_value_us); - crd->issuer_attribute_len = htonl (strlen (iss_attr) + 1); + &del->issuer_key); + del->subject_key = *subject; + del->expiration = GNUNET_htonll (expiration->abs_value_us); + del->issuer_attribute_len = htonl (strlen (iss_attr) + 1); if (NULL == sub_attr){ - crd->subject_attribute_len = htonl (0); + del->subject_attribute_len = htonl (0); } else { - crd->subject_attribute_len = htonl (strlen (sub_attr) + 1); + del->subject_attribute_len = htonl (strlen (sub_attr) + 1); } - GNUNET_memcpy (&crd[1], + GNUNET_memcpy (&del[1], tmp_str, attr_len); if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (issuer, - &crd->purpose, - &crd->signature)) + &del->purpose, + &del->signature)) { GNUNET_break (0); - GNUNET_free (crd); + GNUNET_free (del); return NULL; } - cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len); - cred->signature = crd->signature; - cred->expiration = *expiration; + dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len); + dele->signature = del->signature; + dele->expiration = *expiration; GNUNET_CRYPTO_ecdsa_key_get_public (issuer, - &cred->issuer_key); + &dele->issuer_key); - cred->subject_key = *subject; - cred->issuer_attribute = strdup(iss_attr); - cred->issuer_attribute_len = strlen(iss_attr); + dele->subject_key = *subject; + + // Copy the combined string at the part in the memory where the struct ends + GNUNET_memcpy (&dele[1], + tmp_str, + attr_len); + + dele->issuer_attribute = (char*)&dele[1]; + dele->issuer_attribute_len = strlen(iss_attr); if (NULL == sub_attr){ - cred->subject_attribute = '\0'; - cred->subject_attribute_len = 0; + dele->subject_attribute = NULL; + dele->subject_attribute_len = 0; } else { - cred->subject_attribute = strdup(sub_attr); - cred->subject_attribute_len = strlen(sub_attr); + dele->subject_attribute = (char*)&dele[1] + strlen(iss_attr) + 1; + dele->subject_attribute_len = strlen(sub_attr); } - GNUNET_memcpy (&cred[1], - tmp_str, - attr_len); + GNUNET_free (del); + return dele; - GNUNET_free (crd); - return cred; + // Entweder: strdup und destroy (free auf die subjct_attribute/issuer_attribute) + // oder: pointer auf cred[1], aber nach jedem string im combined string ein EOS <- besser + // function comment: cred must be freed by caller, (add missing sub_iss) } diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c index 22fca7b00..3d20e7082 100644 --- a/src/credential/gnunet-credential.c +++ b/src/credential/gnunet-credential.c @@ -150,7 +150,7 @@ static int sign_ss; /** * Signed issue credentials */ -static char *extension; +static char *import; /** * Queue entry for the 'add' operation. @@ -186,6 +186,16 @@ static uint64_t etime; */ static int etime_is_rel = GNUNET_SYSERR; +/** + * Fixed size of the public/private keys + */ +static const int key_length = 52; + +/** + * Record label for storing delegations + */ +static char *record_label; + /** * Task run on shutdown. Cleans up everything. * @@ -332,7 +342,7 @@ identity_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) { const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; - struct GNUNET_CREDENTIAL_Credential *crd; + struct GNUNET_CREDENTIAL_Credential *cred; struct GNUNET_TIME_Absolute etime_abs; struct GNUNET_TIME_Relative etime_rel; char *res; @@ -400,47 +410,17 @@ identity_cb (void *cls, privkey = GNUNET_IDENTITY_ego_get_private_key (ego); GNUNET_free_non_null (ego_name); ego_name = NULL; - crd = GNUNET_CREDENTIAL_credential_issue (privkey, + cred = GNUNET_CREDENTIAL_credential_issue (privkey, &subject_pkey, issuer_attr, &etime_abs); - res = GNUNET_CREDENTIAL_credential_to_string (crd); - GNUNET_free (crd); + res = GNUNET_CREDENTIAL_credential_to_string (cred); + GNUNET_free (cred); printf ("%s\n", res); GNUNET_SCHEDULER_shutdown (); } -static int -parse_cmdl_param(const char *extensionstring) -{ - char *token; - char *tmp_str; - int counter = 0; - - tmp_str = GNUNET_strdup (extensionstring); - // split string via strtok, assume parameters are in the right order - token = strtok (tmp_str, ";"); - while (NULL != token) { - - // fill variables depending on counter - if(0 == counter) { - expiration = GNUNET_strdup(token); - } else if(1 == counter) { - extension = GNUNET_strdup(token); - } else { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not parse extension string\n"); - } - - counter++; - token = strtok (NULL, ";"); - } - GNUNET_free (tmp_str); - - //return GNUNET_SYSERR; - return GNUNET_OK; -} - /** * Parse expiration time. * @@ -573,55 +553,71 @@ store_cb (void *cls, // Key handling zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); - // Check relevant cmdline parameters - if (NULL == issuer_attr) - { - fprintf (stderr, "Missing option -attribute for operation 'create'.\n"); - GNUNET_SCHEDULER_shutdown (); - return; - } + // TODO maybe dont have to set subject, if only used in if/else can use import here instead!! + if( GNUNET_GNSRECORD_TYPE_DELEGATE == type){ + // Parse import + struct GNUNET_CREDENTIAL_Delegate *cred; + cred = GNUNET_CREDENTIAL_delegate_from_string (import); - if (NULL == subject) - { - fprintf (stderr, "Missing option -subject for operation 'create'.'\n"); - GNUNET_SCHEDULER_shutdown (); - return; - } + // Get import subject public key string + char *subject_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&cred->subject_key); - // String to value conversion for storage - if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, + // Get zone public key string + struct GNUNET_CRYPTO_EcdsaPublicKey zone_pubkey; + GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey); + char *zone_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&zone_pubkey); + + // Check if the subject key in the signed import matches the zone's key it is issued to + if(strcmp(zone_pubkey_str, subject_pubkey_str) != 0) + { + fprintf (stderr, "Import signed delegate does not match this ego's public key.\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + + // Expiration + etime = cred->expiration.abs_value_us; + etime_is_rel = GNUNET_NO; + + // Prepare the data to be store in the record + data_size = GNUNET_CREDENTIAL_delegate_serialize (cred, (char **)&data); + GNUNET_free(cred); + } else { + // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE + if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, subject, &data, &data_size)) - { - fprintf (stderr, "Value `%s' invalid for record type `%s'\n", - subject, - typestring); - GNUNET_SCHEDULER_shutdown (); - return; - } + { + fprintf (stderr, "Value `%s' invalid for record type `%s'\n", + subject, + typestring); + GNUNET_SCHEDULER_shutdown (); + return; + } - // 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; + // 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, + record_label, &error_cb, NULL, &get_existing_record, @@ -634,9 +630,8 @@ sign_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) { const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; - struct GNUNET_CREDENTIAL_Delegate *crd; + struct GNUNET_CREDENTIAL_Delegate *dele; struct GNUNET_TIME_Absolute etime_abs; - struct GNUNET_TIME_Relative etime_rel; char *res; el = NULL; @@ -647,43 +642,33 @@ sign_cb (void *cls, 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); + fprintf (stderr, "%s is not a valid ttl! Only absolute times are accepted!\n", expiration); GNUNET_SCHEDULER_shutdown (); return; } - // if contains a space - split it by the first space only - assume first entry is subject followed by attribute(s) - char *space; - int idx; + // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s) char *subject_pubkey_str; - char *subject_attr; + char *subject_attr = NULL; + char *token; - space = strchr(subject, ' '); - if(NULL == space) + // Subject Public Key + token = strtok (subject, " "); + if (key_length == strlen(token)) { - // only contains subject key e.g. A.a <- B - subject_pubkey_str = subject; - subject_attr = '\0'; + subject_pubkey_str = token; } else { - // subject contains: key attr1.attr2.attr3... - // split subject into subject_pubkey_str and subject_attr - idx = (int)(space - subject); - - subject_pubkey_str = GNUNET_malloc(idx+1); - GNUNET_memcpy(subject_pubkey_str, subject, idx); - subject_pubkey_str[idx] = '\0'; - - int sub_attr_len = strlen(subject) - idx - 1; - // +1 for the \0 - subject_attr = GNUNET_malloc(sub_attr_len + 1); - // +1 to remove the space "key attr" (or whatever separator) - GNUNET_memcpy(subject_attr, subject + idx + 1, sub_attr_len); - subject_attr[sub_attr_len] = '\0'; + fprintf (stderr, "Key error, wrong length: %ld!\n", strlen(token)); + GNUNET_SCHEDULER_shutdown (); + return; + } + // Subject Attribute(s) + token = strtok (NULL, " "); + if(NULL != token) + { + subject_attr = token; } // work on keys @@ -699,14 +684,14 @@ sign_cb (void *cls, } // Sign delegate - crd = GNUNET_CREDENTIAL_delegate_issue (privkey, + dele = GNUNET_CREDENTIAL_delegate_issue (privkey, &subject_pkey, issuer_attr, subject_attr, &etime_abs); - res = GNUNET_CREDENTIAL_delegate_to_string (crd); - GNUNET_free (crd); - printf ("%s;%s\n", expiration, res); + res = GNUNET_CREDENTIAL_delegate_to_string (dele); + GNUNET_free (dele); + printf ("%s\n", res); GNUNET_free_non_null (ego_name); ego_name = NULL; @@ -728,22 +713,34 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - cfg = c; tt = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL); GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); + // Check relevant cmdline parameters if (GNUNET_YES == create_is) { if (NULL == ego_name) { - fprintf (stderr, "ego required\n"); + fprintf (stderr, "Missing option '-ego'\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (NULL == issuer_attr) { + fprintf (stderr, "Missing option '-attribute' for issuer attribute\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (NULL == subject) + { + fprintf (stderr, "Missing option -subject for operation 'create'.'\n"); GNUNET_SCHEDULER_shutdown (); return; } // Lookup ego, on success call store_cb and store as ATTRIBUTE type type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE; + record_label = issuer_attr; el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, @@ -753,18 +750,14 @@ run (void *cls, if (GNUNET_YES == create_ss) { // check if signed parameter has been passed in cmd line call - if (NULL == extension) { - fprintf (stderr, "'extension' required\n"); + if (NULL == import) { + fprintf (stderr, "'import' required\n"); GNUNET_SCHEDULER_shutdown (); return; } - // parses all the passed parameters - parse_cmdl_param(extension); - type = GNUNET_GNSRECORD_TYPE_DELEGATE; - subject = extension; - issuer_attr = GNUNET_GNS_EMPTY_LABEL_AT; + record_label = GNUNET_GNS_EMPTY_LABEL_AT; // Store subject side el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, @@ -1008,7 +1001,7 @@ main (int argc, char *const *argv) GNUNET_GETOPT_option_string ('T', "ttl", "EXP", - gettext_noop ("The time to live for the credential"), + gettext_noop ("The time to live for the credential. e.g. 5m, 6h, \"1990-12-30 12:00:00\""), &expiration), GNUNET_GETOPT_option_flag ('g', "collect", @@ -1027,10 +1020,10 @@ main (int argc, char *const *argv) gettext_noop ("Create, sign and return a credential subject side."), &sign_ss), GNUNET_GETOPT_option_string ('x', - "extension", - "EXT", - gettext_noop ("Signed credentials that should be issued to a zone/ego"), - &extension), + "import", + "IMP", + gettext_noop ("Import signed credentials that should be issued to a zone/ego"), + &import), GNUNET_GETOPT_OPTION_END }; int ret; diff --git a/src/credential/test_credential_own.sh b/src/credential/test_credential_own.sh index d10d1b2ea..b53825d1b 100755 --- a/src/credential/test_credential_own.sh +++ b/src/credential/test_credential_own.sh @@ -49,17 +49,17 @@ gnunet-credential --createIssuerSide --ego=epub --attribute="issside" --subject= gnunet-namestore -D -z epub # Own subject side storage: -SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY" --ttl=5m` -gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" +SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY" --ttl="2019-12-12 10:00:00"` +gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED" -SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno" --ttl=5m` -gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" +SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno" --ttl="2019-12-12 10:00:00"` +gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED" -SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno.pqr" --ttl=5m` -gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" +SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno.pqr" --ttl="2019-12-12 10:00:00"` +gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED" -SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd.stu" --subject="$EORG_KEY efghijklmno.pqr" --ttl=5m` -gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" +SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd.stu" --subject="$EORG_KEY efghijklmno.pqr" --ttl="2019-12-12 10:00:00"` +gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED" gnunet-namestore -D -z eorg diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h index 6801c641e..1d6d5a229 100644 --- a/src/include/gnunet_signatures.h +++ b/src/include/gnunet_signatures.h @@ -241,6 +241,10 @@ extern "C" */ #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 37 +/** + * Signature for a GNUnet delegate + */ +#define GNUNET_SIGNATURE_PURPOSE_DELEGATE 38 #if 0 /* keep Emacsens' auto-indent happy */ { -- cgit v1.2.3