Cleanup, additional input checks, renaming, simplification:
authorAndreas Ebner <pansy007@googlemail.com>
Tue, 9 Jul 2019 15:53:33 +0000 (17:53 +0200)
committerSchanzenbach, Martin <mschanzenbach@posteo.de>
Mon, 7 Oct 2019 10:15:06 +0000 (12:15 +0200)
- introducing own GNUNET_SIGNATURE_PURPOSE_DELEGATE
- renaming of cred/crd in delegation_misc.c
- renamed extension cmd para to import
- changed subject key/attr parsing from memcpy/malloc to strtok
- only allow to create delegates to expire absolute not relative (prevent reusing created delegation signatures)
- check subject key and reuse expiration of import/signed delegation
- replaced strdup() part of delegation_misc.c and credential_serialization.c with pointers
- uncommented return after detection of unverifyable signatures

src/credential/Makefile.am
src/credential/credential.h
src/credential/credential_api.c
src/credential/credential_serialization.c
src/credential/delegate.h [deleted file]
src/credential/delegate_misc.c
src/credential/gnunet-credential.c
src/credential/test_credential_own.sh
src/include/gnunet_signatures.h

index 7d9ab4bea50da2f9950ccc3aa643824ae4a31c47..d7d8964ebf53af945f617996c181870702932c91 100644 (file)
@@ -69,7 +69,7 @@ gnunet_service_credential_LDADD = \
 
 
 libgnunetcredential_la_SOURCES = \
- credential_api.c credential.h deleagte.h\
+ credential_api.c credential.h\
  credential_serialization.c \
  credential_serialization.h \
  credential_misc.c \
index 3d76bbf4fb69d8492582d917a710ed44784bffaa..9de137275adf5f136f127d79fc8447bdb3462f72 100644 (file)
@@ -210,6 +210,49 @@ struct CredentialEntry
    */
 };
 
+struct DelegateEntry
+{
+
+  /**
+   * The signature for this credential by the issuer
+   */
+  struct GNUNET_CRYPTO_EcdsaSignature signature;
+
+  /**
+   * Signature meta
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Public key of the issuer
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
+
+  /**
+   * Public key of the subject this credential was issued to
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
+
+  /**
+   * Expiration time of this credential
+   */
+  uint64_t expiration GNUNET_PACKED;
+   
+  /**
+   * Issuer subject attribute length
+   */
+  uint32_t issuer_attribute_len;
+
+  /**
+   * Issuer attribute length
+   */
+  uint32_t subject_attribute_len;
+
+  /**
+   * Followed by the subject attribute string
+   */
+};
+
 
 GNUNET_NETWORK_STRUCT_END
 
index be5ff25ae3f914dae042570e34e0312675af2dab..3cbaf6c212951c6ca768e550c3a6428a58685f1c 100644 (file)
@@ -30,7 +30,6 @@
 #include "gnunet_protocols.h"
 #include "gnunet_signatures.h"
 #include "credential.h"
-#include "delegate.h"
 #include "credential_serialization.h"
 #include "gnunet_credential_service.h"
 #include "gnunet_identity_service.h"
index 95b29a49cce8ce83da40d097a8c4cd70002e7adc..4e461c6540f5701434b2ddc10bbc575654eaf3fb 100644 (file)
@@ -31,7 +31,6 @@
 #include "gnunet_credential_service.h"
 #include "gnunet_signatures.h"
 #include "credential.h"
-#include "delegate.h"
 
 /**
  * Calculate how many bytes we will need to serialize
@@ -480,7 +479,7 @@ GNUNET_CREDENTIAL_credential_deserialize (const char*data,
 //TODO own file for delegate de/serialization
 
 int
-GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred,
+GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *dele,
                                         char **data)
 {
   size_t size;
@@ -488,46 +487,47 @@ GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred,
   int attr_len;
 
   // +1 for \0
-  if (0 == cred->subject_attribute_len){
-    attr_len = cred->issuer_attribute_len + 1;
+  if (0 == dele->subject_attribute_len){
+    attr_len = dele->issuer_attribute_len + 1;
   } else {
-    attr_len = cred->issuer_attribute_len + cred->subject_attribute_len + 1;
+    attr_len = dele->issuer_attribute_len + dele->subject_attribute_len + 2;
   }
   size = sizeof (struct DelegateEntry) + attr_len;
 
   char tmp_str[attr_len];
-  GNUNET_memcpy(tmp_str, cred->issuer_attribute, cred->issuer_attribute_len);
-  if (0 != cred->subject_attribute_len){
-    GNUNET_memcpy(tmp_str + cred->issuer_attribute_len, cred->subject_attribute, cred->subject_attribute_len);
+  GNUNET_memcpy(tmp_str, dele->issuer_attribute, dele->issuer_attribute_len);
+  if (0 != dele->subject_attribute_len){
+    tmp_str[dele->issuer_attribute_len] = '\0';
+    GNUNET_memcpy(tmp_str + dele->issuer_attribute_len + 1, dele->subject_attribute, dele->subject_attribute_len);
   }
   tmp_str[attr_len - 1] = '\0';
 
   *data = GNUNET_malloc (size);
   cdata = (struct DelegateEntry*)*data;
-  cdata->subject_key = cred->subject_key;
-  cdata->issuer_key = cred->issuer_key;
-  cdata->expiration = GNUNET_htonll (cred->expiration.abs_value_us);
-  cdata->signature = cred->signature;
-  cdata->issuer_attribute_len = htonl (cred->issuer_attribute_len + 1);
-  if (0 == cred->subject_attribute_len){
+  cdata->subject_key = dele->subject_key;
+  cdata->issuer_key = dele->issuer_key;
+  cdata->expiration = GNUNET_htonll (dele->expiration.abs_value_us);
+  cdata->signature = dele->signature;
+  cdata->issuer_attribute_len = htonl (dele->issuer_attribute_len + 1);
+  if (0 == dele->subject_attribute_len){
     cdata->subject_attribute_len = htonl (0);
   } else {
-    cdata->subject_attribute_len = htonl (cred->subject_attribute_len + 1);
+    cdata->subject_attribute_len = htonl (dele->subject_attribute_len + 1);
   }
-  cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
+  cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
   cdata->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
 
   GNUNET_memcpy (&cdata[1],
                  tmp_str,
                  attr_len);
 
-  if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL
+  if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_DELEGATE
                                              &cdata->purpose,
                                              &cdata->signature,
                                              &cdata->issuer_key))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n");
-    //return NULL;
+    return 0;
   }
   return size;
 }
@@ -536,62 +536,49 @@ struct GNUNET_CREDENTIAL_Delegate*
 GNUNET_CREDENTIAL_delegate_deserialize (const char* data,
                                           size_t data_size)
 {
-  struct GNUNET_CREDENTIAL_Delegate *cred;
+  struct GNUNET_CREDENTIAL_Delegate *dele;
   struct DelegateEntry *cdata;
   char *attr_combo_str;
 
   if (data_size < sizeof (struct DelegateEntry))
     return NULL;
   cdata = (struct DelegateEntry*)data;
-  if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL
+  if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_DELEGATE
                                              &cdata->purpose,
                                              &cdata->signature,
                                              &cdata->issuer_key))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n");
-    //return NULL;
+    return NULL;
   }
   attr_combo_str = (char*)&cdata[1];
   int iss_len = ntohl(cdata->issuer_attribute_len);
   int sub_len = ntohl(cdata->subject_attribute_len);
   int attr_combo_len = iss_len + sub_len;
-  cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_combo_len);
 
-  cred->issuer_key = cdata->issuer_key;
-  cred->subject_key = cdata->subject_key;
-  GNUNET_memcpy (&cred[1],
+  dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_combo_len);
+
+  dele->issuer_key = cdata->issuer_key;
+  dele->subject_key = cdata->subject_key;
+  GNUNET_memcpy (&dele[1],
                  attr_combo_str,
                  attr_combo_len);
-  cred->signature = cdata->signature;
+  dele->signature = cdata->signature;
   
-  // Parse the combo attribute string, split into issuer and subject
+  // Set the pointers for the attributes
+  dele->issuer_attribute = (char*)&dele[1];
+  dele->issuer_attribute_len = iss_len;
+  dele->subject_attribute_len = sub_len;
   if(0 == sub_len){
-    cred->issuer_attribute = attr_combo_str;
-    cred->issuer_attribute_len = attr_combo_len;
-    cred->subject_attribute = '\0';
-    cred->subject_attribute_len = 0;
+    dele->subject_attribute = NULL;
   } else {
-    // -1: array index starts from 0
-    char *tmp_str = GNUNET_malloc(iss_len);
-    GNUNET_memcpy(tmp_str, attr_combo_str, iss_len - 1);
-    tmp_str[iss_len] = '\0';
-    cred->issuer_attribute = strdup(tmp_str);
-    cred->issuer_attribute_len = iss_len;
-    GNUNET_free(tmp_str);
-
-    // -1: both times, starting from 0
-    tmp_str = GNUNET_malloc(sub_len);
-    GNUNET_memcpy(tmp_str, attr_combo_str + iss_len - 1, sub_len - 1);
-    tmp_str[sub_len] = '\0';
-    cred->subject_attribute = strdup(tmp_str);
-    cred->subject_attribute_len = sub_len;
-    GNUNET_free(tmp_str);
+    dele->subject_attribute = (char*)&dele[1] + iss_len;
+
   }
 
-  cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
+  dele->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
 
-  return cred;
+  return dele;
 }
 
 /* end of credential_serialization.c */
diff --git a/src/credential/delegate.h b/src/credential/delegate.h
deleted file mode 100644 (file)
index e1bf112..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-      This file is part of GNUnet
-      Copyright (C) 2012-2013 GNUnet e.V.
-
-      GNUnet is free software: you can redistribute it and/or modify it
-      under the terms of the GNU Affero General Public License as published
-      by the Free Software Foundation, either version 3 of the License,
-      or (at your option) any later version.
-
-      GNUnet is distributed in the hope that it will be useful, but
-      WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-      Affero General Public License for more details.
-     
-      You should have received a copy of the GNU Affero General Public License
-      along with this program.  If not, see <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
-
index d900ccd1f214c3fa6c95c6a05a9d37d48535b40d..5dd8609d6e6a196a149c4ba40022425b7da4e86c 100644 (file)
@@ -30,7 +30,7 @@
 #include "gnunet_constants.h"
 #include "gnunet_credential_service.h"
 #include "gnunet_signatures.h"
-#include "delegate.h"
+#include "credential.h"
 #include <inttypes.h>
 
 char*
@@ -74,7 +74,7 @@ GNUNET_CREDENTIAL_delegate_to_string (const struct GNUNET_CREDENTIAL_Delegate *c
 struct GNUNET_CREDENTIAL_Delegate*
 GNUNET_CREDENTIAL_delegate_from_string (const char* s)
 {
-  struct GNUNET_CREDENTIAL_Delegate *cred;
+  struct GNUNET_CREDENTIAL_Delegate *dele;
   size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
   if (enclen % 5 > 0)
     enclen += 5 - enclen % 5;
@@ -118,44 +118,46 @@ GNUNET_CREDENTIAL_delegate_from_string (const char* s)
   if(strcmp(sub_attr,"") == 0) {
     attr_len = strlen (iss_attr) + 1;
   } else {
-    attr_len = strlen (iss_attr) + strlen(sub_attr) + 1;
+    attr_len = strlen (iss_attr) + strlen(sub_attr) + 2;
   }
-  cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
+  dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
 
   char tmp_str[attr_len];
   GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr));
    if(strcmp(sub_attr,"") != 0) {
-    GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr));
+     tmp_str[strlen(iss_attr)] = '\0';
+    GNUNET_memcpy(tmp_str + strlen(iss_attr) + 1, sub_attr, strlen(sub_attr));
   }
   tmp_str[attr_len - 1] = '\0';
   
   GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
                                               strlen (subject_pkey),
-                                              &cred->subject_key);
+                                              &dele->subject_key);
   GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
                                               strlen (issuer_pkey),
-                                              &cred->issuer_key);
+                                              &dele->issuer_key);
   GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode (signature,
                                 strlen (signature),
                                 (char**)&sig));
-  cred->signature = *sig;
-  cred->expiration = etime_abs;
+  dele->signature = *sig;
+  dele->expiration = etime_abs;
   GNUNET_free (sig);
-  GNUNET_memcpy (&cred[1],
+
+  GNUNET_memcpy (&dele[1],
                  tmp_str,
                  attr_len);
 
-  cred->issuer_attribute_len = strlen (iss_attr);
-  cred->issuer_attribute = strdup(iss_attr);
+  dele->issuer_attribute = (char*)&dele[1];
+  dele->issuer_attribute_len = strlen (iss_attr);
   if(strcmp(sub_attr,"") == 0) {
-    cred->subject_attribute_len = 0;
-    cred->subject_attribute = '\0';
+    dele->subject_attribute = NULL;
+    dele->subject_attribute_len = 0;
   } else {
-    cred->subject_attribute_len = strlen (sub_attr);
-    cred->subject_attribute = strdup(sub_attr);
+    dele->subject_attribute = (char*)&dele[1] + strlen(iss_attr) + 1;
+    dele->subject_attribute_len = strlen (sub_attr);
   }
 
-  return cred;
+  return dele;
 }
 
 /**
@@ -163,7 +165,7 @@ GNUNET_CREDENTIAL_delegate_from_string (const char* s)
  *
  * @param issuer the ego that should be used to issue the attribute
  * @param subject the subject of the attribute
- * @param attribute the name of the attribute
+ * @param iss_attr the name of the attribute
  * @return handle to the queued request
  */
 
@@ -174,8 +176,8 @@ GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *is
                                     const char *sub_attr,
                                     struct GNUNET_TIME_Absolute *expiration)
 {
-  struct DelegateEntry *crd;
-  struct GNUNET_CREDENTIAL_Delegate *cred;
+  struct DelegateEntry *del;
+  struct GNUNET_CREDENTIAL_Delegate *dele;
   size_t size;
   int attr_len;
   
@@ -183,68 +185,76 @@ GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *is
     // +1 for \0
     attr_len = strlen (iss_attr) + 1;
   } else {
-    attr_len = strlen (iss_attr) + strlen(sub_attr) + 1;
+    // +2 for both strings need to be terminated with \0
+    attr_len = strlen (iss_attr) + strlen(sub_attr) + 2;
   }
   size = sizeof (struct DelegateEntry) + attr_len;
 
   char tmp_str[attr_len];
   GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr));
   if (NULL != sub_attr){
-    GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr));
+    tmp_str[strlen(iss_attr)] = '\0';
+    GNUNET_memcpy(tmp_str + strlen(iss_attr) + 1, sub_attr, strlen(sub_attr));
   }
   tmp_str[attr_len - 1] = '\0';
-
-  crd = GNUNET_malloc (size);
-  crd->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
-  crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
+  
+  del = GNUNET_malloc (size);
+  del->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
+  del->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
   GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
-                                      &crd->issuer_key);
-  crd->subject_key = *subject;
-  crd->expiration = GNUNET_htonll (expiration->abs_value_us);
-  crd->issuer_attribute_len = htonl (strlen (iss_attr) + 1);
+                                      &del->issuer_key);
+  del->subject_key = *subject;
+  del->expiration = GNUNET_htonll (expiration->abs_value_us);
+  del->issuer_attribute_len = htonl (strlen (iss_attr) + 1);
   if (NULL == sub_attr){
-    crd->subject_attribute_len = htonl (0);
+    del->subject_attribute_len = htonl (0);
   } else {
-    crd->subject_attribute_len = htonl (strlen (sub_attr) + 1);
+    del->subject_attribute_len = htonl (strlen (sub_attr) + 1);
   }
 
-  GNUNET_memcpy (&crd[1],
+  GNUNET_memcpy (&del[1],
                  tmp_str,
                  attr_len);
  
   if (GNUNET_OK !=
       GNUNET_CRYPTO_ecdsa_sign (issuer,
-                                &crd->purpose,
-                                &crd->signature))
+                                &del->purpose,
+                                &del->signature))
   {
     GNUNET_break (0);
-    GNUNET_free (crd);
+    GNUNET_free (del);
     return NULL;
   }
 
-  cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
-  cred->signature = crd->signature;
-  cred->expiration = *expiration;
+  dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
+  dele->signature = del->signature;
+  dele->expiration = *expiration;
   GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
-                                      &cred->issuer_key);
+                                      &dele->issuer_key);
 
-  cred->subject_key = *subject;
-  cred->issuer_attribute = strdup(iss_attr);
-  cred->issuer_attribute_len = strlen(iss_attr);
+  dele->subject_key = *subject;
+
+  // Copy the combined string at the part in the memory where the struct ends
+  GNUNET_memcpy (&dele[1],
+                 tmp_str,
+                 attr_len);
+
+  dele->issuer_attribute = (char*)&dele[1];
+  dele->issuer_attribute_len = strlen(iss_attr);
   if (NULL == sub_attr){
-    cred->subject_attribute = '\0';
-    cred->subject_attribute_len = 0;
+    dele->subject_attribute = NULL;
+    dele->subject_attribute_len = 0;
   } else {
-    cred->subject_attribute = strdup(sub_attr);
-    cred->subject_attribute_len = strlen(sub_attr);
+    dele->subject_attribute = (char*)&dele[1] + strlen(iss_attr) + 1;
+    dele->subject_attribute_len = strlen(sub_attr);
   }
 
-  GNUNET_memcpy (&cred[1],
-                 tmp_str,
-                 attr_len);
+  GNUNET_free (del);
+  return dele;
 
-  GNUNET_free (crd);
-  return cred;
+  // Entweder: strdup und destroy (free auf die subjct_attribute/issuer_attribute)
+  // oder: pointer auf cred[1], aber nach jedem string im combined string ein EOS <- besser
+  // function comment: cred must be freed by caller, (add missing sub_iss)
 }
 
 
index 22fca7b0092ccc9319791c31dff785f2e51fa296..3d20e708212b8ca01578ad61cebc166a5e683c78 100644 (file)
@@ -150,7 +150,7 @@ static int sign_ss;
 /**
  * Signed issue credentials
  */
-static char *extension;
+static char *import;
 
 /**
  * Queue entry for the 'add' operation.
@@ -186,6 +186,16 @@ static uint64_t etime;
  */
 static int etime_is_rel = GNUNET_SYSERR;
 
+/**
+ * Fixed size of the public/private keys
+ */
+static const int key_length = 52;
+
+/**
+ * Record label for storing delegations
+ */
+static char *record_label;
+
 /**
  * Task run on shutdown.  Cleans up everything.
  *
@@ -332,7 +342,7 @@ identity_cb (void *cls,
              const struct GNUNET_IDENTITY_Ego *ego)
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
-  struct GNUNET_CREDENTIAL_Credential *crd;
+  struct GNUNET_CREDENTIAL_Credential *cred;
   struct GNUNET_TIME_Absolute etime_abs;
   struct GNUNET_TIME_Relative etime_rel;
   char *res;
@@ -400,47 +410,17 @@ identity_cb (void *cls,
   privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
   GNUNET_free_non_null (ego_name);
   ego_name = NULL;
-  crd = GNUNET_CREDENTIAL_credential_issue (privkey,
+  cred = GNUNET_CREDENTIAL_credential_issue (privkey,
                                             &subject_pkey,
                                             issuer_attr,
                                             &etime_abs);
 
-  res = GNUNET_CREDENTIAL_credential_to_string (crd);
-  GNUNET_free (crd);
+  res = GNUNET_CREDENTIAL_credential_to_string (cred);
+  GNUNET_free (cred);
   printf ("%s\n", res);
   GNUNET_SCHEDULER_shutdown ();
 }
 
-static int
-parse_cmdl_param(const char *extensionstring)
-{
-  char *token;
-  char *tmp_str;
-  int counter = 0;
-
-  tmp_str = GNUNET_strdup (extensionstring);
-  // split string via strtok, assume parameters are in the right order
-  token = strtok (tmp_str, ";");
-  while (NULL != token) {
-
-    // fill variables depending on counter
-    if(0 == counter) {
-      expiration = GNUNET_strdup(token);
-    } else if(1 == counter) {
-      extension = GNUNET_strdup(token);
-    } else {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not parse extension string\n");
-    }
-  
-    counter++;
-    token = strtok (NULL, ";");
-  }
-  GNUNET_free (tmp_str);
-
-  //return GNUNET_SYSERR;
-  return GNUNET_OK;
-}
-
 /**
  * Parse expiration time.
  *
@@ -573,55 +553,71 @@ store_cb (void *cls,
   // Key handling
   zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
 
-  // Check relevant cmdline parameters
-  if (NULL == issuer_attr)
-  {
-    fprintf (stderr, "Missing option -attribute for operation 'create'.\n");
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
+  // TODO maybe dont have to set subject, if only used in if/else can use import here instead!!
+  if( GNUNET_GNSRECORD_TYPE_DELEGATE == type){
+    // Parse import
+    struct GNUNET_CREDENTIAL_Delegate *cred;
+    cred = GNUNET_CREDENTIAL_delegate_from_string (import);
 
-  if (NULL == subject)
-  {
-    fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
+    // Get import subject public key string
+    char *subject_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&cred->subject_key);
 
-  // String to value conversion for storage
-  if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type,
+    // Get zone public key string
+    struct GNUNET_CRYPTO_EcdsaPublicKey zone_pubkey;
+    GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey);
+    char *zone_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&zone_pubkey);
+
+    // Check if the subject key in the signed import matches the zone's key it is issued to
+    if(strcmp(zone_pubkey_str, subject_pubkey_str) != 0)
+    {
+      fprintf (stderr, "Import signed delegate does not match this ego's public key.\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+
+    // Expiration
+    etime = cred->expiration.abs_value_us;
+    etime_is_rel = GNUNET_NO;
+
+    // Prepare the data to be store in the record
+    data_size = GNUNET_CREDENTIAL_delegate_serialize (cred, (char **)&data);
+    GNUNET_free(cred);
+  } else {
+    // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE
+    if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type,
                                          subject,
                                          &data,
                                          &data_size))
-  {
-    fprintf (stderr, "Value `%s' invalid for record type `%s'\n",
-        subject,
-        typestring);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
+    {
+      fprintf (stderr, "Value `%s' invalid for record type `%s'\n",
+          subject,
+          typestring);
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
 
-  // Take care of expiration
-  if (NULL == expiration)
-  {
-    fprintf (stderr, "Missing option -e for operation 'create'\n");
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-  if (GNUNET_OK != parse_expiration (expiration,
-      &etime_is_rel,
-      &etime))
-  {
-    fprintf (stderr, "Invalid time format `%s'\n",
-              expiration);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
+    // Take care of expiration
+    if (NULL == expiration)
+    {
+      fprintf (stderr, "Missing option -e for operation 'create'\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+    if (GNUNET_OK != parse_expiration (expiration,
+        &etime_is_rel,
+        &etime))
+    {
+      fprintf (stderr, "Invalid time format `%s'\n",
+                expiration);
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
   }
 
   // Start lookup
   add_qe = GNUNET_NAMESTORE_records_lookup (ns,
                                         &zone_pkey,
-                                        issuer_attr,
+                                        record_label,
                                         &error_cb,
                                         NULL,
                                         &get_existing_record,
@@ -634,9 +630,8 @@ sign_cb (void *cls,
             const struct GNUNET_IDENTITY_Ego *ego)
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
-  struct GNUNET_CREDENTIAL_Delegate *crd;
+  struct GNUNET_CREDENTIAL_Delegate *dele;
   struct GNUNET_TIME_Absolute etime_abs;
-  struct GNUNET_TIME_Relative etime_rel;
   char *res;
 
   el = NULL;
@@ -647,43 +642,33 @@ sign_cb (void *cls,
     fprintf (stderr, "Please specify a TTL\n");
     GNUNET_SCHEDULER_shutdown ();
     return;
-  } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration, &etime_rel))
-  {
-    etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
   } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs))
   {
-    fprintf (stderr, "%s is not a valid ttl!\n", expiration);
+    fprintf (stderr, "%s is not a valid ttl! Only absolute times are accepted!\n", expiration);
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
 
-  // if contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
-  char *space;
-  int idx;
+  // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
   char *subject_pubkey_str;
-  char *subject_attr;
+  char *subject_attr = NULL;
+  char *token;
 
-  space = strchr(subject, ' ');
-  if(NULL == space)
+  // Subject Public Key
+  token = strtok (subject, " ");
+  if (key_length == strlen(token))
   {
-    // only contains subject key e.g. A.a <- B
-    subject_pubkey_str = subject;
-    subject_attr = '\0';
+    subject_pubkey_str = token;
   } else {
-    // subject contains: key attr1.attr2.attr3...
-    // split subject into subject_pubkey_str and subject_attr
-    idx = (int)(space - subject);
-
-    subject_pubkey_str = GNUNET_malloc(idx+1);
-    GNUNET_memcpy(subject_pubkey_str, subject, idx);
-    subject_pubkey_str[idx]  = '\0';
-
-    int sub_attr_len = strlen(subject) - idx - 1;
-    // +1 for the \0
-    subject_attr = GNUNET_malloc(sub_attr_len + 1);
-    // +1 to remove the space "key attr" (or whatever separator)
-    GNUNET_memcpy(subject_attr, subject + idx + 1, sub_attr_len);
-    subject_attr[sub_attr_len] = '\0';  
+    fprintf (stderr, "Key error, wrong length: %ld!\n", strlen(token));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  // Subject Attribute(s)
+  token = strtok (NULL, " ");
+  if(NULL != token)
+  {
+    subject_attr = token;
   }
 
   // work on keys
@@ -699,14 +684,14 @@ sign_cb (void *cls,
   }
 
   // Sign delegate
-  crd = GNUNET_CREDENTIAL_delegate_issue (privkey,
+  dele = GNUNET_CREDENTIAL_delegate_issue (privkey,
                                             &subject_pkey,
                                             issuer_attr,
                                             subject_attr,
                                             &etime_abs);
-  res = GNUNET_CREDENTIAL_delegate_to_string (crd);
-  GNUNET_free (crd);
-  printf ("%s;%s\n", expiration, res);
+  res = GNUNET_CREDENTIAL_delegate_to_string (dele);
+  GNUNET_free (dele);
+  printf ("%s\n", res);
 
   GNUNET_free_non_null (ego_name);
   ego_name = NULL;
@@ -728,22 +713,34 @@ run (void *cls,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
-
   cfg = c;
 
   tt = GNUNET_SCHEDULER_add_delayed (timeout,
                                      &do_timeout, NULL);
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
 
+  // Check relevant cmdline parameters
   if (GNUNET_YES == create_is) {
     if (NULL == ego_name) {
-      fprintf (stderr, "ego required\n");
+      fprintf (stderr, "Missing option '-ego'\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+    if (NULL == issuer_attr) {
+      fprintf (stderr, "Missing option '-attribute' for issuer attribute\n");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+    if (NULL == subject)
+    {
+      fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
       GNUNET_SCHEDULER_shutdown ();
       return;
     }
 
     // Lookup ego, on success call store_cb and store as ATTRIBUTE type
     type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE;
+    record_label = issuer_attr;
     el = GNUNET_IDENTITY_ego_lookup (cfg,
                                 ego_name,
                                 &store_cb,
@@ -753,18 +750,14 @@ run (void *cls,
 
   if (GNUNET_YES == create_ss) {
     // check if signed parameter has been passed in cmd line call
-    if (NULL == extension) {
-      fprintf (stderr, "'extension' required\n");
+    if (NULL == import) {
+      fprintf (stderr, "'import' required\n");
       GNUNET_SCHEDULER_shutdown ();
       return;
     }
 
-    // parses all the passed parameters
-    parse_cmdl_param(extension);
-
     type = GNUNET_GNSRECORD_TYPE_DELEGATE;
-    subject = extension;
-    issuer_attr = GNUNET_GNS_EMPTY_LABEL_AT;
+    record_label = GNUNET_GNS_EMPTY_LABEL_AT;
     // Store subject side
     el = GNUNET_IDENTITY_ego_lookup (cfg,
                                 ego_name,
@@ -1008,7 +1001,7 @@ main (int argc, char *const *argv)
     GNUNET_GETOPT_option_string ('T',
                                  "ttl",
                                  "EXP",
-                                 gettext_noop ("The time to live for the credential"),
+                                 gettext_noop ("The time to live for the credential. e.g. 5m, 6h, \"1990-12-30 12:00:00\""),
                                  &expiration),
     GNUNET_GETOPT_option_flag ('g',
                                "collect",
@@ -1027,10 +1020,10 @@ main (int argc, char *const *argv)
                                gettext_noop ("Create, sign and return a credential subject side."),
                                &sign_ss),
     GNUNET_GETOPT_option_string ('x',
-                               "extension",
-                               "EXT",
-                               gettext_noop ("Signed credentials that should be issued to a zone/ego"),
-                               &extension),
+                               "import",
+                               "IMP",
+                               gettext_noop ("Import signed credentials that should be issued to a zone/ego"),
+                               &import),
     GNUNET_GETOPT_OPTION_END
   };
   int ret;
index d10d1b2eab037e1397f985dd99476edb6c785b00..b53825d1bb41a74b99e5094860570840e5088037 100755 (executable)
@@ -49,17 +49,17 @@ gnunet-credential --createIssuerSide --ego=epub --attribute="issside" --subject=
 gnunet-namestore -D -z epub
 
 # Own subject side storage:
-SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY" --ttl=5m`
-gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED"
+SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY" --ttl="2019-12-12 10:00:00"`
+gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
 
-SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno" --ttl=5m`
-gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED"
+SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno" --ttl="2019-12-12 10:00:00"`
+gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
 
-SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno.pqr" --ttl=5m`
-gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED"
+SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno.pqr" --ttl="2019-12-12 10:00:00"`
+gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
 
-SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd.stu" --subject="$EORG_KEY efghijklmno.pqr" --ttl=5m`
-gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED"
+SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd.stu" --subject="$EORG_KEY efghijklmno.pqr" --ttl="2019-12-12 10:00:00"`
+gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
 
 gnunet-namestore -D -z eorg
 
index 6801c641eb5b1fd72fcb88ef2b2d26db4fe9942c..1d6d5a2296f8d9b73eb986ee7ada56c38bf948e6 100644 (file)
@@ -241,6 +241,10 @@ extern "C"
  */
 #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 37
 
+/**
+ * Signature for a GNUnet delegate
+ */
+#define GNUNET_SIGNATURE_PURPOSE_DELEGATE 38
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {