aboutsummaryrefslogtreecommitdiff
path: root/src/abd/abd_serialization.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/abd/abd_serialization.c')
-rw-r--r--src/abd/abd_serialization.c508
1 files changed, 508 insertions, 0 deletions
diff --git a/src/abd/abd_serialization.c b/src/abd/abd_serialization.c
new file mode 100644
index 000000000..d2bc15166
--- /dev/null
+++ b/src/abd/abd_serialization.c
@@ -0,0 +1,508 @@
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 abd/abd_serialization.c
24 * @brief API to serialize and deserialize delegation chains
25 * and abds
26 * @author Martin Schanzenbach
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_abd_service.h"
32#include "gnunet_signatures.h"
33#include "abd.h"
34
35/**
36 * Calculate how many bytes we will need to serialize
37 * the given delegation chain
38 *
39 * @param ds_count number of delegation chain entries
40 * @param dsr array of #GNUNET_ABD_DelegationSet
41 * @return the required size to serialize
42 */
43size_t
44GNUNET_ABD_delegation_set_get_size (
45 unsigned int ds_count,
46 const struct GNUNET_ABD_DelegationSet *dsr)
47{
48 unsigned int i;
49 size_t ret;
50
51 ret = sizeof (struct DelegationRecordData) * (ds_count);
52
53 for (i = 0; i < ds_count; i++)
54 {
55 GNUNET_assert ((ret + dsr[i].subject_attribute_len) >= ret);
56 ret += dsr[i].subject_attribute_len;
57 }
58 return ret;
59}
60
61/**
62 * Serizalize the given delegation chain entries and abd
63 *
64 * @param d_count number of delegation chain entries
65 * @param dsr array of #GNUNET_ABD_DelegationSet
66 * @param dest_size size of the destination
67 * @param dest where to store the result
68 * @return the size of the data, -1 on failure
69 */
70ssize_t
71GNUNET_ABD_delegation_set_serialize (
72 unsigned int d_count,
73 const struct GNUNET_ABD_DelegationSet *dsr,
74 size_t dest_size,
75 char *dest)
76{
77 struct DelegationRecordData rec;
78 unsigned int i;
79 size_t off;
80
81 off = 0;
82 for (i = 0; i < d_count; i++)
83 {
84 rec.subject_attribute_len = htonl ((uint32_t) dsr[i].subject_attribute_len);
85 rec.subject_key = dsr[i].subject_key;
86 if (off + sizeof (rec) > dest_size)
87 return -1;
88 GNUNET_memcpy (&dest[off], &rec, sizeof (rec));
89 off += sizeof (rec);
90 if (0 == dsr[i].subject_attribute_len)
91 continue;
92 if (off + dsr[i].subject_attribute_len > dest_size)
93 return -1;
94 GNUNET_memcpy (&dest[off],
95 dsr[i].subject_attribute,
96 dsr[i].subject_attribute_len);
97 off += dsr[i].subject_attribute_len;
98 }
99 return off;
100}
101
102
103/**
104 * Deserialize the given destination
105 *
106 * @param len size of the serialized delegation chain and cred
107 * @param src the serialized data
108 * @param d_count the number of delegation chain entries
109 * @param dsr where to put the delegation chain entries
110 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
111 */
112int
113GNUNET_ABD_delegation_set_deserialize (
114 size_t len,
115 const char *src,
116 unsigned int d_count,
117 struct GNUNET_ABD_DelegationSet *dsr)
118{
119 struct DelegationRecordData rec;
120 unsigned int i;
121 size_t off;
122
123 off = 0;
124 for (i = 0; i < d_count; i++)
125 {
126 if (off + sizeof (rec) > len)
127 return GNUNET_SYSERR;
128 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
129 dsr[i].subject_key = rec.subject_key;
130 off += sizeof (rec);
131 dsr[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
132 if (off + dsr[i].subject_attribute_len > len)
133 return GNUNET_SYSERR;
134 dsr[i].subject_attribute = (char *) &src[off];
135 off += dsr[i].subject_attribute_len;
136 }
137 return GNUNET_OK;
138}
139
140
141/**
142 * Calculate how many bytes we will need to serialize
143 * the abds
144 *
145 * @param c_count number of abd entries
146 * @param cd a #GNUNET_ABD_Credential
147 * @return the required size to serialize
148 */
149size_t
150GNUNET_ABD_delegates_get_size (
151 unsigned int c_count,
152 const struct GNUNET_ABD_Delegate *cd)
153{
154 unsigned int i;
155 size_t ret;
156
157 ret = sizeof (struct DelegateEntry) * (c_count);
158
159 for (i = 0; i < c_count; i++)
160 {
161 GNUNET_assert ((ret + cd[i].issuer_attribute_len + cd[i].subject_attribute_len) >= ret);
162 // subject_attribute_len should be 0
163 ret += cd[i].issuer_attribute_len + cd[i].subject_attribute_len;
164 }
165 return ret;
166}
167/**
168 * Serizalize the given abds
169 *
170 * @param c_count number of abd entries
171 * @param cd a #GNUNET_ABD_Credential
172 * @param dest_size size of the destination
173 * @param dest where to store the result
174 * @return the size of the data, -1 on failure
175 */
176ssize_t
177GNUNET_ABD_delegates_serialize (
178 unsigned int c_count,
179 const struct GNUNET_ABD_Delegate *cd,
180 size_t dest_size,
181 char *dest)
182{
183 struct DelegateEntry c_rec;
184 unsigned int i;
185 size_t off;
186
187 off = 0;
188 for (i = 0; i < c_count; i++)
189 {
190 //c_rec.subject_attribute_len = htonl ((uint32_t) cd[i].subject_attribute_len);
191 c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
192 c_rec.issuer_key = cd[i].issuer_key;
193 c_rec.subject_key = cd[i].subject_key;
194 c_rec.signature = cd[i].signature;
195 c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
196 c_rec.purpose.size =
197 htonl ((sizeof (struct DelegateEntry) + cd[i].issuer_attribute_len) -
198 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
199 c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us);
200 if (off + sizeof (c_rec) > dest_size)
201 return -1;
202 GNUNET_memcpy (&dest[off], &c_rec, sizeof (c_rec));
203 off += sizeof (c_rec);
204 if (off + cd[i].issuer_attribute_len > dest_size)
205 return -1;
206 GNUNET_memcpy (&dest[off],
207 cd[i].issuer_attribute,
208 cd[i].issuer_attribute_len);
209 off += cd[i].issuer_attribute_len;
210 }
211
212 return off;
213}
214
215
216/**
217 * Deserialize the given destination
218 *
219 * @param len size of the serialized creds
220 * @param src the serialized data
221 * @param c_count the number of abd entries
222 * @param cd where to put the abd data
223 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
224 */
225int
226GNUNET_ABD_delegates_deserialize (size_t len,
227 const char *src,
228 unsigned int c_count,
229 struct GNUNET_ABD_Delegate *cd)
230{
231 struct DelegateEntry c_rec;
232 unsigned int i;
233 size_t off;
234
235 off = 0;
236 for (i = 0; i < c_count; i++)
237 {
238 if (off + sizeof (c_rec) > len)
239 return GNUNET_SYSERR;
240 GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
241 cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
242 cd[i].issuer_key = c_rec.issuer_key;
243 cd[i].subject_key = c_rec.subject_key;
244 cd[i].signature = c_rec.signature;
245 cd[i].expiration.abs_value_us = GNUNET_ntohll (c_rec.expiration);
246 off += sizeof (c_rec);
247 if (off + cd[i].issuer_attribute_len > len)
248 return GNUNET_SYSERR;
249 cd[i].issuer_attribute = &src[off];
250 off += cd[i].issuer_attribute_len;
251 cd[i].subject_attribute_len = 0;
252 }
253 return GNUNET_OK;
254}
255
256
257/**
258 * Calculate how many bytes we will need to serialize
259 * the given delegation chain and abd
260 *
261 * @param d_count number of delegation chain entries
262 * @param dd array of #GNUNET_ABD_Delegation
263 * @param c_count number of abd entries
264 * @param cd a #GNUNET_ABD_Credential
265 * @return the required size to serialize
266 */
267size_t
268GNUNET_ABD_delegation_chain_get_size (
269 unsigned int d_count,
270 const struct GNUNET_ABD_Delegation *dd,
271 unsigned int c_count,
272 const struct GNUNET_ABD_Delegate *cd)
273{
274 unsigned int i;
275 size_t ret;
276
277 ret = sizeof (struct ChainEntry) * (d_count);
278
279 for (i = 0; i < d_count; i++)
280 {
281 GNUNET_assert (
282 (ret + dd[i].issuer_attribute_len + dd[i].subject_attribute_len) >= ret);
283 ret += dd[i].issuer_attribute_len + dd[i].subject_attribute_len;
284 }
285 return ret + GNUNET_ABD_delegates_get_size (c_count, cd);
286}
287
288/**
289 * Serizalize the given delegation chain entries and abd
290 *
291 * @param d_count number of delegation chain entries
292 * @param dd array of #GNUNET_ABD_Delegation
293 * @param c_count number of abd entries
294 * @param cd a #GNUNET_ABD_Credential
295 * @param dest_size size of the destination
296 * @param dest where to store the result
297 * @return the size of the data, -1 on failure
298 */
299ssize_t
300GNUNET_ABD_delegation_chain_serialize (
301 unsigned int d_count,
302 const struct GNUNET_ABD_Delegation *dd,
303 unsigned int c_count,
304 const struct GNUNET_ABD_Delegate *cd,
305 size_t dest_size,
306 char *dest)
307{
308 struct ChainEntry rec;
309 unsigned int i;
310 size_t off;
311
312 off = 0;
313 for (i = 0; i < d_count; i++)
314 {
315 rec.issuer_attribute_len = htonl ((uint32_t) dd[i].issuer_attribute_len);
316 rec.subject_attribute_len = htonl ((uint32_t) dd[i].subject_attribute_len);
317 rec.issuer_key = dd[i].issuer_key;
318 rec.subject_key = dd[i].subject_key;
319 if (off + sizeof (rec) > dest_size)
320 return -1;
321 GNUNET_memcpy (&dest[off], &rec, sizeof (rec));
322 off += sizeof (rec);
323 if (off + dd[i].issuer_attribute_len > dest_size)
324 return -1;
325 GNUNET_memcpy (&dest[off],
326 dd[i].issuer_attribute,
327 dd[i].issuer_attribute_len);
328 off += dd[i].issuer_attribute_len;
329 if (0 == dd[i].subject_attribute_len)
330 continue;
331 if (off + dd[i].subject_attribute_len > dest_size)
332 return -1;
333 GNUNET_memcpy (&dest[off],
334 dd[i].subject_attribute,
335 dd[i].subject_attribute_len);
336 off += dd[i].subject_attribute_len;
337 }
338 return off + GNUNET_ABD_delegates_serialize (c_count,
339 cd,
340 dest_size - off,
341 &dest[off]);
342}
343
344
345/**
346 * Deserialize the given destination
347 *
348 * @param len size of the serialized delegation chain and cred
349 * @param src the serialized data
350 * @param d_count the number of delegation chain entries
351 * @param dd where to put the delegation chain entries
352 * @param c_count the number of abd entries
353 * @param cd where to put the abd data
354 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
355 */
356int
357GNUNET_ABD_delegation_chain_deserialize (
358 size_t len,
359 const char *src,
360 unsigned int d_count,
361 struct GNUNET_ABD_Delegation *dd,
362 unsigned int c_count,
363 struct GNUNET_ABD_Delegate *cd)
364{
365 struct ChainEntry rec;
366 unsigned int i;
367 size_t off;
368
369 off = 0;
370 for (i = 0; i < d_count; i++)
371 {
372 if (off + sizeof (rec) > len)
373 return GNUNET_SYSERR;
374 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
375 dd[i].issuer_attribute_len = ntohl ((uint32_t) rec.issuer_attribute_len);
376 dd[i].issuer_key = rec.issuer_key;
377 dd[i].subject_key = rec.subject_key;
378 off += sizeof (rec);
379 if (off + dd[i].issuer_attribute_len > len)
380 return GNUNET_SYSERR;
381 dd[i].issuer_attribute = &src[off];
382 off += dd[i].issuer_attribute_len;
383 dd[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
384 if (off + dd[i].subject_attribute_len > len)
385 return GNUNET_SYSERR;
386 dd[i].subject_attribute = &src[off];
387 off += dd[i].subject_attribute_len;
388 }
389 return GNUNET_ABD_delegates_deserialize (len - off,
390 &src[off],
391 c_count,
392 cd);
393}
394
395int
396GNUNET_ABD_delegate_serialize (struct GNUNET_ABD_Delegate *dele,
397 char **data)
398{
399 size_t size;
400 struct DelegateEntry *cdata;
401 int attr_len;
402
403 // +1 for \0
404 if (0 == dele->subject_attribute_len)
405 {
406 attr_len = dele->issuer_attribute_len + 1;
407 }
408 else
409 {
410 attr_len = dele->issuer_attribute_len + dele->subject_attribute_len + 2;
411 }
412 size = sizeof (struct DelegateEntry) + attr_len;
413
414 char tmp_str[attr_len];
415 GNUNET_memcpy (tmp_str, dele->issuer_attribute, dele->issuer_attribute_len);
416 if (0 != dele->subject_attribute_len)
417 {
418 tmp_str[dele->issuer_attribute_len] = '\0';
419 GNUNET_memcpy (tmp_str + dele->issuer_attribute_len + 1,
420 dele->subject_attribute,
421 dele->subject_attribute_len);
422 }
423 tmp_str[attr_len - 1] = '\0';
424
425 *data = GNUNET_malloc (size);
426 cdata = (struct DelegateEntry *) *data;
427 cdata->subject_key = dele->subject_key;
428 cdata->issuer_key = dele->issuer_key;
429 cdata->expiration = GNUNET_htonll (dele->expiration.abs_value_us);
430 cdata->signature = dele->signature;
431 cdata->issuer_attribute_len = htonl (dele->issuer_attribute_len + 1);
432 if (0 == dele->subject_attribute_len)
433 {
434 cdata->subject_attribute_len = htonl (0);
435 }
436 else
437 {
438 cdata->subject_attribute_len = htonl (dele->subject_attribute_len + 1);
439 }
440 cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
441 cdata->purpose.size =
442 htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
443
444 GNUNET_memcpy (&cdata[1], tmp_str, attr_len);
445
446 if (GNUNET_OK !=
447 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_DELEGATE,
448 &cdata->purpose,
449 &cdata->signature,
450 &cdata->issuer_key))
451 {
452 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n");
453 return 0;
454 }
455 return size;
456}
457
458struct GNUNET_ABD_Delegate *
459GNUNET_ABD_delegate_deserialize (const char *data, size_t data_size)
460{
461 struct GNUNET_ABD_Delegate *dele;
462 struct DelegateEntry *cdata;
463 char *attr_combo_str;
464
465 if (data_size < sizeof (struct DelegateEntry))
466 return NULL;
467 cdata = (struct DelegateEntry *) data;
468 if (GNUNET_OK !=
469 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_DELEGATE,
470 &cdata->purpose,
471 &cdata->signature,
472 &cdata->issuer_key))
473 {
474 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n");
475 return NULL;
476 }
477 attr_combo_str = (char *) &cdata[1];
478 int iss_len = ntohl (cdata->issuer_attribute_len);
479 int sub_len = ntohl (cdata->subject_attribute_len);
480 int attr_combo_len = iss_len + sub_len;
481
482 dele =
483 GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate) + attr_combo_len);
484
485 dele->issuer_key = cdata->issuer_key;
486 dele->subject_key = cdata->subject_key;
487 GNUNET_memcpy (&dele[1], attr_combo_str, attr_combo_len);
488 dele->signature = cdata->signature;
489
490 // Set the pointers for the attributes
491 dele->issuer_attribute = (char *) &dele[1];
492 dele->issuer_attribute_len = iss_len;
493 dele->subject_attribute_len = sub_len;
494 if (0 == sub_len)
495 {
496 dele->subject_attribute = NULL;
497 }
498 else
499 {
500 dele->subject_attribute = (char *) &dele[1] + iss_len;
501 }
502
503 dele->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
504
505 return dele;
506}
507
508/* end of abd_serialization.c */