2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 GNUnet e.V.
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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
23 * @file abd/abd_serialization.c
24 * @brief API to serialize and deserialize delegation chains
26 * @author Martin Schanzenbach
29 #include "gnunet_util_lib.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_abd_service.h"
32 #include "gnunet_signatures.h"
36 * Calculate how many bytes we will need to serialize
37 * the given delegation chain
39 * @param ds_count number of delegation chain entries
40 * @param dsr array of #GNUNET_ABD_DelegationSet
41 * @return the required size to serialize
44 GNUNET_ABD_delegation_set_get_size (
45 unsigned int ds_count,
46 const struct GNUNET_ABD_DelegationSet *dsr)
51 ret = sizeof (struct DelegationRecordData) * (ds_count);
53 for (i = 0; i < ds_count; i++)
55 GNUNET_assert ((ret + dsr[i].subject_attribute_len) >= ret);
56 ret += dsr[i].subject_attribute_len;
63 * Serizalize the given delegation chain entries and abd
65 * @param d_count number of delegation chain entries
66 * @param dsr array of #GNUNET_ABD_DelegationSet
67 * @param dest_size size of the destination
68 * @param dest where to store the result
69 * @return the size of the data, -1 on failure
72 GNUNET_ABD_delegation_set_serialize (
74 const struct GNUNET_ABD_DelegationSet *dsr,
78 struct DelegationRecordData rec;
83 for (i = 0; i < d_count; i++)
85 rec.subject_attribute_len = htonl ((uint32_t) dsr[i].subject_attribute_len);
86 rec.subject_key = dsr[i].subject_key;
87 if (off + sizeof (rec) > dest_size)
89 GNUNET_memcpy (&dest[off], &rec, sizeof (rec));
91 if (0 == dsr[i].subject_attribute_len)
93 if (off + dsr[i].subject_attribute_len > dest_size)
95 GNUNET_memcpy (&dest[off],
96 dsr[i].subject_attribute,
97 dsr[i].subject_attribute_len);
98 off += dsr[i].subject_attribute_len;
105 * Deserialize the given destination
107 * @param len size of the serialized delegation chain and cred
108 * @param src the serialized data
109 * @param d_count the number of delegation chain entries
110 * @param dsr where to put the delegation chain entries
111 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
114 GNUNET_ABD_delegation_set_deserialize (
117 unsigned int d_count,
118 struct GNUNET_ABD_DelegationSet *dsr)
120 struct DelegationRecordData rec;
125 for (i = 0; i < d_count; i++)
127 if (off + sizeof (rec) > len)
128 return GNUNET_SYSERR;
129 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
130 dsr[i].subject_key = rec.subject_key;
132 dsr[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
133 if (off + dsr[i].subject_attribute_len > len)
134 return GNUNET_SYSERR;
135 dsr[i].subject_attribute = (char *) &src[off];
136 off += dsr[i].subject_attribute_len;
143 * Calculate how many bytes we will need to serialize
146 * @param c_count number of abd entries
147 * @param cd a #GNUNET_ABD_Credential
148 * @return the required size to serialize
151 GNUNET_ABD_delegates_get_size (
152 unsigned int c_count,
153 const struct GNUNET_ABD_Delegate *cd)
158 ret = sizeof (struct DelegateEntry) * (c_count);
160 for (i = 0; i < c_count; i++)
162 GNUNET_assert ((ret + cd[i].issuer_attribute_len
163 + cd[i].subject_attribute_len) >= ret);
164 // subject_attribute_len should be 0
165 ret += cd[i].issuer_attribute_len + cd[i].subject_attribute_len;
172 * Serizalize the given abds
174 * @param c_count number of abd entries
175 * @param cd a #GNUNET_ABD_Credential
176 * @param dest_size size of the destination
177 * @param dest where to store the result
178 * @return the size of the data, -1 on failure
181 GNUNET_ABD_delegates_serialize (
182 unsigned int c_count,
183 const struct GNUNET_ABD_Delegate *cd,
187 struct DelegateEntry c_rec;
192 for (i = 0; i < c_count; i++)
194 // c_rec.subject_attribute_len = htonl ((uint32_t) cd[i].subject_attribute_len);
195 c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
196 c_rec.issuer_key = cd[i].issuer_key;
197 c_rec.subject_key = cd[i].subject_key;
198 c_rec.signature = cd[i].signature;
199 c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
201 htonl ((sizeof (struct DelegateEntry) + cd[i].issuer_attribute_len)
202 - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
203 c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us);
204 if (off + sizeof (c_rec) > dest_size)
206 GNUNET_memcpy (&dest[off], &c_rec, sizeof (c_rec));
207 off += sizeof (c_rec);
208 if (off + cd[i].issuer_attribute_len > dest_size)
210 GNUNET_memcpy (&dest[off],
211 cd[i].issuer_attribute,
212 cd[i].issuer_attribute_len);
213 off += cd[i].issuer_attribute_len;
221 * Deserialize the given destination
223 * @param len size of the serialized creds
224 * @param src the serialized data
225 * @param c_count the number of abd entries
226 * @param cd where to put the abd data
227 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
230 GNUNET_ABD_delegates_deserialize (size_t len,
232 unsigned int c_count,
233 struct GNUNET_ABD_Delegate *cd)
235 struct DelegateEntry c_rec;
240 for (i = 0; i < c_count; i++)
242 if (off + sizeof (c_rec) > len)
243 return GNUNET_SYSERR;
244 GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
245 cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
246 cd[i].issuer_key = c_rec.issuer_key;
247 cd[i].subject_key = c_rec.subject_key;
248 cd[i].signature = c_rec.signature;
249 cd[i].expiration.abs_value_us = GNUNET_ntohll (c_rec.expiration);
250 off += sizeof (c_rec);
251 if (off + cd[i].issuer_attribute_len > len)
252 return GNUNET_SYSERR;
253 cd[i].issuer_attribute = &src[off];
254 off += cd[i].issuer_attribute_len;
255 cd[i].subject_attribute_len = 0;
262 * Calculate how many bytes we will need to serialize
263 * the given delegation chain and abd
265 * @param d_count number of delegation chain entries
266 * @param dd array of #GNUNET_ABD_Delegation
267 * @param c_count number of abd entries
268 * @param cd a #GNUNET_ABD_Credential
269 * @return the required size to serialize
272 GNUNET_ABD_delegation_chain_get_size (
273 unsigned int d_count,
274 const struct GNUNET_ABD_Delegation *dd,
275 unsigned int c_count,
276 const struct GNUNET_ABD_Delegate *cd)
281 ret = sizeof (struct ChainEntry) * (d_count);
283 for (i = 0; i < d_count; i++)
286 (ret + dd[i].issuer_attribute_len + dd[i].subject_attribute_len) >= ret);
287 ret += dd[i].issuer_attribute_len + dd[i].subject_attribute_len;
289 return ret + GNUNET_ABD_delegates_get_size (c_count, cd);
294 * Serizalize the given delegation chain entries and abd
296 * @param d_count number of delegation chain entries
297 * @param dd array of #GNUNET_ABD_Delegation
298 * @param c_count number of abd entries
299 * @param cd a #GNUNET_ABD_Credential
300 * @param dest_size size of the destination
301 * @param dest where to store the result
302 * @return the size of the data, -1 on failure
305 GNUNET_ABD_delegation_chain_serialize (
306 unsigned int d_count,
307 const struct GNUNET_ABD_Delegation *dd,
308 unsigned int c_count,
309 const struct GNUNET_ABD_Delegate *cd,
313 struct ChainEntry rec;
318 for (i = 0; i < d_count; i++)
320 rec.issuer_attribute_len = htonl ((uint32_t) dd[i].issuer_attribute_len);
321 rec.subject_attribute_len = htonl ((uint32_t) dd[i].subject_attribute_len);
322 rec.issuer_key = dd[i].issuer_key;
323 rec.subject_key = dd[i].subject_key;
324 if (off + sizeof (rec) > dest_size)
326 GNUNET_memcpy (&dest[off], &rec, sizeof (rec));
328 if (off + dd[i].issuer_attribute_len > dest_size)
330 GNUNET_memcpy (&dest[off],
331 dd[i].issuer_attribute,
332 dd[i].issuer_attribute_len);
333 off += dd[i].issuer_attribute_len;
334 if (0 == dd[i].subject_attribute_len)
336 if (off + dd[i].subject_attribute_len > dest_size)
338 GNUNET_memcpy (&dest[off],
339 dd[i].subject_attribute,
340 dd[i].subject_attribute_len);
341 off += dd[i].subject_attribute_len;
343 return off + GNUNET_ABD_delegates_serialize (c_count,
351 * Deserialize the given destination
353 * @param len size of the serialized delegation chain and cred
354 * @param src the serialized data
355 * @param d_count the number of delegation chain entries
356 * @param dd where to put the delegation chain entries
357 * @param c_count the number of abd entries
358 * @param cd where to put the abd data
359 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
362 GNUNET_ABD_delegation_chain_deserialize (
365 unsigned int d_count,
366 struct GNUNET_ABD_Delegation *dd,
367 unsigned int c_count,
368 struct GNUNET_ABD_Delegate *cd)
370 struct ChainEntry rec;
375 for (i = 0; i < d_count; i++)
377 if (off + sizeof (rec) > len)
378 return GNUNET_SYSERR;
379 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
380 dd[i].issuer_attribute_len = ntohl ((uint32_t) rec.issuer_attribute_len);
381 dd[i].issuer_key = rec.issuer_key;
382 dd[i].subject_key = rec.subject_key;
384 if (off + dd[i].issuer_attribute_len > len)
385 return GNUNET_SYSERR;
386 dd[i].issuer_attribute = &src[off];
387 off += dd[i].issuer_attribute_len;
388 dd[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
389 if (off + dd[i].subject_attribute_len > len)
390 return GNUNET_SYSERR;
391 dd[i].subject_attribute = &src[off];
392 off += dd[i].subject_attribute_len;
394 return GNUNET_ABD_delegates_deserialize (len - off,
402 GNUNET_ABD_delegate_serialize (struct GNUNET_ABD_Delegate *dele,
406 struct DelegateEntry *cdata;
410 if (0 == dele->subject_attribute_len)
412 attr_len = dele->issuer_attribute_len + 1;
416 attr_len = dele->issuer_attribute_len + dele->subject_attribute_len + 2;
418 size = sizeof (struct DelegateEntry) + attr_len;
420 char tmp_str[attr_len];
421 GNUNET_memcpy (tmp_str, dele->issuer_attribute, dele->issuer_attribute_len);
422 if (0 != dele->subject_attribute_len)
424 tmp_str[dele->issuer_attribute_len] = '\0';
425 GNUNET_memcpy (tmp_str + dele->issuer_attribute_len + 1,
426 dele->subject_attribute,
427 dele->subject_attribute_len);
429 tmp_str[attr_len - 1] = '\0';
431 *data = GNUNET_malloc (size);
432 cdata = (struct DelegateEntry *) *data;
433 cdata->subject_key = dele->subject_key;
434 cdata->issuer_key = dele->issuer_key;
435 cdata->expiration = GNUNET_htonll (dele->expiration.abs_value_us);
436 cdata->signature = dele->signature;
437 cdata->issuer_attribute_len = htonl (dele->issuer_attribute_len + 1);
438 if (0 == dele->subject_attribute_len)
440 cdata->subject_attribute_len = htonl (0);
444 cdata->subject_attribute_len = htonl (dele->subject_attribute_len + 1);
446 cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DELEGATE);
447 cdata->purpose.size =
448 htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
450 GNUNET_memcpy (&cdata[1], tmp_str, attr_len);
453 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_DELEGATE,
458 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Serialize: Invalid delegate\n");
465 struct GNUNET_ABD_Delegate *
466 GNUNET_ABD_delegate_deserialize (const char *data, size_t data_size)
468 struct GNUNET_ABD_Delegate *dele;
469 struct DelegateEntry *cdata;
470 char *attr_combo_str;
472 if (data_size < sizeof (struct DelegateEntry))
474 cdata = (struct DelegateEntry *) data;
476 GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_DELEGATE,
481 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deserialize: Invalid delegate\n");
484 attr_combo_str = (char *) &cdata[1];
485 int iss_len = ntohl (cdata->issuer_attribute_len);
486 int sub_len = ntohl (cdata->subject_attribute_len);
487 int attr_combo_len = iss_len + sub_len;
490 GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate) + attr_combo_len);
492 dele->issuer_key = cdata->issuer_key;
493 dele->subject_key = cdata->subject_key;
494 GNUNET_memcpy (&dele[1], attr_combo_str, attr_combo_len);
495 dele->signature = cdata->signature;
497 // Set the pointers for the attributes
498 dele->issuer_attribute = (char *) &dele[1];
499 dele->issuer_attribute_len = iss_len;
500 dele->subject_attribute_len = sub_len;
503 dele->subject_attribute = NULL;
507 dele->subject_attribute = (char *) &dele[1] + iss_len;
510 dele->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
516 /* end of abd_serialization.c */