- 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
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 = \
#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"
#include "gnunet_credential_service.h"
#include "gnunet_signatures.h"
#include "credential.h"
+#include "delegate.h"
/**
* Calculate how many bytes we will need to serialize
c_count,
cd);
}
+
int
GNUNET_CREDENTIAL_credential_serialize (struct
GNUNET_CREDENTIAL_Credential *cred,
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 */
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 */
--- /dev/null
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+ 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
+
--- /dev/null
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+ 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 <inttypes.h>
+
+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;
+}
+
+
--- /dev/null
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+ 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
#include <gnunet_gnsrecord_lib.h>
#include <gnunet_namestore_service.h>
#include "credential_misc.h"
+#include "delegate_misc.h"
#include "credential_serialization.h"
/**
/**
* Subject pubkey string
*/
-static char *subject_key;
+static char *subject;
/**
* Subject credential string
*/
static int sign_ss;
-/**
- * Add mode
- */
-static int add_iss;
-
/**
* Signed issue credentials
*/
{
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,
&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);
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;
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;
}
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;
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,
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)
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)
}
// 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");
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 ();
// 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");
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)
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);
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;
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,
}
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 ();
// 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,
}
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,
}
- if (NULL == subject_key)
+ if (NULL == subject)
{
fprintf (stderr,
_("Subject public key needed\n"));
}
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;
}
_("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;
}
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",
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",
"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",
"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
};
#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"
credential_value_to_string (void *cls, uint32_t type, const void *data,
size_t data_size)
{
-
const char *cdata;
switch (type) {
}
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: {
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;
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];
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);
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:
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
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;
+
+};
+
/**
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);
/**