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