aboutsummaryrefslogtreecommitdiff
path: root/src/service/reclaim/reclaim_credential.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/reclaim/reclaim_credential.c')
-rw-r--r--src/service/reclaim/reclaim_credential.c1003
1 files changed, 1003 insertions, 0 deletions
diff --git a/src/service/reclaim/reclaim_credential.c b/src/service/reclaim/reclaim_credential.c
new file mode 100644
index 000000000..a0cb7a62e
--- /dev/null
+++ b/src/service/reclaim/reclaim_credential.c
@@ -0,0 +1,1003 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2015 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 * @file reclaim/reclaim_credential.c
23 * @brief helper library to manage identity attribute credentials
24 * @author Martin Schanzenbach
25 */
26#include "gnunet_util_lib.h"
27#include "gnunet_reclaim_plugin.h"
28#include "reclaim_credential.h"
29
30
31/**
32 * Handle for a plugin
33 */
34struct Plugin
35{
36 /**
37 * Name of the plugin
38 */
39 char *library_name;
40
41 /**
42 * Plugin API
43 */
44 struct GNUNET_RECLAIM_CredentialPluginFunctions *api;
45};
46
47
48/**
49 * Plugins
50 */
51static struct Plugin **credential_plugins;
52
53
54/**
55 * Number of plugins
56 */
57static unsigned int num_plugins;
58
59
60/**
61 * Init canary
62 */
63static int initialized;
64
65
66/**
67 * Add a plugin
68 *
69 * @param cls closure
70 * @param library_name name of the API library
71 * @param lib_ret the plugin API pointer
72 */
73static void
74add_plugin (void *cls, const char *library_name, void *lib_ret)
75{
76 struct GNUNET_RECLAIM_CredentialPluginFunctions *api = lib_ret;
77 struct Plugin *plugin;
78
79 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
80 "Loading credential plugin `%s'\n",
81 library_name);
82 plugin = GNUNET_new (struct Plugin);
83 plugin->api = api;
84 plugin->library_name = GNUNET_strdup (library_name);
85 GNUNET_array_append (credential_plugins, num_plugins, plugin);
86}
87
88
89/**
90 * Load plugins
91 */
92static void
93init ()
94{
95 if (GNUNET_YES == initialized)
96 return;
97 initialized = GNUNET_YES;
98 GNUNET_PLUGIN_load_all_in_context (GNUNET_OS_project_data_default (),
99 "libgnunet_plugin_reclaim_credential_",
100 NULL,
101 &add_plugin,
102 NULL);
103}
104
105
106/**
107 * Dual function to #init().
108 */
109void __attribute__ ((destructor))
110RECLAIM_CREDENTIAL_fini ()
111{
112 struct Plugin *plugin;
113 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
114 const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
115
116 if (pd != dpd)
117 GNUNET_OS_init (dpd);
118
119 for (unsigned int i = 0; i < num_plugins; i++)
120 {
121 plugin = credential_plugins[i];
122 GNUNET_break (NULL ==
123 GNUNET_PLUGIN_unload (plugin->library_name,
124 plugin->api));
125 GNUNET_free (plugin->library_name);
126 GNUNET_free (plugin);
127 }
128 GNUNET_free (credential_plugins);
129
130 if (pd != dpd)
131 GNUNET_OS_init (pd);
132
133 credential_plugins = NULL;
134}
135
136
137/**
138 * Convert an credential type name to the corresponding number
139 *
140 * @param typename name to convert
141 * @return corresponding number, UINT32_MAX on error
142 */
143uint32_t
144GNUNET_RECLAIM_credential_typename_to_number (const char *typename)
145{
146 unsigned int i;
147 struct Plugin *plugin;
148 uint32_t ret;
149 init ();
150 for (i = 0; i < num_plugins; i++)
151 {
152 plugin = credential_plugins[i];
153 if (UINT32_MAX !=
154 (ret = plugin->api->typename_to_number (plugin->api->cls,
155 typename)))
156 return ret;
157 }
158 return UINT32_MAX;
159}
160
161
162/**
163 * Convert an credential type number to the corresponding credential type string
164 *
165 * @param type number of a type
166 * @return corresponding typestring, NULL on error
167 */
168const char *
169GNUNET_RECLAIM_credential_number_to_typename (uint32_t type)
170{
171 unsigned int i;
172 struct Plugin *plugin;
173 const char *ret;
174
175 init ();
176 for (i = 0; i < num_plugins; i++)
177 {
178 plugin = credential_plugins[i];
179 if (NULL !=
180 (ret = plugin->api->number_to_typename (plugin->api->cls, type)))
181 return ret;
182 }
183 return NULL;
184}
185
186
187/**
188 * Convert human-readable version of a 'claim' of an credential to the binary
189 * representation
190 *
191 * @param type type of the claim
192 * @param s human-readable string
193 * @param data set to value in binary encoding (will be allocated)
194 * @param data_size set to number of bytes in @a data
195 * @return #GNUNET_OK on success
196 */
197int
198GNUNET_RECLAIM_credential_string_to_value (uint32_t type,
199 const char *s,
200 void **data,
201 size_t *data_size)
202{
203 unsigned int i;
204 struct Plugin *plugin;
205
206 init ();
207 for (i = 0; i < num_plugins; i++)
208 {
209 plugin = credential_plugins[i];
210 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
211 type,
212 s,
213 data,
214 data_size))
215 return GNUNET_OK;
216 }
217 return GNUNET_SYSERR;
218}
219
220
221/**
222 * Convert the 'claim' of an credential to a string
223 *
224 * @param type the type of credential
225 * @param data claim in binary encoding
226 * @param data_size number of bytes in @a data
227 * @return NULL on error, otherwise human-readable representation of the claim
228 */
229char *
230GNUNET_RECLAIM_credential_value_to_string (uint32_t type,
231 const void *data,
232 size_t data_size)
233{
234 unsigned int i;
235 struct Plugin *plugin;
236 char *ret;
237
238 init ();
239 for (i = 0; i < num_plugins; i++)
240 {
241 plugin = credential_plugins[i];
242 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
243 type,
244 data,
245 data_size)))
246 return ret;
247 }
248 return NULL;
249}
250
251
252struct GNUNET_RECLAIM_Credential *
253GNUNET_RECLAIM_credential_new (const char *attr_name,
254 uint32_t type,
255 const void *data,
256 size_t data_size)
257{
258 struct GNUNET_RECLAIM_Credential *attr;
259 char *write_ptr;
260 char *attr_name_tmp = GNUNET_strdup (attr_name);
261
262 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
263
264 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Credential)
265 + strlen (attr_name_tmp) + 1 + data_size);
266 attr->type = type;
267 attr->data_size = data_size;
268 attr->flag = 0;
269 write_ptr = (char *) &attr[1];
270 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
271 attr->name = write_ptr;
272 write_ptr += strlen (attr->name) + 1;
273 GNUNET_memcpy (write_ptr, data, data_size);
274 attr->data = write_ptr;
275 GNUNET_free (attr_name_tmp);
276 return attr;
277}
278
279
280/**
281 * Get required size for serialization buffer
282 *
283 * @param attrs the attribute list to serialize
284 * @return the required buffer size
285 */
286size_t
287GNUNET_RECLAIM_credential_list_serialize_get_size (
288 const struct GNUNET_RECLAIM_CredentialList *credentials)
289{
290 struct GNUNET_RECLAIM_CredentialListEntry *le;
291 size_t len = 0;
292
293 for (le = credentials->list_head; NULL != le; le = le->next)
294 {
295 GNUNET_assert (NULL != le->credential);
296 len += GNUNET_RECLAIM_credential_serialize_get_size (le->credential);
297 len += sizeof(struct GNUNET_RECLAIM_CredentialListEntry);
298 }
299 return len;
300}
301
302
303size_t
304GNUNET_RECLAIM_credential_list_serialize (
305 const struct GNUNET_RECLAIM_CredentialList *credentials,
306 char *result)
307{
308 struct GNUNET_RECLAIM_CredentialListEntry *le;
309 size_t len;
310 size_t total_len;
311 char *write_ptr;
312 write_ptr = result;
313 total_len = 0;
314 for (le = credentials->list_head; NULL != le; le = le->next)
315 {
316 GNUNET_assert (NULL != le->credential);
317 len = GNUNET_RECLAIM_credential_serialize (le->credential, write_ptr);
318 total_len += len;
319 write_ptr += len;
320 }
321 return total_len;
322}
323
324
325struct GNUNET_RECLAIM_CredentialList *
326GNUNET_RECLAIM_credential_list_deserialize (const char *data, size_t data_size)
327{
328 struct GNUNET_RECLAIM_CredentialList *al;
329 struct GNUNET_RECLAIM_CredentialListEntry *ale;
330 size_t att_len;
331 const char *read_ptr;
332
333 al = GNUNET_new (struct GNUNET_RECLAIM_CredentialList);
334
335 if ((data_size < sizeof(struct
336 Credential)
337 + sizeof(struct GNUNET_RECLAIM_CredentialListEntry)))
338 return al;
339
340 read_ptr = data;
341 while (((data + data_size) - read_ptr) >= sizeof(struct Credential))
342 {
343 ale = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry);
344 ale->credential =
345 GNUNET_RECLAIM_credential_deserialize (read_ptr,
346 data_size - (read_ptr - data));
347 if (NULL == ale->credential)
348 {
349 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
350 "Failed to deserialize malformed credential.\n");
351 GNUNET_free (ale);
352 return al;
353 }
354 GNUNET_CONTAINER_DLL_insert (al->list_head, al->list_tail, ale);
355 att_len = GNUNET_RECLAIM_credential_serialize_get_size (ale->credential);
356 read_ptr += att_len;
357 }
358 return al;
359}
360
361
362/**
363 * Make a (deep) copy of the credential list
364 * @param attrs claim list to copy
365 * @return copied claim list
366 */
367struct GNUNET_RECLAIM_CredentialList *
368GNUNET_RECLAIM_credential_list_dup (
369 const struct GNUNET_RECLAIM_CredentialList *al)
370{
371 struct GNUNET_RECLAIM_CredentialListEntry *ale;
372 struct GNUNET_RECLAIM_CredentialListEntry *result_ale;
373 struct GNUNET_RECLAIM_CredentialList *result;
374
375 result = GNUNET_new (struct GNUNET_RECLAIM_CredentialList);
376 for (ale = al->list_head; NULL != ale; ale = ale->next)
377 {
378 result_ale = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry);
379 GNUNET_assert (NULL != ale->credential);
380 result_ale->credential =
381 GNUNET_RECLAIM_credential_new (ale->credential->name,
382 ale->credential->type,
383 ale->credential->data,
384 ale->credential->data_size);
385 result_ale->credential->id = ale->credential->id;
386 GNUNET_CONTAINER_DLL_insert (result->list_head,
387 result->list_tail,
388 result_ale);
389 }
390 return result;
391}
392
393
394void
395GNUNET_RECLAIM_credential_list_destroy (
396 struct GNUNET_RECLAIM_CredentialList *credentials)
397{
398 struct GNUNET_RECLAIM_CredentialListEntry *ale;
399 struct GNUNET_RECLAIM_CredentialListEntry *tmp_ale;
400
401 for (ale = credentials->list_head; NULL != ale;)
402 {
403 if (NULL != ale->credential)
404 GNUNET_free (ale->credential);
405 tmp_ale = ale;
406 ale = ale->next;
407 GNUNET_free (tmp_ale);
408 }
409 GNUNET_free (credentials);
410}
411
412
413/**
414 * Get required size for serialization buffer
415 *
416 * @param attr the credential to serialize
417 * @return the required buffer size
418 */
419size_t
420GNUNET_RECLAIM_credential_serialize_get_size (
421 const struct GNUNET_RECLAIM_Credential *credential)
422{
423 return sizeof(struct Credential) + strlen (credential->name)
424 + credential->data_size;
425}
426
427
428size_t
429GNUNET_RECLAIM_credential_serialize (
430 const struct GNUNET_RECLAIM_Credential *credential,
431 char *result)
432{
433 size_t data_len_ser;
434 size_t name_len;
435 struct Credential *atts;
436 char *write_ptr;
437
438 atts = (struct Credential *) result;
439 atts->credential_type = htonl (credential->type);
440 atts->credential_flag = htonl (credential->flag);
441 atts->credential_id = credential->id;
442 name_len = strlen (credential->name);
443 atts->name_len = htons (name_len);
444 write_ptr = (char *) &atts[1];
445 GNUNET_memcpy (write_ptr, credential->name, name_len);
446 write_ptr += name_len;
447 // TODO plugin-ize
448 // data_len_ser = plugin->serialize_attribute_value (attr,
449 // &attr_ser[1]);
450 data_len_ser = credential->data_size;
451 GNUNET_memcpy (write_ptr, credential->data, credential->data_size);
452 atts->data_size = htons (data_len_ser);
453
454 return sizeof(struct Credential) + strlen (credential->name)
455 + credential->data_size;
456}
457
458
459/**
460 * Deserialize an credential
461 *
462 * @param data the serialized credential
463 * @param data_size the length of the serialized data
464 *
465 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
466 */
467struct GNUNET_RECLAIM_Credential *
468GNUNET_RECLAIM_credential_deserialize (const char *data, size_t data_size)
469{
470 struct GNUNET_RECLAIM_Credential *credential;
471 struct Credential *atts;
472 size_t data_len;
473 size_t name_len;
474 char *write_ptr;
475
476 if (data_size < sizeof(struct Credential))
477 return NULL;
478
479 atts = (struct Credential *) data;
480 data_len = ntohs (atts->data_size);
481 name_len = ntohs (atts->name_len);
482 if (data_size < sizeof(struct Credential) + data_len + name_len)
483 {
484 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
485 "Buffer too small to deserialize\n");
486 return NULL;
487 }
488 credential = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Credential)
489 + data_len + name_len + 1);
490 credential->type = ntohl (atts->credential_type);
491 credential->flag = ntohl (atts->credential_flag);
492 credential->id = atts->credential_id;
493 credential->data_size = data_len;
494
495 write_ptr = (char *) &credential[1];
496 GNUNET_memcpy (write_ptr, &atts[1], name_len);
497 write_ptr[name_len] = '\0';
498 credential->name = write_ptr;
499
500 write_ptr += name_len + 1;
501 GNUNET_memcpy (write_ptr, (char *) &atts[1] + name_len,
502 credential->data_size);
503 credential->data = write_ptr;
504 return credential;
505}
506
507
508struct GNUNET_RECLAIM_AttributeList*
509GNUNET_RECLAIM_credential_get_attributes (const struct
510 GNUNET_RECLAIM_Credential *credential)
511{
512 unsigned int i;
513 struct Plugin *plugin;
514 struct GNUNET_RECLAIM_AttributeList *ret;
515 init ();
516 for (i = 0; i < num_plugins; i++)
517 {
518 plugin = credential_plugins[i];
519 if (NULL !=
520 (ret = plugin->api->get_attributes (plugin->api->cls,
521 credential)))
522 return ret;
523 }
524 return NULL;
525}
526
527
528char*
529GNUNET_RECLAIM_credential_get_issuer (const struct
530 GNUNET_RECLAIM_Credential *credential)
531{
532 unsigned int i;
533 struct Plugin *plugin;
534 char *ret;
535 init ();
536 for (i = 0; i < num_plugins; i++)
537 {
538 plugin = credential_plugins[i];
539 if (NULL !=
540 (ret = plugin->api->get_issuer (plugin->api->cls,
541 credential)))
542 return ret;
543 }
544 return NULL;
545}
546
547
548int
549GNUNET_RECLAIM_credential_get_expiration (const struct
550 GNUNET_RECLAIM_Credential *credential,
551 struct GNUNET_TIME_Absolute*exp)
552{
553 unsigned int i;
554 struct Plugin *plugin;
555 init ();
556 for (i = 0; i < num_plugins; i++)
557 {
558 plugin = credential_plugins[i];
559 if (GNUNET_OK != plugin->api->get_expiration (plugin->api->cls,
560 credential,
561 exp))
562 continue;
563 return GNUNET_OK;
564 }
565 return GNUNET_SYSERR;
566}
567
568
569/**
570 * Convert an presentation type name to the corresponding number
571 *
572 * @param typename name to convert
573 * @return corresponding number, UINT32_MAX on error
574 */
575uint32_t
576GNUNET_RECLAIM_presentation_typename_to_number (const char *typename)
577{
578 unsigned int i;
579 struct Plugin *plugin;
580 uint32_t ret;
581 init ();
582 for (i = 0; i < num_plugins; i++)
583 {
584 plugin = credential_plugins[i];
585 if (UINT32_MAX !=
586 (ret = plugin->api->typename_to_number_p (plugin->api->cls,
587 typename)))
588 return ret;
589 }
590 return UINT32_MAX;
591}
592
593
594const char *
595GNUNET_RECLAIM_presentation_number_to_typename (uint32_t type)
596{
597 unsigned int i;
598 struct Plugin *plugin;
599 const char *ret;
600
601 init ();
602 for (i = 0; i < num_plugins; i++)
603 {
604 plugin = credential_plugins[i];
605 if (NULL !=
606 (ret = plugin->api->number_to_typename_p (plugin->api->cls, type)))
607 return ret;
608 }
609 return NULL;
610}
611
612
613/**
614 * Convert human-readable version of a 'claim' of an presentation to the binary
615 * representation
616 *
617 * @param type type of the claim
618 * @param s human-readable string
619 * @param data set to value in binary encoding (will be allocated)
620 * @param data_size set to number of bytes in @a data
621 * @return #GNUNET_OK on success
622 */
623int
624GNUNET_RECLAIM_presentation_string_to_value (uint32_t type,
625 const char *s,
626 void **data,
627 size_t *data_size)
628{
629 unsigned int i;
630 struct Plugin *plugin;
631
632 init ();
633 for (i = 0; i < num_plugins; i++)
634 {
635 plugin = credential_plugins[i];
636 if (GNUNET_OK == plugin->api->string_to_value_p (plugin->api->cls,
637 type,
638 s,
639 data,
640 data_size))
641 return GNUNET_OK;
642 }
643 return GNUNET_SYSERR;
644}
645
646
647/**
648 * Convert the 'claim' of an presentation to a string
649 *
650 * @param type the type of presentation
651 * @param data claim in binary encoding
652 * @param data_size number of bytes in @a data
653 * @return NULL on error, otherwise human-readable representation of the claim
654 */
655char *
656GNUNET_RECLAIM_presentation_value_to_string (uint32_t type,
657 const void *data,
658 size_t data_size)
659{
660 unsigned int i;
661 struct Plugin *plugin;
662 char *ret;
663
664 init ();
665 for (i = 0; i < num_plugins; i++)
666 {
667 plugin = credential_plugins[i];
668 if (NULL != (ret = plugin->api->value_to_string_p (plugin->api->cls,
669 type,
670 data,
671 data_size)))
672 return ret;
673 }
674 return NULL;
675}
676
677
678struct GNUNET_RECLAIM_Presentation *
679GNUNET_RECLAIM_presentation_new (uint32_t type,
680 const void *data,
681 size_t data_size)
682{
683 struct GNUNET_RECLAIM_Presentation *attr;
684 char *write_ptr;
685
686 attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Presentation)
687 + data_size);
688 attr->type = type;
689 attr->data_size = data_size;
690 write_ptr = (char *) &attr[1];
691 GNUNET_memcpy (write_ptr, data, data_size);
692 attr->data = write_ptr;
693 return attr;
694}
695
696
697/**
698 * Get required size for serialization buffer
699 *
700 * @param attrs the attribute list to serialize
701 * @return the required buffer size
702 */
703size_t
704GNUNET_RECLAIM_presentation_list_serialize_get_size (
705 const struct GNUNET_RECLAIM_PresentationList *presentations)
706{
707 struct GNUNET_RECLAIM_PresentationListEntry *le;
708 size_t len = 0;
709
710 for (le = presentations->list_head; NULL != le; le = le->next)
711 {
712 GNUNET_assert (NULL != le->presentation);
713 len += GNUNET_RECLAIM_presentation_serialize_get_size (le->presentation);
714 }
715 return len;
716}
717
718
719size_t
720GNUNET_RECLAIM_presentation_list_serialize (
721 const struct GNUNET_RECLAIM_PresentationList *presentations,
722 char *result)
723{
724 struct GNUNET_RECLAIM_PresentationListEntry *le;
725 size_t len;
726 size_t total_len;
727 char *write_ptr;
728 write_ptr = result;
729 total_len = 0;
730 for (le = presentations->list_head; NULL != le; le = le->next)
731 {
732 GNUNET_assert (NULL != le->presentation);
733 len = GNUNET_RECLAIM_presentation_serialize (le->presentation, write_ptr);
734 total_len += len;
735 write_ptr += len;
736 }
737 return total_len;
738}
739
740
741/**
742 * Deserialize an presentation list
743 *
744 * @param data the serialized attribute list
745 * @param data_size the length of the serialized data
746 * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller
747 */
748struct GNUNET_RECLAIM_PresentationList *
749GNUNET_RECLAIM_presentation_list_deserialize (const char *data, size_t
750 data_size)
751{
752 struct GNUNET_RECLAIM_PresentationList *al;
753 struct GNUNET_RECLAIM_PresentationListEntry *ale;
754 size_t att_len;
755 const char *read_ptr;
756
757 al = GNUNET_new (struct GNUNET_RECLAIM_PresentationList);
758
759 if (data_size < sizeof(struct Presentation))
760 return al;
761
762 read_ptr = data;
763 while (((data + data_size) - read_ptr) >= sizeof(struct Presentation))
764 {
765 ale = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry);
766 ale->presentation =
767 GNUNET_RECLAIM_presentation_deserialize (read_ptr,
768 data_size - (read_ptr - data));
769 if (NULL == ale->presentation)
770 {
771 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
772 "Failed to deserialize malformed presentation.\n");
773 GNUNET_free (ale);
774 return al;
775 }
776 GNUNET_CONTAINER_DLL_insert (al->list_head, al->list_tail, ale);
777 att_len = GNUNET_RECLAIM_presentation_serialize_get_size (
778 ale->presentation);
779 read_ptr += att_len;
780 }
781 return al;
782}
783
784
785/**
786 * Make a (deep) copy of the presentation list
787 * @param attrs claim list to copy
788 * @return copied claim list
789 */
790struct GNUNET_RECLAIM_PresentationList *
791GNUNET_RECLAIM_presentation_list_dup (
792 const struct GNUNET_RECLAIM_PresentationList *al)
793{
794 struct GNUNET_RECLAIM_PresentationListEntry *ale;
795 struct GNUNET_RECLAIM_PresentationListEntry *result_ale;
796 struct GNUNET_RECLAIM_PresentationList *result;
797
798 result = GNUNET_new (struct GNUNET_RECLAIM_PresentationList);
799 for (ale = al->list_head; NULL != ale; ale = ale->next)
800 {
801 result_ale = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry);
802 GNUNET_assert (NULL != ale->presentation);
803 result_ale->presentation =
804 GNUNET_RECLAIM_presentation_new (ale->presentation->type,
805 ale->presentation->data,
806 ale->presentation->data_size);
807 result_ale->presentation->credential_id = ale->presentation->credential_id;
808 GNUNET_CONTAINER_DLL_insert (result->list_head,
809 result->list_tail,
810 result_ale);
811 }
812 return result;
813}
814
815
816void
817GNUNET_RECLAIM_presentation_list_destroy (
818 struct GNUNET_RECLAIM_PresentationList *presentations)
819{
820 struct GNUNET_RECLAIM_PresentationListEntry *ale;
821 struct GNUNET_RECLAIM_PresentationListEntry *tmp_ale;
822
823 for (ale = presentations->list_head; NULL != ale;)
824 {
825 if (NULL != ale->presentation)
826 GNUNET_free (ale->presentation);
827 tmp_ale = ale;
828 ale = ale->next;
829 GNUNET_free (tmp_ale);
830 }
831 GNUNET_free (presentations);
832}
833
834
835/**
836 * Get required size for serialization buffer
837 *
838 * @param attr the presentation to serialize
839 * @return the required buffer size
840 */
841size_t
842GNUNET_RECLAIM_presentation_serialize_get_size (
843 const struct GNUNET_RECLAIM_Presentation *presentation)
844{
845 return sizeof(struct Presentation) + presentation->data_size;
846}
847
848
849size_t
850GNUNET_RECLAIM_presentation_serialize (
851 const struct GNUNET_RECLAIM_Presentation *presentation,
852 char *result)
853{
854 struct Presentation *atts;
855 char *write_ptr;
856
857 atts = (struct Presentation *) result;
858 atts->presentation_type = htonl (presentation->type);
859 atts->credential_id = presentation->credential_id;
860 write_ptr = (char *) &atts[1];
861 GNUNET_memcpy (write_ptr, presentation->data, presentation->data_size);
862 atts->data_size = htons (presentation->data_size);
863
864 return sizeof(struct Presentation) + presentation->data_size;
865}
866
867
868/**
869 * Deserialize an presentation
870 *
871 * @param data the serialized presentation
872 * @param data_size the length of the serialized data
873 *
874 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
875 */
876struct GNUNET_RECLAIM_Presentation *
877GNUNET_RECLAIM_presentation_deserialize (const char *data, size_t data_size)
878{
879 struct GNUNET_RECLAIM_Presentation *presentation;
880 struct Presentation *atts;
881 size_t data_len;
882 char *write_ptr;
883
884 if (data_size < sizeof(struct Presentation))
885 return NULL;
886
887 atts = (struct Presentation *) data;
888 data_len = ntohs (atts->data_size);
889 if (data_size < sizeof(struct Presentation) + data_len)
890 {
891 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
892 "Buffer too small to deserialize\n");
893 return NULL;
894 }
895 presentation = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Presentation)
896 + data_len);
897 presentation->type = ntohl (atts->presentation_type);
898 presentation->credential_id = atts->credential_id;
899 presentation->data_size = data_len;
900
901 write_ptr = (char *) &presentation[1];
902 GNUNET_memcpy (write_ptr, &atts[1], data_len);
903 presentation->data = write_ptr;
904 return presentation;
905}
906
907
908struct GNUNET_RECLAIM_AttributeList*
909GNUNET_RECLAIM_presentation_get_attributes (const struct
910 GNUNET_RECLAIM_Presentation *
911 presentation)
912{
913 unsigned int i;
914 struct Plugin *plugin;
915 struct GNUNET_RECLAIM_AttributeList *ret;
916 init ();
917 for (i = 0; i < num_plugins; i++)
918 {
919 plugin = credential_plugins[i];
920 if (NULL !=
921 (ret = plugin->api->get_attributes_p (plugin->api->cls,
922 presentation)))
923 return ret;
924 }
925 return NULL;
926}
927
928
929char*
930GNUNET_RECLAIM_presentation_get_issuer (const struct
931 GNUNET_RECLAIM_Presentation *
932 presentation)
933{
934 unsigned int i;
935 struct Plugin *plugin;
936 char *ret;
937 init ();
938 for (i = 0; i < num_plugins; i++)
939 {
940 plugin = credential_plugins[i];
941 if (NULL !=
942 (ret = plugin->api->get_issuer_p (plugin->api->cls,
943 presentation)))
944 return ret;
945 }
946 return NULL;
947}
948
949
950int
951GNUNET_RECLAIM_presentation_get_expiration (const struct
952 GNUNET_RECLAIM_Presentation *
953 presentation,
954 struct GNUNET_TIME_Absolute*exp)
955{
956 unsigned int i;
957 struct Plugin *plugin;
958 init ();
959 for (i = 0; i < num_plugins; i++)
960 {
961 plugin = credential_plugins[i];
962 if (GNUNET_OK != plugin->api->get_expiration_p (plugin->api->cls,
963 presentation,
964 exp))
965 continue;
966 return GNUNET_OK;
967 }
968 return GNUNET_SYSERR;
969}
970
971
972/**
973 * Create a presentation from a credential and a lift of (selected)
974 * attributes in the credential.
975 *
976 * @param cred the credential to use
977 * @param attrs the attributes to present from the credential
978 * @return the credential presentation presenting the attributes according
979 * to the presentation mechanism of the credential
980 * or NULL on error.
981 */
982int
983GNUNET_RECLAIM_credential_get_presentation (
984 const struct GNUNET_RECLAIM_Credential *cred,
985 const struct GNUNET_RECLAIM_AttributeList *attrs,
986 struct GNUNET_RECLAIM_Presentation **presentation)
987{
988 unsigned int i;
989 struct Plugin *plugin;
990 init ();
991 for (i = 0; i < num_plugins; i++)
992 {
993 plugin = credential_plugins[i];
994 if (GNUNET_OK != plugin->api->create_presentation (plugin->api->cls,
995 cred,
996 attrs,
997 presentation))
998 continue;
999 (*presentation)->credential_id = cred->id;
1000 return GNUNET_OK;
1001 }
1002 return GNUNET_SYSERR;
1003}