aboutsummaryrefslogtreecommitdiff
path: root/src/credential/credential_serialization.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/credential/credential_serialization.c')
-rw-r--r--src/credential/credential_serialization.c460
1 files changed, 460 insertions, 0 deletions
diff --git a/src/credential/credential_serialization.c b/src/credential/credential_serialization.c
new file mode 100644
index 000000000..1d23bb08c
--- /dev/null
+++ b/src/credential/credential_serialization.c
@@ -0,0 +1,460 @@
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
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21
22/**
23 * @file credential/credential_serialization.c
24 * @brief API to serialize and deserialize delegation chains
25 * and credentials
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 "credential.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_CREDENTIAL_DelegationSet
41 * @return the required size to serialize
42 */
43size_t
44GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count,
45 const struct GNUNET_CREDENTIAL_DelegationSet *dsr)
46{
47 unsigned int i;
48 size_t ret;
49
50 ret = sizeof (struct DelegationRecordData) * (ds_count);
51
52 for (i=0; i<ds_count;i++)
53 {
54 GNUNET_assert ((ret + dsr[i].subject_attribute_len) >= ret);
55 ret += dsr[i].subject_attribute_len;
56 }
57 return ret;
58}
59
60/**
61 * Serizalize the given delegation chain entries and credential
62 *
63 * @param d_count number of delegation chain entries
64 * @param dsr array of #GNUNET_CREDENTIAL_DelegationSet
65 * @param dest_size size of the destination
66 * @param dest where to store the result
67 * @return the size of the data, -1 on failure
68 */
69ssize_t
70GNUNET_CREDENTIAL_delegation_set_serialize (unsigned int d_count,
71 const struct GNUNET_CREDENTIAL_DelegationSet *dsr,
72 size_t dest_size,
73 char *dest)
74{
75 struct DelegationRecordData rec;
76 unsigned int i;
77 size_t off;
78
79 off = 0;
80 for (i=0;i<d_count;i++)
81 {
82 rec.subject_attribute_len = htonl ((uint32_t) dsr[i].subject_attribute_len);
83 rec.subject_key = dsr[i].subject_key;
84 if (off + sizeof (rec) > dest_size)
85 return -1;
86 GNUNET_memcpy (&dest[off],
87 &rec,
88 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_CREDENTIAL_delegation_set_deserialize (size_t len,
114 const char *src,
115 unsigned int d_count,
116 struct GNUNET_CREDENTIAL_DelegationSet *dsr)
117{
118 struct DelegationRecordData rec;
119 unsigned int i;
120 size_t off;
121
122 off = 0;
123 for (i=0;i<d_count;i++)
124 {
125 if (off + sizeof (rec) > len)
126 return GNUNET_SYSERR;
127 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
128 dsr[i].subject_key = rec.subject_key;
129 off += sizeof (rec);
130 dsr[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
131 if (off + dsr[i].subject_attribute_len > len)
132 return GNUNET_SYSERR;
133 dsr[i].subject_attribute = (char*)&src[off];
134 off += dsr[i].subject_attribute_len;
135 }
136 return GNUNET_OK;
137}
138
139
140/**
141 * Calculate how many bytes we will need to serialize
142 * the credentials
143 *
144 * @param c_count number of credential entries
145 * @param cd a #GNUNET_CREDENTIAL_Credential
146 * @return the required size to serialize
147 */
148size_t
149GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count,
150 const struct GNUNET_CREDENTIAL_Credential *cd)
151{
152 unsigned int i;
153 size_t ret;
154
155 ret = sizeof (struct CredentialEntry) * (c_count);
156
157 for (i=0; i<c_count;i++)
158 {
159 GNUNET_assert ((ret + cd[i].issuer_attribute_len) >= ret);
160 ret += cd[i].issuer_attribute_len;
161 }
162 return ret;
163}
164/**
165 * Serizalize the given credentials
166 *
167 * @param c_count number of credential entries
168 * @param cd a #GNUNET_CREDENTIAL_Credential
169 * @param dest_size size of the destination
170 * @param dest where to store the result
171 * @return the size of the data, -1 on failure
172 */
173ssize_t
174GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count,
175 const struct GNUNET_CREDENTIAL_Credential *cd,
176 size_t dest_size,
177 char *dest)
178{
179 struct CredentialEntry c_rec;
180 unsigned int i;
181 size_t off;
182
183 off = 0;
184 for (i=0;i<c_count;i++)
185 {
186 c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
187 c_rec.issuer_key = cd[i].issuer_key;
188 c_rec.subject_key = cd[i].subject_key;
189 c_rec.signature = cd[i].signature;
190 c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
191 c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
192 c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us);
193 if (off + sizeof (c_rec) > dest_size)
194 return -1;
195 GNUNET_memcpy (&dest[off],
196 &c_rec,
197 sizeof (c_rec));
198 off += sizeof (c_rec);
199 if (off + cd[i].issuer_attribute_len > dest_size)
200 return -1;
201 GNUNET_memcpy (&dest[off],
202 cd[i].issuer_attribute,
203 cd[i].issuer_attribute_len);
204 off += cd[i].issuer_attribute_len;
205 }
206
207 return off;
208}
209
210
211
212/**
213 * Deserialize the given destination
214 *
215 * @param len size of the serialized creds
216 * @param src the serialized data
217 * @param c_count the number of credential entries
218 * @param cd where to put the credential data
219 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
220 */
221int
222GNUNET_CREDENTIAL_credentials_deserialize (size_t len,
223 const char *src,
224 unsigned int c_count,
225 struct GNUNET_CREDENTIAL_Credential *cd)
226{
227 struct CredentialEntry c_rec;
228 unsigned int i;
229 size_t off;
230
231 off = 0;
232 for (i=0;i<c_count;i++)
233 {
234 if (off + sizeof (c_rec) > len)
235 return GNUNET_SYSERR;
236 GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
237 cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
238 cd[i].issuer_key = c_rec.issuer_key;
239 cd[i].subject_key = c_rec.subject_key;
240 cd[i].signature = c_rec.signature;
241 cd[i].expiration.abs_value_us = GNUNET_ntohll(c_rec.expiration);
242 off += sizeof (c_rec);
243 if (off + cd[i].issuer_attribute_len > len)
244 return GNUNET_SYSERR;
245 cd[i].issuer_attribute = &src[off];
246 off += cd[i].issuer_attribute_len;
247 }
248 return GNUNET_OK;
249}
250
251
252
253/**
254 * Calculate how many bytes we will need to serialize
255 * the given delegation chain and credential
256 *
257 * @param d_count number of delegation chain entries
258 * @param dd array of #GNUNET_CREDENTIAL_Delegation
259 * @param c_count number of credential entries
260 * @param cd a #GNUNET_CREDENTIAL_Credential
261 * @return the required size to serialize
262 */
263size_t
264GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count,
265 const struct GNUNET_CREDENTIAL_Delegation *dd,
266 unsigned int c_count,
267 const struct GNUNET_CREDENTIAL_Credential *cd)
268{
269 unsigned int i;
270 size_t ret;
271
272 ret = sizeof (struct ChainEntry) * (d_count);
273
274 for (i=0; i<d_count;i++)
275 {
276 GNUNET_assert ((ret +
277 dd[i].issuer_attribute_len +
278 dd[i].subject_attribute_len) >= ret);
279 ret += dd[i].issuer_attribute_len + dd[i].subject_attribute_len;
280 }
281 return ret+GNUNET_CREDENTIAL_credentials_get_size(c_count, cd);
282 return ret;
283}
284
285/**
286 * Serizalize the given delegation chain entries and credential
287 *
288 * @param d_count number of delegation chain entries
289 * @param dd array of #GNUNET_CREDENTIAL_Delegation
290 * @param c_count number of credential entries
291 * @param cd a #GNUNET_CREDENTIAL_Credential
292 * @param dest_size size of the destination
293 * @param dest where to store the result
294 * @return the size of the data, -1 on failure
295 */
296ssize_t
297GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count,
298 const struct GNUNET_CREDENTIAL_Delegation *dd,
299 unsigned int c_count,
300 const struct GNUNET_CREDENTIAL_Credential *cd,
301 size_t dest_size,
302 char *dest)
303{
304 struct ChainEntry rec;
305 unsigned int i;
306 size_t off;
307
308 off = 0;
309 for (i=0;i<d_count;i++)
310 {
311 rec.issuer_attribute_len = htonl ((uint32_t) dd[i].issuer_attribute_len);
312 rec.subject_attribute_len = htonl ((uint32_t) dd[i].subject_attribute_len);
313 rec.issuer_key = dd[i].issuer_key;
314 rec.subject_key = dd[i].subject_key;
315 if (off + sizeof (rec) > dest_size)
316 return -1;
317 GNUNET_memcpy (&dest[off],
318 &rec,
319 sizeof (rec));
320 off += sizeof (rec);
321 if (off + dd[i].issuer_attribute_len > dest_size)
322 return -1;
323 GNUNET_memcpy (&dest[off],
324 dd[i].issuer_attribute,
325 dd[i].issuer_attribute_len);
326 off += dd[i].issuer_attribute_len;
327 if (0 == dd[i].subject_attribute_len)
328 continue;
329 if (off + dd[i].subject_attribute_len > dest_size)
330 return -1;
331 GNUNET_memcpy (&dest[off],
332 dd[i].subject_attribute,
333 dd[i].subject_attribute_len);
334 off += dd[i].subject_attribute_len;
335 }
336 return off+GNUNET_CREDENTIAL_credentials_serialize (c_count,
337 cd,
338 dest_size-off,
339 &dest[off]);
340}
341
342
343/**
344 * Deserialize the given destination
345 *
346 * @param len size of the serialized delegation chain and cred
347 * @param src the serialized data
348 * @param d_count the number of delegation chain entries
349 * @param dd where to put the delegation chain entries
350 * @param c_count the number of credential entries
351 * @param cd where to put the credential data
352 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
353 */
354int
355GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len,
356 const char *src,
357 unsigned int d_count,
358 struct GNUNET_CREDENTIAL_Delegation *dd,
359 unsigned int c_count,
360 struct GNUNET_CREDENTIAL_Credential *cd)
361{
362 struct ChainEntry rec;
363 unsigned int i;
364 size_t off;
365
366 off = 0;
367 for (i=0;i<d_count;i++)
368 {
369 if (off + sizeof (rec) > len)
370 return GNUNET_SYSERR;
371 GNUNET_memcpy (&rec, &src[off], sizeof (rec));
372 dd[i].issuer_attribute_len = ntohl ((uint32_t) rec.issuer_attribute_len);
373 dd[i].issuer_key = rec.issuer_key;
374 dd[i].subject_key = rec.subject_key;
375 off += sizeof (rec);
376 if (off + dd[i].issuer_attribute_len > len)
377 return GNUNET_SYSERR;
378 dd[i].issuer_attribute = &src[off];
379 off += dd[i].issuer_attribute_len;
380 dd[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
381 if (off + dd[i].subject_attribute_len > len)
382 return GNUNET_SYSERR;
383 dd[i].subject_attribute = &src[off];
384 off += dd[i].subject_attribute_len;
385 }
386 return GNUNET_CREDENTIAL_credentials_deserialize (len-off,
387 &src[off],
388 c_count,
389 cd);
390}
391int
392GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred,
393 char **data)
394{
395 size_t size;
396 struct CredentialEntry *cdata;
397
398 size = sizeof (struct CredentialEntry) + strlen (cred->issuer_attribute) + 1;
399 *data = GNUNET_malloc (size);
400 cdata = (struct CredentialEntry*)*data;
401 cdata->subject_key = cred->subject_key;
402 cdata->issuer_key = cred->issuer_key;
403 cdata->expiration = GNUNET_htonll (cred->expiration.abs_value_us);
404 cdata->signature = cred->signature;
405 cdata->issuer_attribute_len = htonl (strlen (cred->issuer_attribute) + 1);
406 cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
407 cdata->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
408 GNUNET_memcpy (&cdata[1],
409 cred->issuer_attribute,
410 strlen (cred->issuer_attribute));
411
412 if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL,
413 &cdata->purpose,
414 &cdata->signature,
415 &cdata->issuer_key))
416 {
417 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
418 "Invalid credential\n");
419 //return NULL;
420 }
421 return size;
422}
423
424struct GNUNET_CREDENTIAL_Credential*
425GNUNET_CREDENTIAL_credential_deserialize (const char* data,
426 size_t data_size)
427{
428 struct GNUNET_CREDENTIAL_Credential *cred;
429 struct CredentialEntry *cdata;
430 char *issuer_attribute;
431
432 if (data_size < sizeof (struct CredentialEntry))
433 return NULL;
434 cdata = (struct CredentialEntry*)data;
435 if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL,
436 &cdata->purpose,
437 &cdata->signature,
438 &cdata->issuer_key))
439 {
440 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
441 "Invalid credential\n");
442 //return NULL;
443 }
444 issuer_attribute = (char*)&cdata[1];
445
446 cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + ntohl(cdata->issuer_attribute_len));
447
448 cred->issuer_key = cdata->issuer_key;
449 cred->subject_key = cdata->subject_key;
450 GNUNET_memcpy (&cred[1],
451 issuer_attribute,
452 ntohl (cdata->issuer_attribute_len));
453 cred->signature = cdata->signature;
454 cred->issuer_attribute = (char*)&cred[1];
455 cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
456 return cred;
457}
458
459
460/* end of credential_serialization.c */