2 This file is part of GNUnet.
3 Copyright (C) 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
22 * @file reclaim/reclaim_api.c
23 * @brief api to interact with the reclaim service
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_mq_lib.h"
30 #include "gnunet_protocols.h"
31 #include "gnunet_reclaim_lib.h"
32 #include "gnunet_reclaim_service.h"
35 #define LOG(kind, ...) GNUNET_log_from (kind, "reclaim-api", __VA_ARGS__)
39 * Handle for an operation with the service.
41 struct GNUNET_RECLAIM_Operation
46 struct GNUNET_RECLAIM_Handle *h;
49 * We keep operations in a DLL.
51 struct GNUNET_RECLAIM_Operation *next;
54 * We keep operations in a DLL.
56 struct GNUNET_RECLAIM_Operation *prev;
59 * Message to send to the service.
60 * Allocated at the end of this struct.
62 const struct GNUNET_MessageHeader *msg;
65 * Continuation to invoke after attribute store call
67 GNUNET_RECLAIM_ContinuationWithStatus as_cb;
70 * Attribute result callback
72 GNUNET_RECLAIM_AttributeResult ar_cb;
75 * Attribute result callback
77 GNUNET_RECLAIM_AttributeTicketResult atr_cb;
80 * Attestation result callback
82 GNUNET_RECLAIM_AttestationResult at_cb;
85 * Revocation result callback
87 GNUNET_RECLAIM_ContinuationWithStatus rvk_cb;
90 * Ticket result callback
92 GNUNET_RECLAIM_TicketCallback tr_cb;
95 * Envelope with the message for this queue entry.
97 struct GNUNET_MQ_Envelope *env;
105 * Closure for @e cont or @e cb.
112 * Handle for a ticket iterator operation
114 struct GNUNET_RECLAIM_TicketIterator
119 struct GNUNET_RECLAIM_TicketIterator *next;
124 struct GNUNET_RECLAIM_TicketIterator *prev;
127 * Main handle to access the idp.
129 struct GNUNET_RECLAIM_Handle *h;
132 * Function to call on completion.
134 GNUNET_SCHEDULER_TaskCallback finish_cb;
137 * Closure for @e finish_cb.
142 * The continuation to call with the results
144 GNUNET_RECLAIM_TicketCallback tr_cb;
147 * Closure for @e tr_cb.
152 * Function to call on errors.
154 GNUNET_SCHEDULER_TaskCallback error_cb;
157 * Closure for @e error_cb.
162 * Envelope of the message to send to the service, if not yet
165 struct GNUNET_MQ_Envelope *env;
168 * The operation id this zone iteration operation has
175 * Handle for a attribute iterator operation
177 struct GNUNET_RECLAIM_AttributeIterator
182 struct GNUNET_RECLAIM_AttributeIterator *next;
187 struct GNUNET_RECLAIM_AttributeIterator *prev;
190 * Main handle to access the service.
192 struct GNUNET_RECLAIM_Handle *h;
195 * Function to call on completion.
197 GNUNET_SCHEDULER_TaskCallback finish_cb;
200 * Closure for @e finish_cb.
205 * The continuation to call with the results
207 GNUNET_RECLAIM_AttributeResult proc;
210 * Closure for @e proc.
215 * Function to call on errors.
217 GNUNET_SCHEDULER_TaskCallback error_cb;
220 * Closure for @e error_cb.
225 * Envelope of the message to send to the service, if not yet
228 struct GNUNET_MQ_Envelope *env;
231 * Private key of the zone.
233 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
236 * The operation id this zone iteration operation has
242 * Handle for a attestation iterator operation
244 struct GNUNET_RECLAIM_AttestationIterator
249 struct GNUNET_RECLAIM_AttestationIterator *next;
254 struct GNUNET_RECLAIM_AttestationIterator *prev;
257 * Main handle to access the service.
259 struct GNUNET_RECLAIM_Handle *h;
262 * Function to call on completion.
264 GNUNET_SCHEDULER_TaskCallback finish_cb;
267 * Closure for @e finish_cb.
272 * The continuation to call with the results
274 GNUNET_RECLAIM_AttestationResult proc;
277 * Closure for @e proc.
282 * Function to call on errors.
284 GNUNET_SCHEDULER_TaskCallback error_cb;
287 * Closure for @e error_cb.
292 * Envelope of the message to send to the service, if not yet
295 struct GNUNET_MQ_Envelope *env;
298 * Private key of the zone.
300 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
303 * The operation id this zone iteration operation has
310 * Handle to the service.
312 struct GNUNET_RECLAIM_Handle
315 * Configuration to use.
317 const struct GNUNET_CONFIGURATION_Handle *cfg;
320 * Socket (if available).
322 struct GNUNET_CLIENT_Connection *client;
330 * Head of active operations.
332 struct GNUNET_RECLAIM_Operation *op_head;
335 * Tail of active operations.
337 struct GNUNET_RECLAIM_Operation *op_tail;
340 * Head of active iterations
342 struct GNUNET_RECLAIM_AttributeIterator *it_head;
345 * Tail of active iterations
347 struct GNUNET_RECLAIM_AttributeIterator *it_tail;
350 * Head of active iterations
352 struct GNUNET_RECLAIM_AttestationIterator *ait_head;
355 * Tail of active iterations
357 struct GNUNET_RECLAIM_AttestationIterator *ait_tail;
360 * Head of active iterations
362 struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
365 * Tail of active iterations
367 struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
370 * Currently pending transmission request, or NULL for none.
372 struct GNUNET_CLIENT_TransmitHandle *th;
375 * Task doing exponential back-off trying to reconnect.
377 struct GNUNET_SCHEDULER_Task *reconnect_task;
380 * Time for next connect retry.
382 struct GNUNET_TIME_Relative reconnect_backoff;
385 * Connection to service (if available).
387 struct GNUNET_MQ_Handle *mq;
390 * Request Id generator. Incremented by one for each request.
395 * Are we polling for incoming messages right now?
402 * Try again to connect to the service.
404 * @param h handle to the reclaim service.
407 reconnect (struct GNUNET_RECLAIM_Handle *h);
413 * @param cls the handle
416 reconnect_task (void *cls)
418 struct GNUNET_RECLAIM_Handle *handle = cls;
420 handle->reconnect_task = NULL;
426 * Disconnect from service and then reconnect.
428 * @param handle our service
431 force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
433 GNUNET_MQ_destroy (handle->mq);
435 handle->reconnect_backoff =
436 GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
437 handle->reconnect_task =
438 GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
447 * @param it entry to free
450 free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
452 struct GNUNET_RECLAIM_Handle *h = it->h;
454 GNUNET_CONTAINER_DLL_remove (h->it_head, h->it_tail, it);
456 GNUNET_MQ_discard (it->env);
464 * @param ait entry to free
467 free_ait (struct GNUNET_RECLAIM_AttestationIterator *ait)
469 struct GNUNET_RECLAIM_Handle *h = ait->h;
471 GNUNET_CONTAINER_DLL_remove (h->ait_head, h->ait_tail, ait);
472 if (NULL != ait->env)
473 GNUNET_MQ_discard (ait->env);
481 * @param op the operation to free
484 free_op (struct GNUNET_RECLAIM_Operation *op)
489 GNUNET_MQ_discard (op->env);
495 * Generic error handler, called with the appropriate error code and
496 * the same closure specified at the creation of the message queue.
497 * Not every message queue implementation supports an error handler.
499 * @param cls closure with the `struct GNUNET_GNS_Handle *`
500 * @param error error code
503 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
505 struct GNUNET_RECLAIM_Handle *handle = cls;
507 force_reconnect (handle);
512 * Handle an incoming message of type
513 * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE
516 * @param msg the message we received
519 handle_success_response (void *cls, const struct SuccessResultMessage *msg)
521 struct GNUNET_RECLAIM_Handle *h = cls;
522 struct GNUNET_RECLAIM_Operation *op;
523 uint32_t r_id = ntohl (msg->id);
527 for (op = h->op_head; NULL != op; op = op->next)
528 if (op->r_id == r_id)
533 res = ntohl (msg->op_result);
534 LOG (GNUNET_ERROR_TYPE_DEBUG,
535 "Received SUCCESS_RESPONSE with result %d\n",
538 /* TODO: add actual error message to response... */
539 if (GNUNET_SYSERR == res)
540 emsg = _ ("failed to store record\n");
543 if (NULL != op->as_cb)
544 op->as_cb (op->cls, res, emsg);
545 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
551 * Handle an incoming message of type
552 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
555 * @param msg the message we received
556 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
559 check_consume_ticket_result (void *cls,
560 const struct ConsumeTicketResultMessage *msg)
566 msg_len = ntohs (msg->header.size);
567 attrs_len = ntohs (msg->attrs_len);
568 attests_len = ntohs (msg->attestations_len);
570 sizeof(struct ConsumeTicketResultMessage) + attrs_len + attests_len)
573 return GNUNET_SYSERR;
580 * Handle an incoming message of type
581 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
584 * @param msg the message we received
587 handle_consume_ticket_result (void *cls,
588 const struct ConsumeTicketResultMessage *msg)
590 struct GNUNET_RECLAIM_Handle *h = cls;
591 struct GNUNET_RECLAIM_Operation *op;
594 uint32_t r_id = ntohl (msg->id);
597 attrs_len = ntohs (msg->attrs_len);
598 attests_len = ntohs (msg->attestations_len);
599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
602 for (op = h->op_head; NULL != op; op = op->next)
603 if (op->r_id == r_id)
609 struct GNUNET_RECLAIM_AttributeList *attrs;
610 struct GNUNET_RECLAIM_AttributeListEntry *le;
611 struct GNUNET_RECLAIM_AttestationList *attests;
612 struct GNUNET_RECLAIM_AttestationListEntry *ale;
614 GNUNET_RECLAIM_attribute_list_deserialize ((char *) &msg[1], attrs_len);
615 read_ptr = ((char *) &msg[1]) + attrs_len;
617 GNUNET_RECLAIM_attestation_list_deserialize (read_ptr, attests_len);
618 if (NULL != op->atr_cb)
622 op->atr_cb (op->cls, &msg->identity, NULL, NULL);
626 for (le = attrs->list_head; NULL != le; le = le->next)
629 GNUNET_RECLAIM_id_is_zero (&le->attribute->attestation))
631 for (ale = attests->list_head; NULL != ale; ale = ale->next)
634 GNUNET_RECLAIM_id_is_equal (&le->attribute->attestation,
635 &ale->attestation->id))
637 op->atr_cb (op->cls, &msg->identity,
638 le->attribute, ale->attestation);
644 else // No attestations
646 op->atr_cb (op->cls, &msg->identity,
647 le->attribute, NULL);
651 GNUNET_RECLAIM_attribute_list_destroy (attrs);
653 GNUNET_RECLAIM_attestation_list_destroy (attests);
657 op->atr_cb (op->cls, NULL, NULL, NULL);
659 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
661 GNUNET_free_non_null (attrs);
669 * Handle an incoming message of type
670 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
673 * @param msg the message we received
674 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
677 check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
682 msg_len = ntohs (msg->header.size);
683 attr_len = ntohs (msg->attr_len);
684 if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
687 return GNUNET_SYSERR;
694 * Handle an incoming message of type
695 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
698 * @param msg the message we received
701 handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
703 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
704 struct GNUNET_RECLAIM_Handle *h = cls;
705 struct GNUNET_RECLAIM_AttributeIterator *it;
706 struct GNUNET_RECLAIM_Operation *op;
708 uint32_t r_id = ntohl (msg->id);
710 attr_len = ntohs (msg->attr_len);
711 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
714 for (it = h->it_head; NULL != it; it = it->next)
715 if (it->r_id == r_id)
717 for (op = h->op_head; NULL != op; op = op->next)
718 if (op->r_id == r_id)
720 if ((NULL == it) && (NULL == op))
724 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
726 if ((NULL == it) && (NULL == op))
734 if (NULL != it->finish_cb)
735 it->finish_cb (it->finish_cb_cls);
740 if (NULL != op->ar_cb)
741 op->ar_cb (op->cls, NULL, NULL);
742 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
749 struct GNUNET_RECLAIM_Attribute *attr;
750 attr = GNUNET_RECLAIM_attribute_deserialize ((char *) &msg[1], attr_len);
753 if (NULL != it->proc)
754 it->proc (it->proc_cls, &msg->identity, attr);
758 if (NULL != op->ar_cb)
759 op->ar_cb (op->cls, &msg->identity, attr);
769 * Handle an incoming message of type
770 * #GNUNET_MESSAGE_TYPE_RECLAIM_attestation_RESULT
773 * @param msg the message we received
774 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
777 check_attestation_result (void *cls, const struct AttestationResultMessage *msg)
782 msg_len = ntohs (msg->header.size);
783 attest_len = ntohs (msg->attestation_len);
784 if (msg_len != sizeof(struct AttestationResultMessage) + attest_len)
787 return GNUNET_SYSERR;
794 * Handle an incoming message of type
795 * #GNUNET_MESSAGE_TYPE_RECLAIM_attestation_RESULT
798 * @param msg the message we received
801 handle_attestation_result (void *cls, const struct
802 AttestationResultMessage *msg)
804 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
805 struct GNUNET_RECLAIM_Handle *h = cls;
806 struct GNUNET_RECLAIM_AttestationIterator *it;
807 struct GNUNET_RECLAIM_Operation *op;
809 uint32_t r_id = ntohl (msg->id);
811 att_len = ntohs (msg->attestation_len);
812 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attestation result.\n");
815 for (it = h->ait_head; NULL != it; it = it->next)
816 if (it->r_id == r_id)
818 for (op = h->op_head; NULL != op; op = op->next)
819 if (op->r_id == r_id)
821 if ((NULL == it) && (NULL == op))
825 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
827 if ((NULL == it) && (NULL == op))
835 if (NULL != it->finish_cb)
836 it->finish_cb (it->finish_cb_cls);
841 if (NULL != op->at_cb)
842 op->at_cb (op->cls, NULL, NULL);
843 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
850 struct GNUNET_RECLAIM_Attestation *att;
851 att = GNUNET_RECLAIM_attestation_deserialize ((char *) &msg[1], att_len);
855 if (NULL != it->proc)
856 it->proc (it->proc_cls, &msg->identity, att);
860 if (NULL != op->at_cb)
861 op->at_cb (op->cls, &msg->identity, att);
871 * Handle an incoming message of type
872 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
875 * @param msg the message we received
878 handle_ticket_result (void *cls, const struct TicketResultMessage *msg)
880 struct GNUNET_RECLAIM_Handle *handle = cls;
881 struct GNUNET_RECLAIM_Operation *op;
882 struct GNUNET_RECLAIM_TicketIterator *it;
883 uint32_t r_id = ntohl (msg->id);
884 static const struct GNUNET_RECLAIM_Ticket ticket;
886 for (op = handle->op_head; NULL != op; op = op->next)
887 if (op->r_id == r_id)
889 for (it = handle->ticket_it_head; NULL != it; it = it->next)
890 if (it->r_id == r_id)
892 if ((NULL == op) && (NULL == it))
896 GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
898 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
900 if (NULL != op->tr_cb)
901 op->tr_cb (op->cls, NULL);
905 if (NULL != op->tr_cb)
906 op->tr_cb (op->cls, &msg->ticket);
914 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
916 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
917 handle->ticket_it_tail,
919 it->finish_cb (it->finish_cb_cls);
924 if (NULL != it->tr_cb)
925 it->tr_cb (it->cls, &msg->ticket);
934 * Handle an incoming message of type
935 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
938 * @param msg the message we received
941 handle_revoke_ticket_result (void *cls,
942 const struct RevokeTicketResultMessage *msg)
944 struct GNUNET_RECLAIM_Handle *h = cls;
945 struct GNUNET_RECLAIM_Operation *op;
946 uint32_t r_id = ntohl (msg->id);
949 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
952 for (op = h->op_head; NULL != op; op = op->next)
953 if (op->r_id == r_id)
957 success = ntohl (msg->success);
959 if (NULL != op->rvk_cb)
961 op->rvk_cb (op->cls, success, NULL);
963 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
972 * Try again to connect to the service.
974 * @param h handle to the reclaim service.
977 reconnect (struct GNUNET_RECLAIM_Handle *h)
979 struct GNUNET_MQ_MessageHandler handlers[] =
980 { GNUNET_MQ_hd_fixed_size (success_response,
981 GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
982 struct SuccessResultMessage,
984 GNUNET_MQ_hd_var_size (attribute_result,
985 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
986 struct AttributeResultMessage,
988 GNUNET_MQ_hd_var_size (attestation_result,
989 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT,
990 struct AttestationResultMessage,
992 GNUNET_MQ_hd_fixed_size (ticket_result,
993 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
994 struct TicketResultMessage,
996 GNUNET_MQ_hd_var_size (consume_ticket_result,
997 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
998 struct ConsumeTicketResultMessage,
1000 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
1001 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
1002 struct RevokeTicketResultMessage,
1004 GNUNET_MQ_handler_end () };
1005 struct GNUNET_RECLAIM_Operation *op;
1007 GNUNET_assert (NULL == h->mq);
1008 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
1011 GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
1014 for (op = h->op_head; NULL != op; op = op->next)
1015 GNUNET_MQ_send_copy (h->mq, op->env);
1020 * Connect to the reclaim service.
1022 * @param cfg the configuration to use
1023 * @return handle to use
1025 struct GNUNET_RECLAIM_Handle *
1026 GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
1028 struct GNUNET_RECLAIM_Handle *h;
1030 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
1043 * Cancel an operation. Note that the operation MAY still
1044 * be executed; this merely cancels the continuation; if the request
1045 * was already transmitted, the service may still choose to complete
1048 * @param op operation to cancel
1051 GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
1053 struct GNUNET_RECLAIM_Handle *h = op->h;
1055 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
1061 * Disconnect from service
1063 * @param h handle to destroy
1066 GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
1068 GNUNET_assert (NULL != h);
1071 GNUNET_MQ_destroy (h->mq);
1074 if (NULL != h->reconnect_task)
1076 GNUNET_SCHEDULER_cancel (h->reconnect_task);
1077 h->reconnect_task = NULL;
1079 GNUNET_assert (NULL == h->op_head);
1085 * Store an attribute. If the attribute is already present,
1086 * it is replaced with the new attribute.
1088 * @param h handle to the re:claimID service
1089 * @param pkey private key of the identity
1090 * @param attr the attribute value
1091 * @param exp_interval the relative expiration interval for the attribute
1092 * @param cont continuation to call when done
1093 * @param cont_cls closure for @a cont
1094 * @return handle to abort the request
1096 struct GNUNET_RECLAIM_Operation *
1097 GNUNET_RECLAIM_attribute_store (
1098 struct GNUNET_RECLAIM_Handle *h,
1099 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1100 const struct GNUNET_RECLAIM_Attribute *attr,
1101 const struct GNUNET_TIME_Relative *exp_interval,
1102 GNUNET_RECLAIM_ContinuationWithStatus cont,
1105 struct GNUNET_RECLAIM_Operation *op;
1106 struct AttributeStoreMessage *sam;
1109 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1113 op->r_id = h->r_id_gen++;
1114 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1115 attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
1116 op->env = GNUNET_MQ_msg_extra (sam,
1118 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
1119 sam->identity = *pkey;
1120 sam->id = htonl (op->r_id);
1121 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1123 GNUNET_RECLAIM_attribute_serialize (attr, (char *) &sam[1]);
1125 sam->attr_len = htons (attr_len);
1127 GNUNET_MQ_send_copy (h->mq, op->env);
1133 * Delete an attribute. Tickets used to share this attribute are updated
1136 * @param h handle to the re:claimID service
1137 * @param pkey Private key of the identity to add an attribute to
1138 * @param attr The attribute
1139 * @param cont Continuation to call when done
1140 * @param cont_cls Closure for @a cont
1141 * @return handle Used to to abort the request
1143 struct GNUNET_RECLAIM_Operation *
1144 GNUNET_RECLAIM_attribute_delete (
1145 struct GNUNET_RECLAIM_Handle *h,
1146 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1147 const struct GNUNET_RECLAIM_Attribute *attr,
1148 GNUNET_RECLAIM_ContinuationWithStatus cont,
1151 struct GNUNET_RECLAIM_Operation *op;
1152 struct AttributeDeleteMessage *dam;
1155 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1159 op->r_id = h->r_id_gen++;
1160 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1161 attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
1162 op->env = GNUNET_MQ_msg_extra (dam,
1164 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE);
1165 dam->identity = *pkey;
1166 dam->id = htonl (op->r_id);
1167 GNUNET_RECLAIM_attribute_serialize (attr, (char *) &dam[1]);
1169 dam->attr_len = htons (attr_len);
1171 GNUNET_MQ_send_copy (h->mq, op->env);
1177 * Store an attestation. If the attestation is already present,
1178 * it is replaced with the new attestation.
1180 * @param h handle to the re:claimID service
1181 * @param pkey private key of the identity
1182 * @param attr the attestation value
1183 * @param exp_interval the relative expiration interval for the attestation
1184 * @param cont continuation to call when done
1185 * @param cont_cls closure for @a cont
1186 * @return handle to abort the request
1188 struct GNUNET_RECLAIM_Operation *
1189 GNUNET_RECLAIM_attestation_store (
1190 struct GNUNET_RECLAIM_Handle *h,
1191 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1192 const struct GNUNET_RECLAIM_Attestation *attr,
1193 const struct GNUNET_TIME_Relative *exp_interval,
1194 GNUNET_RECLAIM_ContinuationWithStatus cont,
1197 struct GNUNET_RECLAIM_Operation *op;
1198 struct AttributeStoreMessage *sam;
1201 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1205 op->r_id = h->r_id_gen++;
1206 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1207 attr_len = GNUNET_RECLAIM_attestation_serialize_get_size (attr);
1208 op->env = GNUNET_MQ_msg_extra (sam,
1210 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE);
1211 sam->identity = *pkey;
1212 sam->id = htonl (op->r_id);
1213 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1215 GNUNET_RECLAIM_attestation_serialize (attr, (char *) &sam[1]);
1217 sam->attr_len = htons (attr_len);
1219 GNUNET_MQ_send_copy (h->mq, op->env);
1225 * Delete an attestation. Tickets used to share this attestation are updated
1228 * @param h handle to the re:claimID service
1229 * @param pkey Private key of the identity to add an attribute to
1230 * @param attr The attestation
1231 * @param cont Continuation to call when done
1232 * @param cont_cls Closure for @a cont
1233 * @return handle Used to to abort the request
1235 struct GNUNET_RECLAIM_Operation *
1236 GNUNET_RECLAIM_attestation_delete (
1237 struct GNUNET_RECLAIM_Handle *h,
1238 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1239 const struct GNUNET_RECLAIM_Attestation *attr,
1240 GNUNET_RECLAIM_ContinuationWithStatus cont,
1243 struct GNUNET_RECLAIM_Operation *op;
1244 struct AttributeDeleteMessage *dam;
1247 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1251 op->r_id = h->r_id_gen++;
1252 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1253 attr_len = GNUNET_RECLAIM_attestation_serialize_get_size (attr);
1254 op->env = GNUNET_MQ_msg_extra (dam,
1256 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE);
1257 dam->identity = *pkey;
1258 dam->id = htonl (op->r_id);
1259 GNUNET_RECLAIM_attestation_serialize (attr, (char *) &dam[1]);
1261 dam->attr_len = htons (attr_len);
1263 GNUNET_MQ_send_copy (h->mq, op->env);
1269 * List all attributes for a local identity.
1270 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
1271 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
1272 * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
1273 * immediately, and then again after
1274 * #GNUNET_RECLAIM_get_attributes_next() is invoked.
1276 * On error (disconnect), @a error_cb will be invoked.
1277 * On normal completion, @a finish_cb proc will be
1280 * @param h Handle to the re:claimID service
1281 * @param identity Identity to iterate over
1282 * @param error_cb Function to call on error (i.e. disconnect),
1283 * the handle is afterwards invalid
1284 * @param error_cb_cls Closure for @a error_cb
1285 * @param proc Function to call on each attribute
1286 * @param proc_cls Closure for @a proc
1287 * @param finish_cb Function to call on completion
1288 * the handle is afterwards invalid
1289 * @param finish_cb_cls Closure for @a finish_cb
1290 * @return an iterator Handle to use for iteration
1292 struct GNUNET_RECLAIM_AttributeIterator *
1293 GNUNET_RECLAIM_get_attributes_start (
1294 struct GNUNET_RECLAIM_Handle *h,
1295 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1296 GNUNET_SCHEDULER_TaskCallback error_cb,
1298 GNUNET_RECLAIM_AttributeResult proc,
1300 GNUNET_SCHEDULER_TaskCallback finish_cb,
1301 void *finish_cb_cls)
1303 struct GNUNET_RECLAIM_AttributeIterator *it;
1304 struct GNUNET_MQ_Envelope *env;
1305 struct AttributeIterationStartMessage *msg;
1308 rid = h->r_id_gen++;
1309 it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
1311 it->error_cb = error_cb;
1312 it->error_cb_cls = error_cb_cls;
1313 it->finish_cb = finish_cb;
1314 it->finish_cb_cls = finish_cb_cls;
1316 it->proc_cls = proc_cls;
1318 it->identity = *identity;
1319 GNUNET_CONTAINER_DLL_insert_tail (h->it_head, h->it_tail, it);
1321 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
1322 msg->id = htonl (rid);
1323 msg->identity = *identity;
1327 GNUNET_MQ_send (h->mq, env);
1333 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
1334 * for the next record.
1336 * @param it the iterator
1339 GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
1341 struct GNUNET_RECLAIM_Handle *h = it->h;
1342 struct AttributeIterationNextMessage *msg;
1343 struct GNUNET_MQ_Envelope *env;
1346 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
1347 msg->id = htonl (it->r_id);
1348 GNUNET_MQ_send (h->mq, env);
1353 * Stops iteration and releases the handle for further calls. Must
1354 * be called on any iteration that has not yet completed prior to calling
1355 * #GNUNET_RECLAIM_disconnect.
1357 * @param it the iterator
1360 GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
1362 struct GNUNET_RECLAIM_Handle *h = it->h;
1363 struct GNUNET_MQ_Envelope *env;
1364 struct AttributeIterationStopMessage *msg;
1369 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
1370 msg->id = htonl (it->r_id);
1371 GNUNET_MQ_send (h->mq, env);
1378 * List all attestations for a local identity.
1379 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
1380 * for any other calls than #GNUNET_RECLAIM_get_attestations_next() and
1381 * #GNUNET_RECLAIM_get_attestations_stop. @a proc will be called once
1382 * immediately, and then again after
1383 * #GNUNET_RECLAIM_get_attestations_next() is invoked.
1385 * On error (disconnect), @a error_cb will be invoked.
1386 * On normal completion, @a finish_cb proc will be
1389 * @param h Handle to the re:claimID service
1390 * @param identity Identity to iterate over
1391 * @param error_cb Function to call on error (i.e. disconnect),
1392 * the handle is afterwards invalid
1393 * @param error_cb_cls Closure for @a error_cb
1394 * @param proc Function to call on each attestation
1395 * @param proc_cls Closure for @a proc
1396 * @param finish_cb Function to call on completion
1397 * the handle is afterwards invalid
1398 * @param finish_cb_cls Closure for @a finish_cb
1399 * @return an iterator Handle to use for iteration
1401 struct GNUNET_RECLAIM_AttestationIterator *
1402 GNUNET_RECLAIM_get_attestations_start (
1403 struct GNUNET_RECLAIM_Handle *h,
1404 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1405 GNUNET_SCHEDULER_TaskCallback error_cb,
1407 GNUNET_RECLAIM_AttestationResult proc,
1409 GNUNET_SCHEDULER_TaskCallback finish_cb,
1410 void *finish_cb_cls)
1412 struct GNUNET_RECLAIM_AttestationIterator *ait;
1413 struct GNUNET_MQ_Envelope *env;
1414 struct AttestationIterationStartMessage *msg;
1417 rid = h->r_id_gen++;
1418 ait = GNUNET_new (struct GNUNET_RECLAIM_AttestationIterator);
1420 ait->error_cb = error_cb;
1421 ait->error_cb_cls = error_cb_cls;
1422 ait->finish_cb = finish_cb;
1423 ait->finish_cb_cls = finish_cb_cls;
1425 ait->proc_cls = proc_cls;
1427 ait->identity = *identity;
1428 GNUNET_CONTAINER_DLL_insert_tail (h->ait_head, h->ait_tail, ait);
1431 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_START);
1432 msg->id = htonl (rid);
1433 msg->identity = *identity;
1437 GNUNET_MQ_send (h->mq, env);
1443 * Calls the record processor specified in #GNUNET_RECLAIM_get_attestation_start
1444 * for the next record.
1446 * @param it the iterator
1449 GNUNET_RECLAIM_get_attestations_next (struct
1450 GNUNET_RECLAIM_AttestationIterator *ait)
1452 struct GNUNET_RECLAIM_Handle *h = ait->h;
1453 struct AttestationIterationNextMessage *msg;
1454 struct GNUNET_MQ_Envelope *env;
1457 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_NEXT);
1458 msg->id = htonl (ait->r_id);
1459 GNUNET_MQ_send (h->mq, env);
1464 * Stops iteration and releases the handle for further calls. Must
1465 * be called on any iteration that has not yet completed prior to calling
1466 * #GNUNET_RECLAIM_disconnect.
1468 * @param it the iterator
1471 GNUNET_RECLAIM_get_attestations_stop (struct
1472 GNUNET_RECLAIM_AttestationIterator *ait)
1474 struct GNUNET_RECLAIM_Handle *h = ait->h;
1475 struct GNUNET_MQ_Envelope *env;
1476 struct AttestationIterationStopMessage *msg;
1482 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_STOP);
1483 msg->id = htonl (ait->r_id);
1484 GNUNET_MQ_send (h->mq, env);
1491 * Issues a ticket to another relying party. The identity may use
1492 * @GNUNET_RECLAIM_ticket_consume to consume the ticket
1493 * and retrieve the attributes specified in the attribute list.
1495 * @param h the reclaim to use
1496 * @param iss the issuing identity (= the user)
1497 * @param rp the subject of the ticket (= the relying party)
1498 * @param attrs the attributes that the relying party is given access to
1499 * @param cb the callback
1500 * @param cb_cls the callback closure
1501 * @return handle to abort the operation
1503 struct GNUNET_RECLAIM_Operation *
1504 GNUNET_RECLAIM_ticket_issue (
1505 struct GNUNET_RECLAIM_Handle *h,
1506 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1507 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1508 const struct GNUNET_RECLAIM_AttributeList *attrs,
1509 GNUNET_RECLAIM_TicketCallback cb,
1512 struct GNUNET_RECLAIM_Operation *op;
1513 struct IssueTicketMessage *tim;
1516 fprintf (stderr, "Issuing ticket\n");
1517 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1521 op->r_id = h->r_id_gen++;
1522 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1523 attr_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
1524 op->env = GNUNET_MQ_msg_extra (tim,
1526 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
1527 tim->identity = *iss;
1529 tim->id = htonl (op->r_id);
1531 GNUNET_RECLAIM_attribute_list_serialize (attrs, (char *) &tim[1]);
1533 tim->attr_len = htons (attr_len);
1535 GNUNET_MQ_send_copy (h->mq, op->env);
1541 * Consumes an issued ticket. The ticket is persisted
1542 * and used to retrieve identity information from the issuer
1544 * @param h the reclaim to use
1545 * @param identity the identity that is the subject of the issued ticket (the
1547 * @param ticket the issued ticket to consume
1548 * @param cb the callback to call
1549 * @param cb_cls the callback closure
1550 * @return handle to abort the operation
1552 struct GNUNET_RECLAIM_Operation *
1553 GNUNET_RECLAIM_ticket_consume (
1554 struct GNUNET_RECLAIM_Handle *h,
1555 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1556 const struct GNUNET_RECLAIM_Ticket *ticket,
1557 GNUNET_RECLAIM_AttributeTicketResult cb,
1560 struct GNUNET_RECLAIM_Operation *op;
1561 struct ConsumeTicketMessage *ctm;
1563 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1567 op->r_id = h->r_id_gen++;
1568 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1569 op->env = GNUNET_MQ_msg (ctm, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
1570 ctm->identity = *identity;
1571 ctm->id = htonl (op->r_id);
1572 ctm->ticket = *ticket;
1574 GNUNET_MQ_send_copy (h->mq, op->env);
1580 * Lists all tickets that have been issued to remote
1581 * identites (relying parties)
1583 * @param h the reclaim to use
1584 * @param identity the issuing identity
1585 * @param error_cb function to call on error (i.e. disconnect),
1586 * the handle is afterwards invalid
1587 * @param error_cb_cls closure for @a error_cb
1588 * @param proc function to call on each ticket; it
1589 * will be called repeatedly with a value (if available)
1590 * @param proc_cls closure for @a proc
1591 * @param finish_cb function to call on completion
1592 * the handle is afterwards invalid
1593 * @param finish_cb_cls closure for @a finish_cb
1594 * @return an iterator handle to use for iteration
1596 struct GNUNET_RECLAIM_TicketIterator *
1597 GNUNET_RECLAIM_ticket_iteration_start (
1598 struct GNUNET_RECLAIM_Handle *h,
1599 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1600 GNUNET_SCHEDULER_TaskCallback error_cb,
1602 GNUNET_RECLAIM_TicketCallback proc,
1604 GNUNET_SCHEDULER_TaskCallback finish_cb,
1605 void *finish_cb_cls)
1607 struct GNUNET_RECLAIM_TicketIterator *it;
1608 struct GNUNET_MQ_Envelope *env;
1609 struct TicketIterationStartMessage *msg;
1612 rid = h->r_id_gen++;
1613 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1615 it->error_cb = error_cb;
1616 it->error_cb_cls = error_cb_cls;
1617 it->finish_cb = finish_cb;
1618 it->finish_cb_cls = finish_cb_cls;
1622 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it);
1623 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1624 msg->id = htonl (rid);
1625 msg->identity = *identity;
1629 GNUNET_MQ_send (h->mq, env);
1635 * Calls the ticket processor specified in
1636 * #GNUNET_RECLAIM_ticket_iteration_start for the next record.
1638 * @param it the iterator
1641 GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
1643 struct GNUNET_RECLAIM_Handle *h = it->h;
1644 struct TicketIterationNextMessage *msg;
1645 struct GNUNET_MQ_Envelope *env;
1647 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
1648 msg->id = htonl (it->r_id);
1649 GNUNET_MQ_send (h->mq, env);
1654 * Stops iteration and releases the handle for further calls. Must
1655 * be called on any iteration that has not yet completed prior to calling
1656 * #GNUNET_RECLAIM_disconnect.
1658 * @param it the iterator
1661 GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
1663 struct GNUNET_RECLAIM_Handle *h = it->h;
1664 struct GNUNET_MQ_Envelope *env;
1665 struct TicketIterationStopMessage *msg;
1670 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
1671 msg->id = htonl (it->r_id);
1672 GNUNET_MQ_send (h->mq, env);
1679 * Revoked an issued ticket. The relying party will be unable to retrieve
1680 * attributes. Other issued tickets remain unaffected.
1681 * This includes tickets issued to other relying parties as well as to
1682 * other tickets issued to the audience specified in this ticket.
1684 * @param h the identity provider to use
1685 * @param identity the issuing identity
1686 * @param ticket the ticket to revoke
1687 * @param cb the callback
1688 * @param cb_cls the callback closure
1689 * @return handle to abort the operation
1691 struct GNUNET_RECLAIM_Operation *
1692 GNUNET_RECLAIM_ticket_revoke (
1693 struct GNUNET_RECLAIM_Handle *h,
1694 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1695 const struct GNUNET_RECLAIM_Ticket *ticket,
1696 GNUNET_RECLAIM_ContinuationWithStatus cb,
1699 struct GNUNET_RECLAIM_Operation *op;
1700 struct RevokeTicketMessage *msg;
1703 rid = h->r_id_gen++;
1704 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1709 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1710 op->env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
1711 msg->id = htonl (rid);
1712 msg->identity = *identity;
1713 msg->ticket = *ticket;
1716 GNUNET_MQ_send (h->mq, op->env);
1723 /* end of reclaim_api.c */