From fc58d9d4241ed2dcd4b492b4f922ba959449a697 Mon Sep 17 00:00:00 2001 From: Andreas Ebner Date: Sun, 7 Jul 2019 15:04:40 +0200 Subject: Implemented delegate sign and store function for GNS entries: - functions to store and sign delegates (all types) including serialization/string_to_value/.. - solved (almost) all TODOs - some renaming and cleanup in gnunet-credential.c - valgrind checked - test file adapted accordingly --- src/credential/Makefile.am | 6 +- src/credential/credential_api.c | 1 + src/credential/credential_serialization.c | 118 +++++++++++++ src/credential/credential_serialization.h | 8 + src/credential/delegate.h | 79 +++++++++ src/credential/delegate_misc.c | 250 ++++++++++++++++++++++++++ src/credential/delegate_misc.h | 36 ++++ src/credential/gnunet-credential.c | 254 ++++++++------------------- src/credential/plugin_gnsrecord_credential.c | 125 ++----------- src/credential/test_credential_own.sh | 34 ++-- src/include/gnunet_credential_service.h | 62 +++++++ 11 files changed, 661 insertions(+), 312 deletions(-) create mode 100644 src/credential/delegate.h create mode 100644 src/credential/delegate_misc.c create mode 100644 src/credential/delegate_misc.h (limited to 'src') diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am index 5b14b3def..7d9ab4bea 100644 --- a/src/credential/Makefile.am +++ b/src/credential/Makefile.am @@ -69,11 +69,13 @@ gnunet_service_credential_LDADD = \ libgnunetcredential_la_SOURCES = \ - credential_api.c credential.h \ + credential_api.c credential.h deleagte.h\ credential_serialization.c \ credential_serialization.h \ credential_misc.c \ - credential_misc.h + credential_misc.h \ + delegate_misc.c \ + delegate_misc.h libgnunetcredential_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la $(XLIB) libgnunetcredential_la_LDFLAGS = \ diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c index 3cbaf6c21..be5ff25ae 100644 --- a/src/credential/credential_api.c +++ b/src/credential/credential_api.c @@ -30,6 +30,7 @@ #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 40fa112dd..95b29a49c 100644 --- a/src/credential/credential_serialization.c +++ b/src/credential/credential_serialization.c @@ -31,6 +31,7 @@ #include "gnunet_credential_service.h" #include "gnunet_signatures.h" #include "credential.h" +#include "delegate.h" /** * Calculate how many bytes we will need to serialize @@ -402,6 +403,7 @@ GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len, c_count, cd); } + int GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred, @@ -475,5 +477,121 @@ GNUNET_CREDENTIAL_credential_deserialize (const char*data, return cred; } +//TODO own file for delegate de/serialization + +int +GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred, + char **data) +{ + size_t size; + struct DelegateEntry *cdata; + int attr_len; + + // +1 for \0 + if (0 == cred->subject_attribute_len){ + attr_len = cred->issuer_attribute_len + 1; + } else { + attr_len = cred->issuer_attribute_len + cred->subject_attribute_len + 1; + } + 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); + } + 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_attribute_len = htonl (0); + } else { + cdata->subject_attribute_len = htonl (cred->subject_attribute_len + 1); + } + cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); + 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, + &cdata->purpose, + &cdata->signature, + &cdata->issuer_key)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n"); + //return NULL; + } + return size; +} + +struct GNUNET_CREDENTIAL_Delegate* +GNUNET_CREDENTIAL_delegate_deserialize (const char* data, + size_t data_size) +{ + struct GNUNET_CREDENTIAL_Delegate *cred; + 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, + &cdata->purpose, + &cdata->signature, + &cdata->issuer_key)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n"); + //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], + attr_combo_str, + attr_combo_len); + cred->signature = cdata->signature; + + // Parse the combo attribute string, split into issuer and subject + 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; + } 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); + } + + cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration); + + return cred; +} /* end of credential_serialization.c */ diff --git a/src/credential/credential_serialization.h b/src/credential/credential_serialization.h index 65326de31..ebeae0d89 100644 --- a/src/credential/credential_serialization.h +++ b/src/credential/credential_serialization.h @@ -169,5 +169,13 @@ GNUNET_CREDENTIAL_credential_serialize (struct struct GNUNET_CREDENTIAL_Credential* GNUNET_CREDENTIAL_credential_deserialize (const char*data, size_t data_size); + +int +GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred, + char **data); + +struct GNUNET_CREDENTIAL_Delegate* +GNUNET_CREDENTIAL_delegate_deserialize (const char* data, + size_t data_size); #endif /* end of credential_serialization.h */ diff --git a/src/credential/delegate.h b/src/credential/delegate.h new file mode 100644 index 000000000..e1bf112ef --- /dev/null +++ b/src/credential/delegate.h @@ -0,0 +1,79 @@ +/* + 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 new file mode 100644 index 000000000..d900ccd1f --- /dev/null +++ b/src/credential/delegate_misc.c @@ -0,0 +1,250 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013, 2016 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_misc.c + * @brief Misc API for delegate + * + * @author Martin Schanzenbach + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_constants.h" +#include "gnunet_credential_service.h" +#include "gnunet_signatures.h" +#include "delegate.h" +#include + +char* +GNUNET_CREDENTIAL_delegate_to_string (const struct GNUNET_CREDENTIAL_Delegate *cred) +{ + char *cred_str; + char *subject_pkey; + char *issuer_pkey; + char *signature; + + subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); + issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key); + GNUNET_STRINGS_base64_encode ((char*)&cred->signature, + sizeof (struct GNUNET_CRYPTO_EcdsaSignature), + &signature); + if(0 == cred->subject_attribute_len){ + GNUNET_asprintf (&cred_str, + "%s.%s -> %s | %s | %"SCNu64, + issuer_pkey, + cred->issuer_attribute, + subject_pkey, + signature, + cred->expiration.abs_value_us); + } else { + GNUNET_asprintf (&cred_str, + "%s.%s -> %s.%s | %s | %"SCNu64, + issuer_pkey, + cred->issuer_attribute, + subject_pkey, + cred->subject_attribute, + signature, + cred->expiration.abs_value_us); + } + GNUNET_free (subject_pkey); + GNUNET_free (issuer_pkey); + GNUNET_free (signature); + + return cred_str; +} + +struct GNUNET_CREDENTIAL_Delegate* +GNUNET_CREDENTIAL_delegate_from_string (const char* s) +{ + struct GNUNET_CREDENTIAL_Delegate *cred; + size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; + if (enclen % 5 > 0) + enclen += 5 - enclen % 5; + enclen /= 5; /* 260/5 = 52 */ + char subject_pkey[enclen + 1]; + char issuer_pkey[enclen + 1]; + char iss_attr[253 + 1]; + // Needs to be initialized, in case of Type 1 credential (A.a <- B) + char sub_attr[253 + 1] = ""; + char signature[256]; //TODO max payload size + + struct GNUNET_CRYPTO_EcdsaSignature *sig; + struct GNUNET_TIME_Absolute etime_abs; + + // If it's A.a <- B.b... + if (6 != SSCANF (s, + "%52s.%253s -> %52s.%253s | %s | %"SCNu64, + issuer_pkey, + iss_attr, + subject_pkey, + sub_attr, + signature, + &etime_abs.abs_value_us)) + { + // Try if it's A.a <- B + if (5 != SSCANF (s, + "%52s.%253s -> %52s | %s | %"SCNu64, + issuer_pkey, + iss_attr, + subject_pkey, + signature, + &etime_abs.abs_value_us)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to parse DEL record string `%s'\n", s); + return NULL; + } + } + + // +1 for \0 + int attr_len; + if(strcmp(sub_attr,"") == 0) { + attr_len = strlen (iss_attr) + 1; + } else { + attr_len = strlen (iss_attr) + strlen(sub_attr) + 1; + } + cred = 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[attr_len - 1] = '\0'; + + GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, + strlen (subject_pkey), + &cred->subject_key); + GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey, + strlen (issuer_pkey), + &cred->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; + GNUNET_free (sig); + GNUNET_memcpy (&cred[1], + tmp_str, + attr_len); + + cred->issuer_attribute_len = strlen (iss_attr); + cred->issuer_attribute = strdup(iss_attr); + if(strcmp(sub_attr,"") == 0) { + cred->subject_attribute_len = 0; + cred->subject_attribute = '\0'; + } else { + cred->subject_attribute_len = strlen (sub_attr); + cred->subject_attribute = strdup(sub_attr); + } + + return cred; +} + +/** + * Issue an attribute to a subject + * + * @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 + * @return handle to the queued request + */ + +struct GNUNET_CREDENTIAL_Delegate * +GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, + struct GNUNET_CRYPTO_EcdsaPublicKey *subject, + const char *iss_attr, + const char *sub_attr, + struct GNUNET_TIME_Absolute *expiration) +{ + struct DelegateEntry *crd; + struct GNUNET_CREDENTIAL_Delegate *cred; + size_t size; + int attr_len; + + if (NULL == sub_attr){ + // +1 for \0 + attr_len = strlen (iss_attr) + 1; + } else { + attr_len = strlen (iss_attr) + strlen(sub_attr) + 1; + } + 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[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); + 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); + if (NULL == sub_attr){ + crd->subject_attribute_len = htonl (0); + } else { + crd->subject_attribute_len = htonl (strlen (sub_attr) + 1); + } + + GNUNET_memcpy (&crd[1], + tmp_str, + attr_len); + + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_sign (issuer, + &crd->purpose, + &crd->signature)) + { + GNUNET_break (0); + GNUNET_free (crd); + return NULL; + } + + cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len); + cred->signature = crd->signature; + cred->expiration = *expiration; + GNUNET_CRYPTO_ecdsa_key_get_public (issuer, + &cred->issuer_key); + + cred->subject_key = *subject; + cred->issuer_attribute = strdup(iss_attr); + cred->issuer_attribute_len = strlen(iss_attr); + if (NULL == sub_attr){ + cred->subject_attribute = '\0'; + cred->subject_attribute_len = 0; + } else { + cred->subject_attribute = strdup(sub_attr); + cred->subject_attribute_len = strlen(sub_attr); + } + + GNUNET_memcpy (&cred[1], + tmp_str, + attr_len); + + GNUNET_free (crd); + return cred; +} + + diff --git a/src/credential/delegate_misc.h b/src/credential/delegate_misc.h new file mode 100644 index 000000000..936517437 --- /dev/null +++ b/src/credential/delegate_misc.h @@ -0,0 +1,36 @@ +/* + 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_misc.h + * @brief Delegate helper functions + */ +#ifndef DELEGATE_MISC_H +#define DELEGATE_MISC_H + +#include "gnunet_credential_service.h" + +char * +GNUNET_CREDENTIAL_delegate_to_string ( + const struct GNUNET_CREDENTIAL_Delegate *cred); + +struct GNUNET_CREDENTIAL_Delegate * +GNUNET_CREDENTIAL_delegate_from_string (const char *str); + +#endif diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c index 35fa6ff8a..22fca7b00 100644 --- a/src/credential/gnunet-credential.c +++ b/src/credential/gnunet-credential.c @@ -28,6 +28,7 @@ #include #include #include "credential_misc.h" +#include "delegate_misc.h" #include "credential_serialization.h" /** @@ -78,7 +79,7 @@ static struct GNUNET_SCHEDULER_Task *tt; /** * Subject pubkey string */ -static char *subject_key; +static char *subject; /** * Subject credential string @@ -146,11 +147,6 @@ static int create_ss; */ static int sign_ss; -/** - * Add mode - */ -static int add_iss; - /** * Signed issue credentials */ @@ -291,6 +287,7 @@ handle_verify_result (void *cls, { iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].issuer_key); sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].subject_key); + if (0 != dc[i].subject_attribute_len) { printf ("(%d) %s.%s <- %s.%s\n", i, @@ -409,108 +406,34 @@ identity_cb (void *cls, &etime_abs); res = GNUNET_CREDENTIAL_credential_to_string (crd); - fprintf(stderr,"Cred: %s\n", res); GNUNET_free (crd); printf ("%s\n", res); GNUNET_SCHEDULER_shutdown (); } - -static char -*strtokm(char *str, const char *delim) -{ - static char *tok; - static char *next; - char *m; - - if (delim == NULL) return NULL; - - tok = (str) ? str : next; - if (tok == NULL) return NULL; - - m = strstr(tok, delim); - - if (m) { - next = m + strlen(delim); - *m = '\0'; - } else { - next = NULL; - } - - if (m == tok || *tok == '\0') return strtokm(NULL, delim); - - return tok; -} - -void topntail(char *str) { - size_t len = strlen(str); - // check if last char is a space, if yes: remove 2 chars at the end - if(str[len-1] == ' ') - { - len -= 1; - } - // remove first and last char - memmove(str, str+1, len-2); - str[len-2] = 0; -} - static int parse_cmdl_param(const char *extensionstring) { - fprintf(stderr, "Starting to parse extension string...\n"); - fprintf(stderr, "string to parse: %s\n", extensionstring); - - //Example: - //--ego=epub --attribute=aasds --subject=DKCC5SMTBNV6W3VXDJ7A1N1YS6TRG7B3XC2S5N4HSXJEYYRFRCCG basd --ttl=60m - //--extension=NVTQZA44336VHKCP2SA20BR6899T621B2PJKC3V730AKXC37T6M0.aasds -> DKCC5SMTBNV6W3VXDJ7A1N1YS6TRG7B3XC2S5N4HSXJEYYRFRCCG | D1NuT8hHEUbkCURo1lkcSPKhYiydhv4nMkV042kc9J4MgIhB2/fQKLgJUyuGlJKvYgXLf4jHXNRHJe+aCLG7jw== | 1561126006528100 - - //TODO: parse, wenn nicht als argument direkt geparsed werden kann - - char cmd_para[100]; - char para_str[1024]; char *token; char *tmp_str; - int matches = 0; + int counter = 0; tmp_str = GNUNET_strdup (extensionstring); - // use special strtok to match multiple characters - token = strtokm (tmp_str, "--"); + // split string via strtok, assume parameters are in the right order + token = strtok (tmp_str, ";"); while (NULL != token) { - // also fills the variables if "regex"-like match - fprintf(stderr, "TOKEN: %s\n", token); - // match everything till =, ignore = (%*c), match everything including whitespaces (required for the extension parameter) - matches = SSCANF (token, "%[^=]%*c%[^\n]", cmd_para, para_str); - // string not well formatted - if (0 == matches) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ("Failed to parse to extensionstring.\n")); - GNUNET_SCHEDULER_shutdown (); - GNUNET_free (tmp_str); - return GNUNET_SYSERR; + + // fill variables depending on counter + if(0 == counter) { + expiration = GNUNET_strdup(token); + } else if(1 == counter) { + extension = GNUNET_strdup(token); } else { - fprintf(stderr,"Found command and parameter: %s %s\n", cmd_para, para_str); - // assign values to variables, topntail to remove trailing/leading " - if(strcmp(cmd_para, "ego") == 0) { - fprintf(stderr,"ego found and parsed\n"); - topntail(para_str); - ego_name = GNUNET_strdup(para_str); - } else if(strcmp(cmd_para, "attribute") == 0) { - fprintf(stderr,"issuer found and parsed\n"); - topntail(para_str); - issuer_attr = GNUNET_strdup(para_str); - } else if(strcmp(cmd_para, "subject") == 0) { - fprintf(stderr,"subject found and parsed\n"); - topntail(para_str); - subject_key = GNUNET_strdup(para_str); - } else if(strcmp(cmd_para, "ttl") == 0) { - fprintf(stderr,"ttl found and parsed\n"); - expiration = GNUNET_strdup(para_str); - } else if(strcmp(cmd_para, "extension") == 0) { - fprintf(stderr,"extension found and parsed\n"); - topntail(para_str); - extension = GNUNET_strdup(para_str); - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not parse extension string\n"); } - token = strtokm (NULL, "--"); + + counter++; + token = strtok (NULL, ";"); } GNUNET_free (tmp_str); @@ -531,7 +454,7 @@ parse_expiration (const char *expirationstring, int *etime_is_rel, uint64_t *etime) { - // TODO just copied from gnunet-namestore.c + // copied from namestore/gnunet-namestore.c struct GNUNET_TIME_Relative etime_rel; struct GNUNET_TIME_Absolute etime_abs; @@ -574,8 +497,7 @@ parse_expiration (const char *expirationstring, static void error_cb (void *cls) { - // TODO: Better - fprintf(stderr, "In add_error_cb\n"); + fprintf(stderr, "Error occured during lookup, shutting down.\n"); GNUNET_SCHEDULER_shutdown (); return; } @@ -584,8 +506,7 @@ add_continuation (void *cls, int32_t success, const char *emsg) { - fprintf(stderr, "Start: add_continuation\n"); - + // TODO what does that do, can I somehow parse an empty callback on success or do I have to set the qe* to NULL? struct GNUNET_NAMESTORE_QueueEntry **qe = cls; *qe = NULL; @@ -602,11 +523,6 @@ get_existing_record (void *cls, struct GNUNET_GNSRECORD_Data rdn[rd_count + 1]; struct GNUNET_GNSRECORD_Data *rde; - fprintf(stderr, "Start: get_existing_record\n"); - - fprintf(stderr, "count: %d\n", rd_count); - - memset (rdn, 0, sizeof (struct GNUNET_GNSRECORD_Data)); GNUNET_memcpy (&rdn[1], rd, @@ -615,7 +531,7 @@ get_existing_record (void *cls, rde->data = data; rde->data_size = data_size; rde->record_type = type; - // TODO: flags + // Flags not required , TODO what have we said we do with that now? Look it up in my writing /*if (1 == is_shadow) rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; if (1 != is_public) @@ -642,9 +558,8 @@ store_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; - fprintf(stderr, "Start: store_cb\n"); + el = NULL; ns = GNUNET_NAMESTORE_connect (cfg); if (NULL == ns) @@ -656,14 +571,9 @@ store_cb (void *cls, } // Key handling - fprintf(stderr, "Connected to ns\n"); zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); - fprintf(stderr, "Got zone_pkey\n"); - // TODO rename to zone_pub? - GNUNET_CRYPTO_ecdsa_key_get_public (&zone_pkey, &pub); // Check relevant cmdline parameters - // name ⁼ issuer_attr if (NULL == issuer_attr) { fprintf (stderr, "Missing option -attribute for operation 'create'.\n"); @@ -671,9 +581,7 @@ store_cb (void *cls, return; } - // TODO later, rename subject_key to subject - // value ⁼ subject_key - if (NULL == subject_key) + if (NULL == subject) { fprintf (stderr, "Missing option -subject for operation 'create'.'\n"); GNUNET_SCHEDULER_shutdown (); @@ -682,20 +590,18 @@ store_cb (void *cls, // String to value conversion for storage if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, - subject_key, + subject, &data, &data_size)) { fprintf (stderr, "Value `%s' invalid for record type `%s'\n", - subject_key, + subject, typestring); GNUNET_SCHEDULER_shutdown (); return; } - fprintf (stderr, "Data size: `%lu'\n", data_size); // Take care of expiration - if (NULL == expiration) { fprintf (stderr, "Missing option -e for operation 'create'\n"); @@ -728,13 +634,12 @@ sign_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego) { const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; - struct GNUNET_CREDENTIAL_Credential *crd; + struct GNUNET_CREDENTIAL_Delegate *crd; struct GNUNET_TIME_Absolute etime_abs; struct GNUNET_TIME_Relative etime_rel; char *res; el = NULL; - // work on expiration time if (NULL == expiration) @@ -752,19 +657,34 @@ sign_cb (void *cls, return; } - // if contains a space - split it by the first space only - assume first token entry is subject_key - fprintf (stderr, "Start splitting\n"); + // if contains a space - split it by the first space only - assume first entry is subject followed by attribute(s) char *space; int idx; - space = strchr(subject_key, ' '); - idx = (int)(space - subject_key); + char *subject_pubkey_str; + char *subject_attr; - // TODO rename subject_key to subject - char *subject_pubkey_str = GNUNET_malloc(idx+1); - GNUNET_memcpy(subject_pubkey_str, subject_key, idx); - subject_pubkey_str[idx] = '\0'; - - fprintf(stderr, "idx: %d, str: %s\n", idx, subject_pubkey_str); + space = strchr(subject, ' '); + if(NULL == space) + { + // only contains subject key e.g. A.a <- B + subject_pubkey_str = subject; + subject_attr = '\0'; + } 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'; + } // work on keys privkey = GNUNET_IDENTITY_ego_get_private_key (ego); @@ -778,18 +698,15 @@ sign_cb (void *cls, return; } - // Sign credential / TODO not credential but delegate (new method), not only pass subject_pkey but also subject_attr - // gnunet-credential --issue --ego=registrarb --subject=$ALICE_KEY --attribute=$REG_STUD_ATTR --ttl=5m -c test_credential_lookup.conf - // gnunet-credential --create --ego=epub --attribute="a" --subject="B b" --where="ss" -E 60m - // TODO: only signs subject_pkey at the moment, also requires subject_attr (or both in subject_key) - crd = GNUNET_CREDENTIAL_credential_issue (privkey, + // Sign delegate + crd = GNUNET_CREDENTIAL_delegate_issue (privkey, &subject_pkey, issuer_attr, + subject_attr, &etime_abs); - res = GNUNET_CREDENTIAL_credential_to_string (crd); - fprintf(stderr,"Dele: %s\n", res); + res = GNUNET_CREDENTIAL_delegate_to_string (crd); GNUNET_free (crd); - printf ("--ego=\"%s\" --attribute=\"%s\" --subject=\"%s\" --ttl=%s --extension=\"%s\"\n", ego_name, issuer_attr, subject_key, expiration, res); + printf ("%s;%s\n", expiration, res); GNUNET_free_non_null (ego_name); ego_name = NULL; @@ -819,18 +736,14 @@ run (void *cls, GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); if (GNUNET_YES == create_is) { - fprintf(stderr, "Starting to create issuer side...\n"); - if (NULL == ego_name) { fprintf (stderr, "ego required\n"); GNUNET_SCHEDULER_shutdown (); return; } + // Lookup ego, on success call store_cb and store as ATTRIBUTE type type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE; - //TODO: Store normally (at issuer, for backward search) - // stuff from gnunet-namestore.c of namestore folder - fprintf (stderr, "Start: Store issuer side\n"); el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, @@ -839,8 +752,7 @@ run (void *cls, } if (GNUNET_YES == create_ss) { - fprintf(stderr, "Starting to create subject side...\n"); - // check if "credential"/signed parameter filled + // check if signed parameter has been passed in cmd line call if (NULL == extension) { fprintf (stderr, "'extension' required\n"); GNUNET_SCHEDULER_shutdown (); @@ -850,19 +762,10 @@ run (void *cls, // parses all the passed parameters parse_cmdl_param(extension); - fprintf (stderr,"List of parsed attributes:\n"); - fprintf (stderr,"Ego: %s\n", ego_name); - fprintf (stderr,"Attribute: %s\n", issuer_attr); - fprintf (stderr,"Subject: %s\n", subject_key); - fprintf (stderr,"ttl: %s\n", expiration); - fprintf (stderr,"Extension: %s\n", extension); - - //TODO: subject key does not have to be returned, extension replaces it - //TODO: use own delegation type, implement string_to_value and value_to_string methods of plugin - //type = GNUNET_GNSRECORD_TYPE_DELEGATE; - type = GNUNET_GNSRECORD_TYPE_CREDENTIAL; - subject_key = extension; - fprintf (stderr, "Start: Store subject side\n"); + type = GNUNET_GNSRECORD_TYPE_DELEGATE; + subject = extension; + issuer_attr = GNUNET_GNS_EMPTY_LABEL_AT; + // Store subject side el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, @@ -872,26 +775,19 @@ run (void *cls, } if (GNUNET_YES == sign_ss) { - fprintf(stderr, "Starting to sign subject side...\n"); - if (NULL == ego_name) { fprintf (stderr, "ego required\n"); GNUNET_SCHEDULER_shutdown (); return; } - - if (NULL == subject_key) + if (NULL == subject) { fprintf (stderr, "Subject public key needed\n"); GNUNET_SCHEDULER_shutdown (); return; - } - //TODO: Sign like credential and return to store subject side - //TODO: Return everything as an input for the add - //TODO: Idee: Gleich add machen, statt return und neues add - fprintf (stderr, "Start: Sign, return and subject side store\n"); + // lookup ego and call function sign_cb on success el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &sign_cb, @@ -940,7 +836,7 @@ run (void *cls, } - if (NULL == subject_key) + if (NULL == subject) { fprintf (stderr, _("Subject public key needed\n")); @@ -949,13 +845,13 @@ run (void *cls, } if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key, - strlen (subject_key), + GNUNET_CRYPTO_ecdsa_public_key_from_string (subject, + strlen (subject), &subject_pkey)) { fprintf (stderr, _("Subject public key `%s' is not well-formed\n"), - subject_key); + subject); GNUNET_SCHEDULER_shutdown (); return; } @@ -1061,7 +957,6 @@ run (void *cls, _("Please specify name to lookup, subject key and issuer key!\n")); GNUNET_SCHEDULER_shutdown (); } - fprintf (stderr, "In the end it doesnt even shutdown\n"); return; } @@ -1088,8 +983,8 @@ main (int argc, char *const *argv) GNUNET_GETOPT_option_string ('s', "subject", "PKEY", - gettext_noop ("The public key of the subject to lookup the credential for"), - &subject_key), + gettext_noop ("The public key of the subject to lookup the credential for, or for issuer side storage: subject and its attributes"), + &subject), GNUNET_GETOPT_option_string ('b', "credential", "CRED", @@ -1103,7 +998,7 @@ main (int argc, char *const *argv) GNUNET_GETOPT_option_string ('e', "ego", "EGO", - gettext_noop ("The ego to use"), + gettext_noop ("The ego/zone name to use"), &ego_name), GNUNET_GETOPT_option_string ('a', "attribute", @@ -1119,10 +1014,9 @@ main (int argc, char *const *argv) "collect", gettext_noop ("collect credentials"), &collect), - GNUNET_GETOPT_option_flag ('U', "createIssuerSide", - gettext_noop ("TODO: rename create to --issue, Create and issue a credential issuer side."), + gettext_noop ("Create and issue a credential issuer side."), &create_is), GNUNET_GETOPT_option_flag ('C', "createSubjectSide", @@ -1132,14 +1026,10 @@ main (int argc, char *const *argv) "signSubjectSide", gettext_noop ("Create, sign and return a credential subject side."), &sign_ss), - GNUNET_GETOPT_option_flag ('A', - "add", - gettext_noop ("Add credential to the namestore of an ego"), - &add_iss), GNUNET_GETOPT_option_string ('x', "extension", "EXT", - gettext_noop ("Signed issue credentials"), + gettext_noop ("Signed credentials that should be issued to a zone/ego"), &extension), GNUNET_GETOPT_OPTION_END }; diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c index a4c3a94e8..f2fb0b1a6 100644 --- a/src/credential/plugin_gnsrecord_credential.c +++ b/src/credential/plugin_gnsrecord_credential.c @@ -28,6 +28,7 @@ #include "gnunet_util_lib.h" #include "credential_misc.h" +#include "delegate_misc.h" #include "credential_serialization.h" #include "gnunet_credential_service.h" #include "gnunet_gnsrecord_lib.h" @@ -46,7 +47,6 @@ static char * credential_value_to_string (void *cls, uint32_t type, const void *data, size_t data_size) { - const char *cdata; switch (type) { @@ -94,8 +94,6 @@ credential_value_to_string (void *cls, uint32_t type, const void *data, } GNUNET_free (subject_pkey); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "############### attr str: %s \n", attr_str); - //DEBUG ############### attr str: BKX50FK9QYNTFGPR6647CDASM63G21NEJC02QP58NHN7B7M8TKT0 student return attr_str; } case GNUNET_GNSRECORD_TYPE_CREDENTIAL: { @@ -107,10 +105,14 @@ credential_value_to_string (void *cls, uint32_t type, const void *data, GNUNET_free (cred); return cred_str; } - case GNUNET_GNSRECORD_TYPE_DELEGATE: { - printf("####################################vts\n"); - - return GNUNET_strndup (data, data_size); + case GNUNET_GNSRECORD_TYPE_DELEGATE: { + struct GNUNET_CREDENTIAL_Delegate *cred; + char *cred_str; + + cred = GNUNET_CREDENTIAL_delegate_deserialize (data, data_size); + cred_str = GNUNET_CREDENTIAL_delegate_to_string (cred); + GNUNET_free (cred); + return cred_str; } default: return NULL; @@ -137,8 +139,6 @@ credential_string_to_value (void *cls, uint32_t type, const char *s, return GNUNET_SYSERR; switch (type) { case GNUNET_GNSRECORD_TYPE_ATTRIBUTE: { - printf ("Start: string_to_value attribute\n"); - struct GNUNET_CREDENTIAL_DelegationRecord *sets; char attr_str[253 + 1]; char subject_pkey[52 + 1]; @@ -217,8 +217,6 @@ credential_string_to_value (void *cls, uint32_t type, const char *s, return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_CREDENTIAL: { - printf ("Start: string_to_value credential\n"); - struct GNUNET_CREDENTIAL_Credential *cred; cred = GNUNET_CREDENTIAL_credential_from_string (s); @@ -226,110 +224,11 @@ credential_string_to_value (void *cls, uint32_t type, const char *s, return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_DELEGATE: { - printf ("Start: string_to_value delegate\n"); - - char* tmp_str; - char* token; - int matches = 0; - int entries = 0; - size_t tmp_data_size = 0; - char issuer_attr_str[253 + 1], subject_attr_str[253 + 1]; - char issuer_pkey[52 + 1], subject_pkey[52 + 1]; - int i; - - // Split AND - tmp_str = GNUNET_strdup (s); - // Split string by ',' and first entry stored in token - token = strtok (tmp_str, ","); - // TODO: Use of this except for entry counting and format checking (why tmp_data size in the function above?) - while(NULL != token) { - printf("DEL############### tokenX %s\n", token); - - // TODO: only for type A.a <- B.b, missing other types, especially with multiple roles on the right side - // Alles splitten mit "%s %s <- %s %s ..." oder lieber "%s %s <- %s" und das dem lookup überlassen? Dann aber feld größe unknown - - // Match with string and fill variables - matches = SSCANF (token, "%s %s <- %s %s", issuer_pkey, issuer_attr_str, subject_pkey, subject_attr_str); - printf("DEL############### issuerpkey %s, issueratt %s, subjectpkey %s, subjectattr %s\n", - issuer_pkey, issuer_attr_str, subject_pkey, subject_attr_str); - - // Doesn't match string, DEL record string wrong formatted, throw error - if (2 >= matches) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Unable to parse DEL record string `%s'\n"), s); - GNUNET_free (tmp_str); - return GNUNET_SYSERR; - } - - printf("DEL############### matches %d\n", matches); - if (3 == matches) { - // Type A.a <- B - printf("DEL############### A.a <-B found\n"); - } - if (4 == matches) { - printf("DEL############### A.a <- B.b found\n"); - } - - // Get next entry of tmp_str (pointer still saved), store entry in token, NULL if no more entries - token = strtok(NULL, ","); - entries++; - } - // TODO fill tmp_data_size (but what's that) - - tmp_str = GNUNET_strdup (s); - token = strtok (tmp_str, ","); - if (NULL == token) { - GNUNET_free (tmp_str); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed string %s\n", s); - return GNUNET_SYSERR; - } - - // TODO own GNUNET_CREDENTIAL_Delegation struct (when I know the format) - struct GNUNET_CREDENTIAL_Delegation set[entries]; - // sets memory to be 0, starting at *set for the size of struct * entries - memset (set, 0, sizeof (struct GNUNET_CREDENTIAL_Delegation) * entries); - - for (i = 0; i < entries; i++) { - matches = SSCANF (token, "%s %s <- %s %s", issuer_pkey, issuer_attr_str, subject_pkey, subject_attr_str); - - // Set public keys of issuer and subject - GNUNET_CRYPTO_ecdsa_public_key_from_string ( - issuer_pkey, strlen (issuer_pkey), &set[i].issuer_key); - GNUNET_CRYPTO_ecdsa_public_key_from_string ( - subject_pkey, strlen (subject_pkey), &set[i].subject_key); - - // Set issuer attribute, always present - set[i].issuer_attribute_len = strlen (issuer_attr_str) + 1; - set[i].issuer_attribute = GNUNET_strdup (issuer_attr_str); - - if (4 == matches) { - // A.a <- B.b - set[i].subject_attribute_len = strlen (subject_attr_str) + 1; - set[i].subject_attribute = GNUNET_strdup (subject_attr_str); - } - - // If more entries, then token string can take the next entry (separated by ',') by calling strtok again - token = strtok (NULL, ","); - } - //TODO: own method - //tmp_data_size = GNUNET_CREDENTIAL_delegation_set_get_size (entries, set); - - if (-1 == tmp_data_size) { - GNUNET_free (tmp_str); - return GNUNET_SYSERR; - } - - //TODO: serialize - - - - - - + struct GNUNET_CREDENTIAL_Delegate *cred; + cred = GNUNET_CREDENTIAL_delegate_from_string (s); + *data_size = GNUNET_CREDENTIAL_delegate_serialize (cred, (char **)data); - *data_size = strlen (s); - *data = GNUNET_strdup (s); return GNUNET_OK; } default: diff --git a/src/credential/test_credential_own.sh b/src/credential/test_credential_own.sh index a5f567511..d10d1b2ea 100755 --- a/src/credential/test_credential_own.sh +++ b/src/credential/test_credential_own.sh @@ -43,24 +43,28 @@ REG_STUD_ATTR="student" END_ATTR="end" TEST_CREDENTIAL="mygnunetcreds" -# Test for forward search (0) StateU.student -> EOrg.end -# gnunet-namestore -p -z eorg -a -n "@" -t DEL -V "$STATEU_KEY $STATE_STUD_ATTR <- $EORG_KEY $END_ATTR" -e 60m -c test_credential_lookup.conf -# gnunet-namestore -D -z eorg - -# Alternative Format that is being implemented at the moment: -# Issuerside: -# gnunet-credential --create --ego=A --attribute="a" --subject="B.b" --where="is" - gnunet-credential --createIssuerSide --ego=epub --attribute="aasds" --subject="$EORG_KEY basd" --ttl=60m - SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="asd" --subject="$EORG_KEY basd" --ttl=60m` - echo $SIGNED - gnunet-credential --createSubjectSide --extension "$SIGNED" -# Subjectside: -# X = gnunet-credential --create -e E -a "a" -s "B.b" -w ss -# gnunet-credential --add -e E -x X +# Own issuer side storage: +gnunet-credential --createIssuerSide --ego=epub --attribute="issside" --subject="$EORG_KEY asd" --ttl=5m + +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 efghijklmno" --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=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=5m` +gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" + +gnunet-namestore -D -z eorg # (1) EPub assigns the attribute "discount" to all entities that have been assigned "preferred" by EOrg gnunet-namestore -p -z epub -a -n $DISC_ATTR -t ATTR -V "$EORG_KEY $PREF_ATTR" -e 5m -c test_credential_lookup.conf -gnunet-namestore -D -z epub # (2) EOrg assigns the attribute "preferred" to all entities that have been assigned "student" by StateU gnunet-namestore -p -z eorg -a -n $PREF_ATTR -t ATTR -V "$STATEU_KEY $STATE_STUD_ATTR" -e 5m -c test_credential_lookup.conf diff --git a/src/include/gnunet_credential_service.h b/src/include/gnunet_credential_service.h index 05cdb7c9f..7b179e99f 100644 --- a/src/include/gnunet_credential_service.h +++ b/src/include/gnunet_credential_service.h @@ -202,6 +202,53 @@ struct GNUNET_CREDENTIAL_Credential const char *issuer_attribute; }; +/** + * A delegate + */ +struct GNUNET_CREDENTIAL_Delegate { + + /** + * The issuer of the credential + */ + struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; + + /** + * Public key of the subject this credential was issued to + */ + struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; + + /** + * Signature of this credential + */ + struct GNUNET_CRYPTO_EcdsaSignature signature; + + /** + * Expiration of this credential + */ + struct GNUNET_TIME_Absolute expiration; + + /** + * Length of the issuer attribute + */ + uint32_t issuer_attribute_len; + + /** + * The issuer attribute + */ + const char *issuer_attribute; + + /** + * Length of the subject attribute + */ + uint32_t subject_attribute_len; + + /** + * The subject attribute + */ + const char *subject_attribute; + +}; + /** @@ -363,6 +410,21 @@ GNUNET_CREDENTIAL_credential_issue (const struct const char *attribute, struct GNUNET_TIME_Absolute *expiration); +/** + * Issue an attribute to a subject + * + * @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 expiration the TTL of the credential + * @return handle to the queued request + */ +struct GNUNET_CREDENTIAL_Delegate* +GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, + struct GNUNET_CRYPTO_EcdsaPublicKey *subject, + const char *iss_attr, + const char *sub_attr, + struct GNUNET_TIME_Absolute *expiration); /** -- cgit v1.2.3