summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Ebner <pansy007@googlemail.com>2019-07-09 17:53:33 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-10-07 12:15:06 +0200
commit5091edcec16455febee99afec20e0ffe6cc59c21 (patch)
treec7d517e26ca7d3d4f863b4154361293bc79d733e
parentfc58d9d4241ed2dcd4b492b4f922ba959449a697 (diff)
downloadgnunet-5091edcec16455febee99afec20e0ffe6cc59c21.tar.gz
gnunet-5091edcec16455febee99afec20e0ffe6cc59c21.zip
Cleanup, additional input checks, renaming, simplification:
- introducing own GNUNET_SIGNATURE_PURPOSE_DELEGATE - renaming of cred/crd in delegation_misc.c - renamed extension cmd para to import - changed subject key/attr parsing from memcpy/malloc to strtok - only allow to create delegates to expire absolute not relative (prevent reusing created delegation signatures) - check subject key and reuse expiration of import/signed delegation - replaced strdup() part of delegation_misc.c and credential_serialization.c with pointers - uncommented return after detection of unverifyable signatures
-rw-r--r--src/credential/Makefile.am2
-rw-r--r--src/credential/credential.h43
-rw-r--r--src/credential/credential_api.c1
-rw-r--r--src/credential/credential_serialization.c85
-rw-r--r--src/credential/delegate.h79
-rw-r--r--src/credential/delegate_misc.c114
-rw-r--r--src/credential/gnunet-credential.c233
-rwxr-xr-xsrc/credential/test_credential_own.sh16
-rw-r--r--src/include/gnunet_signatures.h4
9 files changed, 267 insertions, 310 deletions
diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am
index 7d9ab4bea..d7d8964eb 100644
--- a/src/credential/Makefile.am
+++ b/src/credential/Makefile.am
@@ -69,7 +69,7 @@ gnunet_service_credential_LDADD = \
69 69
70 70
71libgnunetcredential_la_SOURCES = \ 71libgnunetcredential_la_SOURCES = \
72 credential_api.c credential.h deleagte.h\ 72 credential_api.c credential.h\
73 credential_serialization.c \ 73 credential_serialization.c \
74 credential_serialization.h \ 74 credential_serialization.h \
75 credential_misc.c \ 75 credential_misc.c \
diff --git a/src/credential/credential.h b/src/credential/credential.h
index 3d76bbf4f..9de137275 100644
--- a/src/credential/credential.h
+++ b/src/credential/credential.h
@@ -210,6 +210,49 @@ struct CredentialEntry
210 */ 210 */
211}; 211};
212 212
213struct DelegateEntry
214{
215
216 /**
217 * The signature for this credential by the issuer
218 */
219 struct GNUNET_CRYPTO_EcdsaSignature signature;
220
221 /**
222 * Signature meta
223 */
224 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
225
226 /**
227 * Public key of the issuer
228 */
229 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
230
231 /**
232 * Public key of the subject this credential was issued to
233 */
234 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
235
236 /**
237 * Expiration time of this credential
238 */
239 uint64_t expiration GNUNET_PACKED;
240
241 /**
242 * Issuer subject attribute length
243 */
244 uint32_t issuer_attribute_len;
245
246 /**
247 * Issuer attribute length
248 */
249 uint32_t subject_attribute_len;
250
251 /**
252 * Followed by the subject attribute string
253 */
254};
255
213 256
214GNUNET_NETWORK_STRUCT_END 257GNUNET_NETWORK_STRUCT_END
215 258
diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c
index be5ff25ae..3cbaf6c21 100644
--- a/src/credential/credential_api.c
+++ b/src/credential/credential_api.c
@@ -30,7 +30,6 @@
30#include "gnunet_protocols.h" 30#include "gnunet_protocols.h"
31#include "gnunet_signatures.h" 31#include "gnunet_signatures.h"
32#include "credential.h" 32#include "credential.h"
33#include "delegate.h"
34#include "credential_serialization.h" 33#include "credential_serialization.h"
35#include "gnunet_credential_service.h" 34#include "gnunet_credential_service.h"
36#include "gnunet_identity_service.h" 35#include "gnunet_identity_service.h"
diff --git a/src/credential/credential_serialization.c b/src/credential/credential_serialization.c
index 95b29a49c..4e461c654 100644
--- a/src/credential/credential_serialization.c
+++ b/src/credential/credential_serialization.c
@@ -31,7 +31,6 @@
31#include "gnunet_credential_service.h" 31#include "gnunet_credential_service.h"
32#include "gnunet_signatures.h" 32#include "gnunet_signatures.h"
33#include "credential.h" 33#include "credential.h"
34#include "delegate.h"
35 34
36/** 35/**
37 * Calculate how many bytes we will need to serialize 36 * Calculate how many bytes we will need to serialize
@@ -480,7 +479,7 @@ GNUNET_CREDENTIAL_credential_deserialize (const char*data,
480//TODO own file for delegate de/serialization 479//TODO own file for delegate de/serialization
481 480
482int 481int
483GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred, 482GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *dele,
484 char **data) 483 char **data)
485{ 484{
486 size_t size; 485 size_t size;
@@ -488,46 +487,47 @@ GNUNET_CREDENTIAL_delegate_serialize (struct GNUNET_CREDENTIAL_Delegate *cred,
488 int attr_len; 487 int attr_len;
489 488
490 // +1 for \0 489 // +1 for \0
491 if (0 == cred->subject_attribute_len){ 490 if (0 == dele->subject_attribute_len){
492 attr_len = cred->issuer_attribute_len + 1; 491 attr_len = dele->issuer_attribute_len + 1;
493 } else { 492 } else {
494 attr_len = cred->issuer_attribute_len + cred->subject_attribute_len + 1; 493 attr_len = dele->issuer_attribute_len + dele->subject_attribute_len + 2;
495 } 494 }
496 size = sizeof (struct DelegateEntry) + attr_len; 495 size = sizeof (struct DelegateEntry) + attr_len;
497 496
498 char tmp_str[attr_len]; 497 char tmp_str[attr_len];
499 GNUNET_memcpy(tmp_str, cred->issuer_attribute, cred->issuer_attribute_len); 498 GNUNET_memcpy(tmp_str, dele->issuer_attribute, dele->issuer_attribute_len);
500 if (0 != cred->subject_attribute_len){ 499 if (0 != dele->subject_attribute_len){
501 GNUNET_memcpy(tmp_str + cred->issuer_attribute_len, cred->subject_attribute, cred->subject_attribute_len); 500 tmp_str[dele->issuer_attribute_len] = '\0';
501 GNUNET_memcpy(tmp_str + dele->issuer_attribute_len + 1, dele->subject_attribute, dele->subject_attribute_len);
502 } 502 }
503 tmp_str[attr_len - 1] = '\0'; 503 tmp_str[attr_len - 1] = '\0';
504 504
505 *data = GNUNET_malloc (size); 505 *data = GNUNET_malloc (size);
506 cdata = (struct DelegateEntry*)*data; 506 cdata = (struct DelegateEntry*)*data;
507 cdata->subject_key = cred->subject_key; 507 cdata->subject_key = dele->subject_key;
508 cdata->issuer_key = cred->issuer_key; 508 cdata->issuer_key = dele->issuer_key;
509 cdata->expiration = GNUNET_htonll (cred->expiration.abs_value_us); 509 cdata->expiration = GNUNET_htonll (dele->expiration.abs_value_us);
510 cdata->signature = cred->signature; 510 cdata->signature = dele->signature;
511 cdata->issuer_attribute_len = htonl (cred->issuer_attribute_len + 1); 511 cdata->issuer_attribute_len = htonl (dele->issuer_attribute_len + 1);
512 if (0 == cred->subject_attribute_len){ 512 if (0 == dele->subject_attribute_len){
513 cdata->subject_attribute_len = htonl (0); 513 cdata->subject_attribute_len = htonl (0);
514 } else { 514 } else {
515 cdata->subject_attribute_len = htonl (cred->subject_attribute_len + 1); 515 cdata->subject_attribute_len = htonl (dele->subject_attribute_len + 1);
516 } 516 }
517 cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); 517 cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
518 cdata->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); 518 cdata->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
519 519
520 GNUNET_memcpy (&cdata[1], 520 GNUNET_memcpy (&cdata[1],
521 tmp_str, 521 tmp_str,
522 attr_len); 522 attr_len);
523 523
524 if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, 524 if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_DELEGATE,
525 &cdata->purpose, 525 &cdata->purpose,
526 &cdata->signature, 526 &cdata->signature,
527 &cdata->issuer_key)) 527 &cdata->issuer_key))
528 { 528 {
529 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n"); 529 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n");
530 //return NULL; 530 return 0;
531 } 531 }
532 return size; 532 return size;
533} 533}
@@ -536,62 +536,49 @@ struct GNUNET_CREDENTIAL_Delegate*
536GNUNET_CREDENTIAL_delegate_deserialize (const char* data, 536GNUNET_CREDENTIAL_delegate_deserialize (const char* data,
537 size_t data_size) 537 size_t data_size)
538{ 538{
539 struct GNUNET_CREDENTIAL_Delegate *cred; 539 struct GNUNET_CREDENTIAL_Delegate *dele;
540 struct DelegateEntry *cdata; 540 struct DelegateEntry *cdata;
541 char *attr_combo_str; 541 char *attr_combo_str;
542 542
543 if (data_size < sizeof (struct DelegateEntry)) 543 if (data_size < sizeof (struct DelegateEntry))
544 return NULL; 544 return NULL;
545 cdata = (struct DelegateEntry*)data; 545 cdata = (struct DelegateEntry*)data;
546 if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, 546 if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_DELEGATE,
547 &cdata->purpose, 547 &cdata->purpose,
548 &cdata->signature, 548 &cdata->signature,
549 &cdata->issuer_key)) 549 &cdata->issuer_key))
550 { 550 {
551 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n"); 551 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n");
552 //return NULL; 552 return NULL;
553 } 553 }
554 attr_combo_str = (char*)&cdata[1]; 554 attr_combo_str = (char*)&cdata[1];
555 int iss_len = ntohl(cdata->issuer_attribute_len); 555 int iss_len = ntohl(cdata->issuer_attribute_len);
556 int sub_len = ntohl(cdata->subject_attribute_len); 556 int sub_len = ntohl(cdata->subject_attribute_len);
557 int attr_combo_len = iss_len + sub_len; 557 int attr_combo_len = iss_len + sub_len;
558
559 cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_combo_len);
560 558
561 cred->issuer_key = cdata->issuer_key; 559 dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_combo_len);
562 cred->subject_key = cdata->subject_key; 560
563 GNUNET_memcpy (&cred[1], 561 dele->issuer_key = cdata->issuer_key;
562 dele->subject_key = cdata->subject_key;
563 GNUNET_memcpy (&dele[1],
564 attr_combo_str, 564 attr_combo_str,
565 attr_combo_len); 565 attr_combo_len);
566 cred->signature = cdata->signature; 566 dele->signature = cdata->signature;
567 567
568 // Parse the combo attribute string, split into issuer and subject 568 // Set the pointers for the attributes
569 dele->issuer_attribute = (char*)&dele[1];
570 dele->issuer_attribute_len = iss_len;
571 dele->subject_attribute_len = sub_len;
569 if(0 == sub_len){ 572 if(0 == sub_len){
570 cred->issuer_attribute = attr_combo_str; 573 dele->subject_attribute = NULL;
571 cred->issuer_attribute_len = attr_combo_len;
572 cred->subject_attribute = '\0';
573 cred->subject_attribute_len = 0;
574 } else { 574 } else {
575 // -1: array index starts from 0 575 dele->subject_attribute = (char*)&dele[1] + iss_len;
576 char *tmp_str = GNUNET_malloc(iss_len); 576
577 GNUNET_memcpy(tmp_str, attr_combo_str, iss_len - 1);
578 tmp_str[iss_len] = '\0';
579 cred->issuer_attribute = strdup(tmp_str);
580 cred->issuer_attribute_len = iss_len;
581 GNUNET_free(tmp_str);
582
583 // -1: both times, starting from 0
584 tmp_str = GNUNET_malloc(sub_len);
585 GNUNET_memcpy(tmp_str, attr_combo_str + iss_len - 1, sub_len - 1);
586 tmp_str[sub_len] = '\0';
587 cred->subject_attribute = strdup(tmp_str);
588 cred->subject_attribute_len = sub_len;
589 GNUNET_free(tmp_str);
590 } 577 }
591 578
592 cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration); 579 dele->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
593 580
594 return cred; 581 return dele;
595} 582}
596 583
597/* end of credential_serialization.c */ 584/* end of credential_serialization.c */
diff --git a/src/credential/delegate.h b/src/credential/delegate.h
deleted file mode 100644
index e1bf112ef..000000000
--- a/src/credential/delegate.h
+++ /dev/null
@@ -1,79 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2012-2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file credential/delegate.h
22 * @brief IPC messages between CREDENTIAL API and CREDENTIAL service
23 * @author Martin Schanzenbach
24 */
25#ifndef DELEGATE_H
26#define DELEGATE_H
27
28#include "gnunet_credential_service.h"
29
30GNUNET_NETWORK_STRUCT_BEGIN
31
32struct DelegateEntry
33{
34
35 /**
36 * The signature for this credential by the issuer
37 */
38 struct GNUNET_CRYPTO_EcdsaSignature signature;
39
40 /**
41 * Signature meta
42 */
43 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
44
45 /**
46 * Public key of the issuer
47 */
48 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
49
50 /**
51 * Public key of the subject this credential was issued to
52 */
53 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
54
55 /**
56 * Expiration time of this credential
57 */
58 uint64_t expiration GNUNET_PACKED;
59
60 /**
61 * Issuer subject attribute length
62 */
63 uint32_t issuer_attribute_len;
64
65 /**
66 * Issuer attribute length
67 */
68 uint32_t subject_attribute_len;
69
70 /**
71 * Followed by the subject attribute string
72 */
73};
74
75
76GNUNET_NETWORK_STRUCT_END
77
78#endif
79
diff --git a/src/credential/delegate_misc.c b/src/credential/delegate_misc.c
index d900ccd1f..5dd8609d6 100644
--- a/src/credential/delegate_misc.c
+++ b/src/credential/delegate_misc.c
@@ -30,7 +30,7 @@
30#include "gnunet_constants.h" 30#include "gnunet_constants.h"
31#include "gnunet_credential_service.h" 31#include "gnunet_credential_service.h"
32#include "gnunet_signatures.h" 32#include "gnunet_signatures.h"
33#include "delegate.h" 33#include "credential.h"
34#include <inttypes.h> 34#include <inttypes.h>
35 35
36char* 36char*
@@ -74,7 +74,7 @@ GNUNET_CREDENTIAL_delegate_to_string (const struct GNUNET_CREDENTIAL_Delegate *c
74struct GNUNET_CREDENTIAL_Delegate* 74struct GNUNET_CREDENTIAL_Delegate*
75GNUNET_CREDENTIAL_delegate_from_string (const char* s) 75GNUNET_CREDENTIAL_delegate_from_string (const char* s)
76{ 76{
77 struct GNUNET_CREDENTIAL_Delegate *cred; 77 struct GNUNET_CREDENTIAL_Delegate *dele;
78 size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; 78 size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
79 if (enclen % 5 > 0) 79 if (enclen % 5 > 0)
80 enclen += 5 - enclen % 5; 80 enclen += 5 - enclen % 5;
@@ -118,44 +118,46 @@ GNUNET_CREDENTIAL_delegate_from_string (const char* s)
118 if(strcmp(sub_attr,"") == 0) { 118 if(strcmp(sub_attr,"") == 0) {
119 attr_len = strlen (iss_attr) + 1; 119 attr_len = strlen (iss_attr) + 1;
120 } else { 120 } else {
121 attr_len = strlen (iss_attr) + strlen(sub_attr) + 1; 121 attr_len = strlen (iss_attr) + strlen(sub_attr) + 2;
122 } 122 }
123 cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len); 123 dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
124 124
125 char tmp_str[attr_len]; 125 char tmp_str[attr_len];
126 GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr)); 126 GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr));
127 if(strcmp(sub_attr,"") != 0) { 127 if(strcmp(sub_attr,"") != 0) {
128 GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr)); 128 tmp_str[strlen(iss_attr)] = '\0';
129 GNUNET_memcpy(tmp_str + strlen(iss_attr) + 1, sub_attr, strlen(sub_attr));
129 } 130 }
130 tmp_str[attr_len - 1] = '\0'; 131 tmp_str[attr_len - 1] = '\0';
131 132
132 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, 133 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
133 strlen (subject_pkey), 134 strlen (subject_pkey),
134 &cred->subject_key); 135 &dele->subject_key);
135 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey, 136 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
136 strlen (issuer_pkey), 137 strlen (issuer_pkey),
137 &cred->issuer_key); 138 &dele->issuer_key);
138 GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode (signature, 139 GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode (signature,
139 strlen (signature), 140 strlen (signature),
140 (char**)&sig)); 141 (char**)&sig));
141 cred->signature = *sig; 142 dele->signature = *sig;
142 cred->expiration = etime_abs; 143 dele->expiration = etime_abs;
143 GNUNET_free (sig); 144 GNUNET_free (sig);
144 GNUNET_memcpy (&cred[1], 145
146 GNUNET_memcpy (&dele[1],
145 tmp_str, 147 tmp_str,
146 attr_len); 148 attr_len);
147 149
148 cred->issuer_attribute_len = strlen (iss_attr); 150 dele->issuer_attribute = (char*)&dele[1];
149 cred->issuer_attribute = strdup(iss_attr); 151 dele->issuer_attribute_len = strlen (iss_attr);
150 if(strcmp(sub_attr,"") == 0) { 152 if(strcmp(sub_attr,"") == 0) {
151 cred->subject_attribute_len = 0; 153 dele->subject_attribute = NULL;
152 cred->subject_attribute = '\0'; 154 dele->subject_attribute_len = 0;
153 } else { 155 } else {
154 cred->subject_attribute_len = strlen (sub_attr); 156 dele->subject_attribute = (char*)&dele[1] + strlen(iss_attr) + 1;
155 cred->subject_attribute = strdup(sub_attr); 157 dele->subject_attribute_len = strlen (sub_attr);
156 } 158 }
157 159
158 return cred; 160 return dele;
159} 161}
160 162
161/** 163/**
@@ -163,7 +165,7 @@ GNUNET_CREDENTIAL_delegate_from_string (const char* s)
163 * 165 *
164 * @param issuer the ego that should be used to issue the attribute 166 * @param issuer the ego that should be used to issue the attribute
165 * @param subject the subject of the attribute 167 * @param subject the subject of the attribute
166 * @param attribute the name of the attribute 168 * @param iss_attr the name of the attribute
167 * @return handle to the queued request 169 * @return handle to the queued request
168 */ 170 */
169 171
@@ -174,8 +176,8 @@ GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *is
174 const char *sub_attr, 176 const char *sub_attr,
175 struct GNUNET_TIME_Absolute *expiration) 177 struct GNUNET_TIME_Absolute *expiration)
176{ 178{
177 struct DelegateEntry *crd; 179 struct DelegateEntry *del;
178 struct GNUNET_CREDENTIAL_Delegate *cred; 180 struct GNUNET_CREDENTIAL_Delegate *dele;
179 size_t size; 181 size_t size;
180 int attr_len; 182 int attr_len;
181 183
@@ -183,68 +185,76 @@ GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *is
183 // +1 for \0 185 // +1 for \0
184 attr_len = strlen (iss_attr) + 1; 186 attr_len = strlen (iss_attr) + 1;
185 } else { 187 } else {
186 attr_len = strlen (iss_attr) + strlen(sub_attr) + 1; 188 // +2 for both strings need to be terminated with \0
189 attr_len = strlen (iss_attr) + strlen(sub_attr) + 2;
187 } 190 }
188 size = sizeof (struct DelegateEntry) + attr_len; 191 size = sizeof (struct DelegateEntry) + attr_len;
189 192
190 char tmp_str[attr_len]; 193 char tmp_str[attr_len];
191 GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr)); 194 GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr));
192 if (NULL != sub_attr){ 195 if (NULL != sub_attr){
193 GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr)); 196 tmp_str[strlen(iss_attr)] = '\0';
197 GNUNET_memcpy(tmp_str + strlen(iss_attr) + 1, sub_attr, strlen(sub_attr));
194 } 198 }
195 tmp_str[attr_len - 1] = '\0'; 199 tmp_str[attr_len - 1] = '\0';
196 200
197 crd = GNUNET_malloc (size); 201 del = GNUNET_malloc (size);
198 crd->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); 202 del->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
199 crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); 203 del->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
200 GNUNET_CRYPTO_ecdsa_key_get_public (issuer, 204 GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
201 &crd->issuer_key); 205 &del->issuer_key);
202 crd->subject_key = *subject; 206 del->subject_key = *subject;
203 crd->expiration = GNUNET_htonll (expiration->abs_value_us); 207 del->expiration = GNUNET_htonll (expiration->abs_value_us);
204 crd->issuer_attribute_len = htonl (strlen (iss_attr) + 1); 208 del->issuer_attribute_len = htonl (strlen (iss_attr) + 1);
205 if (NULL == sub_attr){ 209 if (NULL == sub_attr){
206 crd->subject_attribute_len = htonl (0); 210 del->subject_attribute_len = htonl (0);
207 } else { 211 } else {
208 crd->subject_attribute_len = htonl (strlen (sub_attr) + 1); 212 del->subject_attribute_len = htonl (strlen (sub_attr) + 1);
209 } 213 }
210 214
211 GNUNET_memcpy (&crd[1], 215 GNUNET_memcpy (&del[1],
212 tmp_str, 216 tmp_str,
213 attr_len); 217 attr_len);
214 218
215 if (GNUNET_OK != 219 if (GNUNET_OK !=
216 GNUNET_CRYPTO_ecdsa_sign (issuer, 220 GNUNET_CRYPTO_ecdsa_sign (issuer,
217 &crd->purpose, 221 &del->purpose,
218 &crd->signature)) 222 &del->signature))
219 { 223 {
220 GNUNET_break (0); 224 GNUNET_break (0);
221 GNUNET_free (crd); 225 GNUNET_free (del);
222 return NULL; 226 return NULL;
223 } 227 }
224 228
225 cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len); 229 dele = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
226 cred->signature = crd->signature; 230 dele->signature = del->signature;
227 cred->expiration = *expiration; 231 dele->expiration = *expiration;
228 GNUNET_CRYPTO_ecdsa_key_get_public (issuer, 232 GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
229 &cred->issuer_key); 233 &dele->issuer_key);
230 234
231 cred->subject_key = *subject; 235 dele->subject_key = *subject;
232 cred->issuer_attribute = strdup(iss_attr); 236
233 cred->issuer_attribute_len = strlen(iss_attr); 237 // Copy the combined string at the part in the memory where the struct ends
238 GNUNET_memcpy (&dele[1],
239 tmp_str,
240 attr_len);
241
242 dele->issuer_attribute = (char*)&dele[1];
243 dele->issuer_attribute_len = strlen(iss_attr);
234 if (NULL == sub_attr){ 244 if (NULL == sub_attr){
235 cred->subject_attribute = '\0'; 245 dele->subject_attribute = NULL;
236 cred->subject_attribute_len = 0; 246 dele->subject_attribute_len = 0;
237 } else { 247 } else {
238 cred->subject_attribute = strdup(sub_attr); 248 dele->subject_attribute = (char*)&dele[1] + strlen(iss_attr) + 1;
239 cred->subject_attribute_len = strlen(sub_attr); 249 dele->subject_attribute_len = strlen(sub_attr);
240 } 250 }
241 251
242 GNUNET_memcpy (&cred[1], 252 GNUNET_free (del);
243 tmp_str, 253 return dele;
244 attr_len);
245 254
246 GNUNET_free (crd); 255 // Entweder: strdup und destroy (free auf die subjct_attribute/issuer_attribute)
247 return cred; 256 // oder: pointer auf cred[1], aber nach jedem string im combined string ein EOS <- besser
257 // function comment: cred must be freed by caller, (add missing sub_iss)
248} 258}
249 259
250 260
diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c
index 22fca7b00..3d20e7082 100644
--- a/src/credential/gnunet-credential.c
+++ b/src/credential/gnunet-credential.c
@@ -150,7 +150,7 @@ static int sign_ss;
150/** 150/**
151 * Signed issue credentials 151 * Signed issue credentials
152 */ 152 */
153static char *extension; 153static char *import;
154 154
155/** 155/**
156 * Queue entry for the 'add' operation. 156 * Queue entry for the 'add' operation.
@@ -187,6 +187,16 @@ static uint64_t etime;
187static int etime_is_rel = GNUNET_SYSERR; 187static int etime_is_rel = GNUNET_SYSERR;
188 188
189/** 189/**
190 * Fixed size of the public/private keys
191 */
192static const int key_length = 52;
193
194/**
195 * Record label for storing delegations
196 */
197static char *record_label;
198
199/**
190 * Task run on shutdown. Cleans up everything. 200 * Task run on shutdown. Cleans up everything.
191 * 201 *
192 * @param cls unused 202 * @param cls unused
@@ -332,7 +342,7 @@ identity_cb (void *cls,
332 const struct GNUNET_IDENTITY_Ego *ego) 342 const struct GNUNET_IDENTITY_Ego *ego)
333{ 343{
334 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; 344 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
335 struct GNUNET_CREDENTIAL_Credential *crd; 345 struct GNUNET_CREDENTIAL_Credential *cred;
336 struct GNUNET_TIME_Absolute etime_abs; 346 struct GNUNET_TIME_Absolute etime_abs;
337 struct GNUNET_TIME_Relative etime_rel; 347 struct GNUNET_TIME_Relative etime_rel;
338 char *res; 348 char *res;
@@ -400,47 +410,17 @@ identity_cb (void *cls,
400 privkey = GNUNET_IDENTITY_ego_get_private_key (ego); 410 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
401 GNUNET_free_non_null (ego_name); 411 GNUNET_free_non_null (ego_name);
402 ego_name = NULL; 412 ego_name = NULL;
403 crd = GNUNET_CREDENTIAL_credential_issue (privkey, 413 cred = GNUNET_CREDENTIAL_credential_issue (privkey,
404 &subject_pkey, 414 &subject_pkey,
405 issuer_attr, 415 issuer_attr,
406 &etime_abs); 416 &etime_abs);
407 417
408 res = GNUNET_CREDENTIAL_credential_to_string (crd); 418 res = GNUNET_CREDENTIAL_credential_to_string (cred);
409 GNUNET_free (crd); 419 GNUNET_free (cred);
410 printf ("%s\n", res); 420 printf ("%s\n", res);
411 GNUNET_SCHEDULER_shutdown (); 421 GNUNET_SCHEDULER_shutdown ();
412} 422}
413 423
414static int
415parse_cmdl_param(const char *extensionstring)
416{
417 char *token;
418 char *tmp_str;
419 int counter = 0;
420
421 tmp_str = GNUNET_strdup (extensionstring);
422 // split string via strtok, assume parameters are in the right order
423 token = strtok (tmp_str, ";");
424 while (NULL != token) {
425
426 // fill variables depending on counter
427 if(0 == counter) {
428 expiration = GNUNET_strdup(token);
429 } else if(1 == counter) {
430 extension = GNUNET_strdup(token);
431 } else {
432 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not parse extension string\n");
433 }
434
435 counter++;
436 token = strtok (NULL, ";");
437 }
438 GNUNET_free (tmp_str);
439
440 //return GNUNET_SYSERR;
441 return GNUNET_OK;
442}
443
444/** 424/**
445 * Parse expiration time. 425 * Parse expiration time.
446 * 426 *
@@ -573,55 +553,71 @@ store_cb (void *cls,
573 // Key handling 553 // Key handling
574 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); 554 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
575 555
576 // Check relevant cmdline parameters 556 // TODO maybe dont have to set subject, if only used in if/else can use import here instead!!
577 if (NULL == issuer_attr) 557 if( GNUNET_GNSRECORD_TYPE_DELEGATE == type){
578 { 558 // Parse import
579 fprintf (stderr, "Missing option -attribute for operation 'create'.\n"); 559 struct GNUNET_CREDENTIAL_Delegate *cred;
580 GNUNET_SCHEDULER_shutdown (); 560 cred = GNUNET_CREDENTIAL_delegate_from_string (import);
581 return;
582 }
583 561
584 if (NULL == subject) 562 // Get import subject public key string
585 { 563 char *subject_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&cred->subject_key);
586 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
587 GNUNET_SCHEDULER_shutdown ();
588 return;
589 }
590 564
591 // String to value conversion for storage 565 // Get zone public key string
592 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, 566 struct GNUNET_CRYPTO_EcdsaPublicKey zone_pubkey;
567 GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey);
568 char *zone_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&zone_pubkey);
569
570 // Check if the subject key in the signed import matches the zone's key it is issued to
571 if(strcmp(zone_pubkey_str, subject_pubkey_str) != 0)
572 {
573 fprintf (stderr, "Import signed delegate does not match this ego's public key.\n");
574 GNUNET_SCHEDULER_shutdown ();
575 return;
576 }
577
578 // Expiration
579 etime = cred->expiration.abs_value_us;
580 etime_is_rel = GNUNET_NO;
581
582 // Prepare the data to be store in the record
583 data_size = GNUNET_CREDENTIAL_delegate_serialize (cred, (char **)&data);
584 GNUNET_free(cred);
585 } else {
586 // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE
587 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type,
593 subject, 588 subject,
594 &data, 589 &data,
595 &data_size)) 590 &data_size))
596 { 591 {
597 fprintf (stderr, "Value `%s' invalid for record type `%s'\n", 592 fprintf (stderr, "Value `%s' invalid for record type `%s'\n",
598 subject, 593 subject,
599 typestring); 594 typestring);
600 GNUNET_SCHEDULER_shutdown (); 595 GNUNET_SCHEDULER_shutdown ();
601 return; 596 return;
602 } 597 }
603 598
604 // Take care of expiration 599 // Take care of expiration
605 if (NULL == expiration) 600 if (NULL == expiration)
606 { 601 {
607 fprintf (stderr, "Missing option -e for operation 'create'\n"); 602 fprintf (stderr, "Missing option -e for operation 'create'\n");
608 GNUNET_SCHEDULER_shutdown (); 603 GNUNET_SCHEDULER_shutdown ();
609 return; 604 return;
610 } 605 }
611 if (GNUNET_OK != parse_expiration (expiration, 606 if (GNUNET_OK != parse_expiration (expiration,
612 &etime_is_rel, 607 &etime_is_rel,
613 &etime)) 608 &etime))
614 { 609 {
615 fprintf (stderr, "Invalid time format `%s'\n", 610 fprintf (stderr, "Invalid time format `%s'\n",
616 expiration); 611 expiration);
617 GNUNET_SCHEDULER_shutdown (); 612 GNUNET_SCHEDULER_shutdown ();
618 return; 613 return;
614 }
619 } 615 }
620 616
621 // Start lookup 617 // Start lookup
622 add_qe = GNUNET_NAMESTORE_records_lookup (ns, 618 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
623 &zone_pkey, 619 &zone_pkey,
624 issuer_attr, 620 record_label,
625 &error_cb, 621 &error_cb,
626 NULL, 622 NULL,
627 &get_existing_record, 623 &get_existing_record,
@@ -634,9 +630,8 @@ sign_cb (void *cls,
634 const struct GNUNET_IDENTITY_Ego *ego) 630 const struct GNUNET_IDENTITY_Ego *ego)
635{ 631{
636 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; 632 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
637 struct GNUNET_CREDENTIAL_Delegate *crd; 633 struct GNUNET_CREDENTIAL_Delegate *dele;
638 struct GNUNET_TIME_Absolute etime_abs; 634 struct GNUNET_TIME_Absolute etime_abs;
639 struct GNUNET_TIME_Relative etime_rel;
640 char *res; 635 char *res;
641 636
642 el = NULL; 637 el = NULL;
@@ -647,43 +642,33 @@ sign_cb (void *cls,
647 fprintf (stderr, "Please specify a TTL\n"); 642 fprintf (stderr, "Please specify a TTL\n");
648 GNUNET_SCHEDULER_shutdown (); 643 GNUNET_SCHEDULER_shutdown ();
649 return; 644 return;
650 } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration, &etime_rel))
651 {
652 etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
653 } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs)) 645 } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs))
654 { 646 {
655 fprintf (stderr, "%s is not a valid ttl!\n", expiration); 647 fprintf (stderr, "%s is not a valid ttl! Only absolute times are accepted!\n", expiration);
656 GNUNET_SCHEDULER_shutdown (); 648 GNUNET_SCHEDULER_shutdown ();
657 return; 649 return;
658 } 650 }
659 651
660 // if contains a space - split it by the first space only - assume first entry is subject followed by attribute(s) 652 // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
661 char *space;
662 int idx;
663 char *subject_pubkey_str; 653 char *subject_pubkey_str;
664 char *subject_attr; 654 char *subject_attr = NULL;
655 char *token;
665 656
666 space = strchr(subject, ' '); 657 // Subject Public Key
667 if(NULL == space) 658 token = strtok (subject, " ");
659 if (key_length == strlen(token))
668 { 660 {
669 // only contains subject key e.g. A.a <- B 661 subject_pubkey_str = token;
670 subject_pubkey_str = subject;
671 subject_attr = '\0';
672 } else { 662 } else {
673 // subject contains: key attr1.attr2.attr3... 663 fprintf (stderr, "Key error, wrong length: %ld!\n", strlen(token));
674 // split subject into subject_pubkey_str and subject_attr 664 GNUNET_SCHEDULER_shutdown ();
675 idx = (int)(space - subject); 665 return;
676 666 }
677 subject_pubkey_str = GNUNET_malloc(idx+1); 667 // Subject Attribute(s)
678 GNUNET_memcpy(subject_pubkey_str, subject, idx); 668 token = strtok (NULL, " ");
679 subject_pubkey_str[idx] = '\0'; 669 if(NULL != token)
680 670 {
681 int sub_attr_len = strlen(subject) - idx - 1; 671 subject_attr = token;
682 // +1 for the \0
683 subject_attr = GNUNET_malloc(sub_attr_len + 1);
684 // +1 to remove the space "key attr" (or whatever separator)
685 GNUNET_memcpy(subject_attr, subject + idx + 1, sub_attr_len);
686 subject_attr[sub_attr_len] = '\0';
687 } 672 }
688 673
689 // work on keys 674 // work on keys
@@ -699,14 +684,14 @@ sign_cb (void *cls,
699 } 684 }
700 685
701 // Sign delegate 686 // Sign delegate
702 crd = GNUNET_CREDENTIAL_delegate_issue (privkey, 687 dele = GNUNET_CREDENTIAL_delegate_issue (privkey,
703 &subject_pkey, 688 &subject_pkey,
704 issuer_attr, 689 issuer_attr,
705 subject_attr, 690 subject_attr,
706 &etime_abs); 691 &etime_abs);
707 res = GNUNET_CREDENTIAL_delegate_to_string (crd); 692 res = GNUNET_CREDENTIAL_delegate_to_string (dele);
708 GNUNET_free (crd); 693 GNUNET_free (dele);
709 printf ("%s;%s\n", expiration, res); 694 printf ("%s\n", res);
710 695
711 GNUNET_free_non_null (ego_name); 696 GNUNET_free_non_null (ego_name);
712 ego_name = NULL; 697 ego_name = NULL;
@@ -728,22 +713,34 @@ run (void *cls,
728 const char *cfgfile, 713 const char *cfgfile,
729 const struct GNUNET_CONFIGURATION_Handle *c) 714 const struct GNUNET_CONFIGURATION_Handle *c)
730{ 715{
731
732 cfg = c; 716 cfg = c;
733 717
734 tt = GNUNET_SCHEDULER_add_delayed (timeout, 718 tt = GNUNET_SCHEDULER_add_delayed (timeout,
735 &do_timeout, NULL); 719 &do_timeout, NULL);
736 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 720 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
737 721
722 // Check relevant cmdline parameters
738 if (GNUNET_YES == create_is) { 723 if (GNUNET_YES == create_is) {
739 if (NULL == ego_name) { 724 if (NULL == ego_name) {
740 fprintf (stderr, "ego required\n"); 725 fprintf (stderr, "Missing option '-ego'\n");
726 GNUNET_SCHEDULER_shutdown ();
727 return;
728 }
729 if (NULL == issuer_attr) {
730 fprintf (stderr, "Missing option '-attribute' for issuer attribute\n");
731 GNUNET_SCHEDULER_shutdown ();
732 return;
733 }
734 if (NULL == subject)
735 {
736 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
741 GNUNET_SCHEDULER_shutdown (); 737 GNUNET_SCHEDULER_shutdown ();
742 return; 738 return;
743 } 739 }
744 740
745 // Lookup ego, on success call store_cb and store as ATTRIBUTE type 741 // Lookup ego, on success call store_cb and store as ATTRIBUTE type
746 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE; 742 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE;
743 record_label = issuer_attr;
747 el = GNUNET_IDENTITY_ego_lookup (cfg, 744 el = GNUNET_IDENTITY_ego_lookup (cfg,
748 ego_name, 745 ego_name,
749 &store_cb, 746 &store_cb,
@@ -753,18 +750,14 @@ run (void *cls,
753 750
754 if (GNUNET_YES == create_ss) { 751 if (GNUNET_YES == create_ss) {
755 // check if signed parameter has been passed in cmd line call 752 // check if signed parameter has been passed in cmd line call
756 if (NULL == extension) { 753 if (NULL == import) {
757 fprintf (stderr, "'extension' required\n"); 754 fprintf (stderr, "'import' required\n");
758 GNUNET_SCHEDULER_shutdown (); 755 GNUNET_SCHEDULER_shutdown ();
759 return; 756 return;
760 } 757 }
761 758
762 // parses all the passed parameters
763 parse_cmdl_param(extension);
764
765 type = GNUNET_GNSRECORD_TYPE_DELEGATE; 759 type = GNUNET_GNSRECORD_TYPE_DELEGATE;
766 subject = extension; 760 record_label = GNUNET_GNS_EMPTY_LABEL_AT;
767 issuer_attr = GNUNET_GNS_EMPTY_LABEL_AT;
768 // Store subject side 761 // Store subject side
769 el = GNUNET_IDENTITY_ego_lookup (cfg, 762 el = GNUNET_IDENTITY_ego_lookup (cfg,
770 ego_name, 763 ego_name,
@@ -1008,7 +1001,7 @@ main (int argc, char *const *argv)
1008 GNUNET_GETOPT_option_string ('T', 1001 GNUNET_GETOPT_option_string ('T',
1009 "ttl", 1002 "ttl",
1010 "EXP", 1003 "EXP",
1011 gettext_noop ("The time to live for the credential"), 1004 gettext_noop ("The time to live for the credential. e.g. 5m, 6h, \"1990-12-30 12:00:00\""),
1012 &expiration), 1005 &expiration),
1013 GNUNET_GETOPT_option_flag ('g', 1006 GNUNET_GETOPT_option_flag ('g',
1014 "collect", 1007 "collect",
@@ -1027,10 +1020,10 @@ main (int argc, char *const *argv)
1027 gettext_noop ("Create, sign and return a credential subject side."), 1020 gettext_noop ("Create, sign and return a credential subject side."),
1028 &sign_ss), 1021 &sign_ss),
1029 GNUNET_GETOPT_option_string ('x', 1022 GNUNET_GETOPT_option_string ('x',
1030 "extension", 1023 "import",
1031 "EXT", 1024 "IMP",
1032 gettext_noop ("Signed credentials that should be issued to a zone/ego"), 1025 gettext_noop ("Import signed credentials that should be issued to a zone/ego"),
1033 &extension), 1026 &import),
1034 GNUNET_GETOPT_OPTION_END 1027 GNUNET_GETOPT_OPTION_END
1035 }; 1028 };
1036 int ret; 1029 int ret;
diff --git a/src/credential/test_credential_own.sh b/src/credential/test_credential_own.sh
index d10d1b2ea..b53825d1b 100755
--- a/src/credential/test_credential_own.sh
+++ b/src/credential/test_credential_own.sh
@@ -49,17 +49,17 @@ gnunet-credential --createIssuerSide --ego=epub --attribute="issside" --subject=
49gnunet-namestore -D -z epub 49gnunet-namestore -D -z epub
50 50
51# Own subject side storage: 51# Own subject side storage:
52SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY" --ttl=5m` 52SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY" --ttl="2019-12-12 10:00:00"`
53gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" 53gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
54 54
55SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno" --ttl=5m` 55SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno" --ttl="2019-12-12 10:00:00"`
56gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" 56gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
57 57
58SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno.pqr" --ttl=5m` 58SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd" --subject="$EORG_KEY efghijklmno.pqr" --ttl="2019-12-12 10:00:00"`
59gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" 59gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
60 60
61SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd.stu" --subject="$EORG_KEY efghijklmno.pqr" --ttl=5m` 61SIGNED=`$DO_TIMEOUT gnunet-credential --signSubjectSide --ego=epub --attribute="abcd.stu" --subject="$EORG_KEY efghijklmno.pqr" --ttl="2019-12-12 10:00:00"`
62gnunet-credential --createSubjectSide --ego=eorg --extension "$SIGNED" 62gnunet-credential --createSubjectSide --ego=eorg --import "$SIGNED"
63 63
64gnunet-namestore -D -z eorg 64gnunet-namestore -D -z eorg
65 65
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index 6801c641e..1d6d5a229 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -241,6 +241,10 @@ extern "C"
241 */ 241 */
242#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 37 242#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 37
243 243
244/**
245 * Signature for a GNUnet delegate
246 */
247#define GNUNET_SIGNATURE_PURPOSE_DELEGATE 38
244 248
245#if 0 /* keep Emacsens' auto-indent happy */ 249#if 0 /* keep Emacsens' auto-indent happy */
246{ 250{