gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] 02/18: Implemented delegate sign and store functio


From: gnunet
Subject: [GNUnet-SVN] [gnunet] 02/18: Implemented delegate sign and store function for GNS entries:
Date: Mon, 07 Oct 2019 12:30:58 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

commit fc58d9d4241ed2dcd4b492b4f922ba959449a697
Author: Andreas Ebner <address@hidden>
AuthorDate: Sun Jul 7 15:04:40 2019 +0200

    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(-)

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 <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
+
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 <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;
+}
+
+
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 <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
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 <gnunet_gnsrecord_lib.h>
 #include <gnunet_namestore_service.h>
 #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);
 
 
 /**

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]