aboutsummaryrefslogtreecommitdiff
path: root/src/credential/delegate_misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/credential/delegate_misc.c')
-rw-r--r--src/credential/delegate_misc.c250
1 files changed, 250 insertions, 0 deletions
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 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 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
22/**
23 * @file credential/delegate_misc.c
24 * @brief Misc API for delegate
25 *
26 * @author Martin Schanzenbach
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_credential_service.h"
32#include "gnunet_signatures.h"
33#include "delegate.h"
34#include <inttypes.h>
35
36char*
37GNUNET_CREDENTIAL_delegate_to_string (const struct GNUNET_CREDENTIAL_Delegate *cred)
38{
39 char *cred_str;
40 char *subject_pkey;
41 char *issuer_pkey;
42 char *signature;
43
44 subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
45 issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
46 GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
47 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
48 &signature);
49 if(0 == cred->subject_attribute_len){
50 GNUNET_asprintf (&cred_str,
51 "%s.%s -> %s | %s | %"SCNu64,
52 issuer_pkey,
53 cred->issuer_attribute,
54 subject_pkey,
55 signature,
56 cred->expiration.abs_value_us);
57 } else {
58 GNUNET_asprintf (&cred_str,
59 "%s.%s -> %s.%s | %s | %"SCNu64,
60 issuer_pkey,
61 cred->issuer_attribute,
62 subject_pkey,
63 cred->subject_attribute,
64 signature,
65 cred->expiration.abs_value_us);
66 }
67 GNUNET_free (subject_pkey);
68 GNUNET_free (issuer_pkey);
69 GNUNET_free (signature);
70
71 return cred_str;
72}
73
74struct GNUNET_CREDENTIAL_Delegate*
75GNUNET_CREDENTIAL_delegate_from_string (const char* s)
76{
77 struct GNUNET_CREDENTIAL_Delegate *cred;
78 size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
79 if (enclen % 5 > 0)
80 enclen += 5 - enclen % 5;
81 enclen /= 5; /* 260/5 = 52 */
82 char subject_pkey[enclen + 1];
83 char issuer_pkey[enclen + 1];
84 char iss_attr[253 + 1];
85 // Needs to be initialized, in case of Type 1 credential (A.a <- B)
86 char sub_attr[253 + 1] = "";
87 char signature[256]; //TODO max payload size
88
89 struct GNUNET_CRYPTO_EcdsaSignature *sig;
90 struct GNUNET_TIME_Absolute etime_abs;
91
92 // If it's A.a <- B.b...
93 if (6 != SSCANF (s,
94 "%52s.%253s -> %52s.%253s | %s | %"SCNu64,
95 issuer_pkey,
96 iss_attr,
97 subject_pkey,
98 sub_attr,
99 signature,
100 &etime_abs.abs_value_us))
101 {
102 // Try if it's A.a <- B
103 if (5 != SSCANF (s,
104 "%52s.%253s -> %52s | %s | %"SCNu64,
105 issuer_pkey,
106 iss_attr,
107 subject_pkey,
108 signature,
109 &etime_abs.abs_value_us))
110 {
111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to parse DEL record string `%s'\n", s);
112 return NULL;
113 }
114 }
115
116 // +1 for \0
117 int attr_len;
118 if(strcmp(sub_attr,"") == 0) {
119 attr_len = strlen (iss_attr) + 1;
120 } else {
121 attr_len = strlen (iss_attr) + strlen(sub_attr) + 1;
122 }
123 cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
124
125 char tmp_str[attr_len];
126 GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr));
127 if(strcmp(sub_attr,"") != 0) {
128 GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr));
129 }
130 tmp_str[attr_len - 1] = '\0';
131
132 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
133 strlen (subject_pkey),
134 &cred->subject_key);
135 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
136 strlen (issuer_pkey),
137 &cred->issuer_key);
138 GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode (signature,
139 strlen (signature),
140 (char**)&sig));
141 cred->signature = *sig;
142 cred->expiration = etime_abs;
143 GNUNET_free (sig);
144 GNUNET_memcpy (&cred[1],
145 tmp_str,
146 attr_len);
147
148 cred->issuer_attribute_len = strlen (iss_attr);
149 cred->issuer_attribute = strdup(iss_attr);
150 if(strcmp(sub_attr,"") == 0) {
151 cred->subject_attribute_len = 0;
152 cred->subject_attribute = '\0';
153 } else {
154 cred->subject_attribute_len = strlen (sub_attr);
155 cred->subject_attribute = strdup(sub_attr);
156 }
157
158 return cred;
159}
160
161/**
162 * Issue an attribute to a subject
163 *
164 * @param issuer the ego that should be used to issue the attribute
165 * @param subject the subject of the attribute
166 * @param attribute the name of the attribute
167 * @return handle to the queued request
168 */
169
170struct GNUNET_CREDENTIAL_Delegate *
171GNUNET_CREDENTIAL_delegate_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
172 struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
173 const char *iss_attr,
174 const char *sub_attr,
175 struct GNUNET_TIME_Absolute *expiration)
176{
177 struct DelegateEntry *crd;
178 struct GNUNET_CREDENTIAL_Delegate *cred;
179 size_t size;
180 int attr_len;
181
182 if (NULL == sub_attr){
183 // +1 for \0
184 attr_len = strlen (iss_attr) + 1;
185 } else {
186 attr_len = strlen (iss_attr) + strlen(sub_attr) + 1;
187 }
188 size = sizeof (struct DelegateEntry) + attr_len;
189
190 char tmp_str[attr_len];
191 GNUNET_memcpy(tmp_str, iss_attr, strlen(iss_attr));
192 if (NULL != sub_attr){
193 GNUNET_memcpy(tmp_str + strlen(iss_attr), sub_attr, strlen(sub_attr));
194 }
195 tmp_str[attr_len - 1] = '\0';
196
197 crd = GNUNET_malloc (size);
198 crd->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
199 crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
200 GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
201 &crd->issuer_key);
202 crd->subject_key = *subject;
203 crd->expiration = GNUNET_htonll (expiration->abs_value_us);
204 crd->issuer_attribute_len = htonl (strlen (iss_attr) + 1);
205 if (NULL == sub_attr){
206 crd->subject_attribute_len = htonl (0);
207 } else {
208 crd->subject_attribute_len = htonl (strlen (sub_attr) + 1);
209 }
210
211 GNUNET_memcpy (&crd[1],
212 tmp_str,
213 attr_len);
214
215 if (GNUNET_OK !=
216 GNUNET_CRYPTO_ecdsa_sign (issuer,
217 &crd->purpose,
218 &crd->signature))
219 {
220 GNUNET_break (0);
221 GNUNET_free (crd);
222 return NULL;
223 }
224
225 cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) + attr_len);
226 cred->signature = crd->signature;
227 cred->expiration = *expiration;
228 GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
229 &cred->issuer_key);
230
231 cred->subject_key = *subject;
232 cred->issuer_attribute = strdup(iss_attr);
233 cred->issuer_attribute_len = strlen(iss_attr);
234 if (NULL == sub_attr){
235 cred->subject_attribute = '\0';
236 cred->subject_attribute_len = 0;
237 } else {
238 cred->subject_attribute = strdup(sub_attr);
239 cred->subject_attribute_len = strlen(sub_attr);
240 }
241
242 GNUNET_memcpy (&cred[1],
243 tmp_str,
244 attr_len);
245
246 GNUNET_free (crd);
247 return cred;
248}
249
250