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_attribute_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)
565 msg_len = ntohs (msg->header.size);
566 attrs_len = ntohs (msg->attrs_len);
567 if (msg_len != sizeof(struct ConsumeTicketResultMessage) + attrs_len)
570 return GNUNET_SYSERR;
577 * Handle an incoming message of type
578 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
581 * @param msg the message we received
584 handle_consume_ticket_result (void *cls,
585 const struct ConsumeTicketResultMessage *msg)
587 struct GNUNET_RECLAIM_Handle *h = cls;
588 struct GNUNET_RECLAIM_Operation *op;
591 uint32_t r_id = ntohl (msg->id);
594 attrs_len = ntohs (msg->attrs_len);
595 attests_len = ntohs (msg->attestations_len);
596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
599 for (op = h->op_head; NULL != op; op = op->next)
600 if (op->r_id == r_id)
606 struct GNUNET_RECLAIM_AttributeList *attrs;
607 struct GNUNET_RECLAIM_AttributeListEntry *le;
608 struct GNUNET_RECLAIM_AttestationList *attests;
609 struct GNUNET_RECLAIM_AttestationListEntry *ale;
611 GNUNET_RECLAIM_attribute_list_deserialize ((char *) &msg[1], attrs_len);
612 read_ptr = ((char *) &msg[1]) + attrs_len;
614 GNUNET_RECLAIM_attestation_list_deserialize (read_ptr, attests_len);
615 if (NULL != op->atr_cb)
619 op->atr_cb (op->cls, &msg->identity, NULL, NULL);
623 for (le = attrs->list_head; NULL != le; le = le->next)
626 GNUNET_RECLAIM_id_is_zero (&le->attribute->attestation))
628 for (ale = attests->list_head; NULL != ale; ale = ale->next)
631 GNUNET_RECLAIM_id_is_equal (&le->attribute->id,
632 &ale->attestation->id))
634 op->atr_cb (op->cls, &msg->identity,
635 le->attribute, ale->attestation);
641 else // No attestations
643 op->atr_cb (op->cls, &msg->identity,
644 le->attribute, NULL);
647 GNUNET_RECLAIM_attribute_list_destroy (attrs);
648 GNUNET_RECLAIM_attestation_list_destroy (attests);
652 op->atr_cb (op->cls, NULL, NULL, NULL);
654 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
656 GNUNET_free_non_null (attrs);
664 * Handle an incoming message of type
665 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
668 * @param msg the message we received
669 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
672 check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
677 msg_len = ntohs (msg->header.size);
678 attr_len = ntohs (msg->attr_len);
679 if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
682 return GNUNET_SYSERR;
689 * Handle an incoming message of type
690 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
693 * @param msg the message we received
696 handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
698 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
699 struct GNUNET_RECLAIM_Handle *h = cls;
700 struct GNUNET_RECLAIM_AttributeIterator *it;
701 struct GNUNET_RECLAIM_Operation *op;
704 uint32_t r_id = ntohl (msg->id);
706 attr_len = ntohs (msg->attr_len);
707 attest_len = ntohs (msg->attestation_len);
708 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
711 for (it = h->it_head; NULL != it; it = it->next)
712 if (it->r_id == r_id)
714 for (op = h->op_head; NULL != op; op = op->next)
715 if (op->r_id == r_id)
717 if ((NULL == it) && (NULL == op))
721 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
723 if ((NULL == it) && (NULL == op))
731 if (NULL != it->finish_cb)
732 it->finish_cb (it->finish_cb_cls);
737 if (NULL != op->ar_cb)
738 op->ar_cb (op->cls, NULL, NULL);
739 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
746 struct GNUNET_RECLAIM_Attribute *attr;
747 attr = GNUNET_RECLAIM_attribute_deserialize ((char *) &msg[1], attr_len);
750 if (NULL != it->proc)
751 it->proc (it->proc_cls, &msg->identity, attr);
755 if (NULL != op->ar_cb)
756 op->ar_cb (op->cls, &msg->identity, attr);
766 * Handle an incoming message of type
767 * #GNUNET_MESSAGE_TYPE_RECLAIM_attestation_RESULT
770 * @param msg the message we received
771 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
774 check_attestation_result (void *cls, const struct AttestationResultMessage *msg)
779 msg_len = ntohs (msg->header.size);
780 attr_len = ntohs (msg->attestation_len);
781 if (msg_len != sizeof(struct AttestationResultMessage) + attr_len)
784 return GNUNET_SYSERR;
791 * Handle an incoming message of type
792 * #GNUNET_MESSAGE_TYPE_RECLAIM_attestation_RESULT
795 * @param msg the message we received
798 handle_attestation_result (void *cls, const struct
799 AttestationResultMessage *msg)
801 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
802 struct GNUNET_RECLAIM_Handle *h = cls;
803 struct GNUNET_RECLAIM_AttestationIterator *it;
804 struct GNUNET_RECLAIM_AttributeList *attrs;
805 struct GNUNET_RECLAIM_Operation *op;
808 uint32_t r_id = ntohl (msg->id);
810 att_len = ntohs (msg->attestation_len);
811 attrs_len = ntohs (msg->attributes_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, 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);
852 char *read_ptr = ((char *) &msg[1]) + att_len;
853 attrs = GNUNET_RECLAIM_attribute_list_deserialize (read_ptr, attrs_len);
856 if (NULL != it->proc)
857 it->proc (it->proc_cls, &msg->identity, att, attrs);
861 if (NULL != op->at_cb)
862 op->at_cb (op->cls, &msg->identity, att, attrs);
865 GNUNET_RECLAIM_attribute_list_destroy (attrs);
873 * Handle an incoming message of type
874 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
877 * @param msg the message we received
880 handle_ticket_result (void *cls, const struct TicketResultMessage *msg)
882 struct GNUNET_RECLAIM_Handle *handle = cls;
883 struct GNUNET_RECLAIM_Operation *op;
884 struct GNUNET_RECLAIM_TicketIterator *it;
885 uint32_t r_id = ntohl (msg->id);
886 static const struct GNUNET_RECLAIM_Ticket ticket;
888 for (op = handle->op_head; NULL != op; op = op->next)
889 if (op->r_id == r_id)
891 for (it = handle->ticket_it_head; NULL != it; it = it->next)
892 if (it->r_id == r_id)
894 if ((NULL == op) && (NULL == it))
898 GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
900 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
902 if (NULL != op->tr_cb)
903 op->tr_cb (op->cls, NULL);
907 if (NULL != op->tr_cb)
908 op->tr_cb (op->cls, &msg->ticket);
916 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
918 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
919 handle->ticket_it_tail,
921 it->finish_cb (it->finish_cb_cls);
926 if (NULL != it->tr_cb)
927 it->tr_cb (it->cls, &msg->ticket);
936 * Handle an incoming message of type
937 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
940 * @param msg the message we received
943 handle_revoke_ticket_result (void *cls,
944 const struct RevokeTicketResultMessage *msg)
946 struct GNUNET_RECLAIM_Handle *h = cls;
947 struct GNUNET_RECLAIM_Operation *op;
948 uint32_t r_id = ntohl (msg->id);
951 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
954 for (op = h->op_head; NULL != op; op = op->next)
955 if (op->r_id == r_id)
959 success = ntohl (msg->success);
961 if (NULL != op->rvk_cb)
963 op->rvk_cb (op->cls, success, NULL);
965 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
974 * Try again to connect to the service.
976 * @param h handle to the reclaim service.
979 reconnect (struct GNUNET_RECLAIM_Handle *h)
981 struct GNUNET_MQ_MessageHandler handlers[] =
982 { GNUNET_MQ_hd_fixed_size (success_response,
983 GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
984 struct SuccessResultMessage,
986 GNUNET_MQ_hd_var_size (attribute_result,
987 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
988 struct AttributeResultMessage,
990 GNUNET_MQ_hd_var_size (attestation_result,
991 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT,
992 struct AttestationResultMessage,
994 GNUNET_MQ_hd_fixed_size (ticket_result,
995 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
996 struct TicketResultMessage,
998 GNUNET_MQ_hd_var_size (consume_ticket_result,
999 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
1000 struct ConsumeTicketResultMessage,
1002 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
1003 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
1004 struct RevokeTicketResultMessage,
1006 GNUNET_MQ_handler_end () };
1007 struct GNUNET_RECLAIM_Operation *op;
1009 GNUNET_assert (NULL == h->mq);
1010 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
1013 GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
1016 for (op = h->op_head; NULL != op; op = op->next)
1017 GNUNET_MQ_send_copy (h->mq, op->env);
1022 * Connect to the reclaim service.
1024 * @param cfg the configuration to use
1025 * @return handle to use
1027 struct GNUNET_RECLAIM_Handle *
1028 GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
1030 struct GNUNET_RECLAIM_Handle *h;
1032 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
1045 * Cancel an operation. Note that the operation MAY still
1046 * be executed; this merely cancels the continuation; if the request
1047 * was already transmitted, the service may still choose to complete
1050 * @param op operation to cancel
1053 GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
1055 struct GNUNET_RECLAIM_Handle *h = op->h;
1057 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
1063 * Disconnect from service
1065 * @param h handle to destroy
1068 GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
1070 GNUNET_assert (NULL != h);
1073 GNUNET_MQ_destroy (h->mq);
1076 if (NULL != h->reconnect_task)
1078 GNUNET_SCHEDULER_cancel (h->reconnect_task);
1079 h->reconnect_task = NULL;
1081 GNUNET_assert (NULL == h->op_head);
1087 * Store an attribute. If the attribute is already present,
1088 * it is replaced with the new attribute.
1090 * @param h handle to the re:claimID service
1091 * @param pkey private key of the identity
1092 * @param attr the attribute value
1093 * @param exp_interval the relative expiration interval for the attribute
1094 * @param cont continuation to call when done
1095 * @param cont_cls closure for @a cont
1096 * @return handle to abort the request
1098 struct GNUNET_RECLAIM_Operation *
1099 GNUNET_RECLAIM_attribute_store (
1100 struct GNUNET_RECLAIM_Handle *h,
1101 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1102 const struct GNUNET_RECLAIM_Attribute *attr,
1103 const struct GNUNET_TIME_Relative *exp_interval,
1104 GNUNET_RECLAIM_ContinuationWithStatus cont,
1107 struct GNUNET_RECLAIM_Operation *op;
1108 struct AttributeStoreMessage *sam;
1111 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1115 op->r_id = h->r_id_gen++;
1116 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1117 attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
1118 op->env = GNUNET_MQ_msg_extra (sam,
1120 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
1121 sam->identity = *pkey;
1122 sam->id = htonl (op->r_id);
1123 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1125 GNUNET_RECLAIM_attribute_serialize (attr, (char *) &sam[1]);
1127 sam->attr_len = htons (attr_len);
1129 GNUNET_MQ_send_copy (h->mq, op->env);
1135 * Delete an attribute. Tickets used to share this attribute are updated
1138 * @param h handle to the re:claimID service
1139 * @param pkey Private key of the identity to add an attribute to
1140 * @param attr The attribute
1141 * @param cont Continuation to call when done
1142 * @param cont_cls Closure for @a cont
1143 * @return handle Used to to abort the request
1145 struct GNUNET_RECLAIM_Operation *
1146 GNUNET_RECLAIM_attribute_delete (
1147 struct GNUNET_RECLAIM_Handle *h,
1148 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1149 const struct GNUNET_RECLAIM_Attribute *attr,
1150 GNUNET_RECLAIM_ContinuationWithStatus cont,
1153 struct GNUNET_RECLAIM_Operation *op;
1154 struct AttributeDeleteMessage *dam;
1157 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1161 op->r_id = h->r_id_gen++;
1162 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1163 attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
1164 op->env = GNUNET_MQ_msg_extra (dam,
1166 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE);
1167 dam->identity = *pkey;
1168 dam->id = htonl (op->r_id);
1169 GNUNET_RECLAIM_attribute_serialize (attr, (char *) &dam[1]);
1171 dam->attr_len = htons (attr_len);
1173 GNUNET_MQ_send_copy (h->mq, op->env);
1179 * Store an attestation. If the attestation is already present,
1180 * it is replaced with the new attestation.
1182 * @param h handle to the re:claimID service
1183 * @param pkey private key of the identity
1184 * @param attr the attestation value
1185 * @param exp_interval the relative expiration interval for the attestation
1186 * @param cont continuation to call when done
1187 * @param cont_cls closure for @a cont
1188 * @return handle to abort the request
1190 struct GNUNET_RECLAIM_Operation *
1191 GNUNET_RECLAIM_attestation_store (
1192 struct GNUNET_RECLAIM_Handle *h,
1193 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1194 const struct GNUNET_RECLAIM_Attestation *attr,
1195 const struct GNUNET_TIME_Relative *exp_interval,
1196 GNUNET_RECLAIM_ContinuationWithStatus cont,
1199 struct GNUNET_RECLAIM_Operation *op;
1200 struct AttributeStoreMessage *sam;
1203 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1207 op->r_id = h->r_id_gen++;
1208 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1209 attr_len = GNUNET_RECLAIM_attestation_serialize_get_size (attr);
1210 op->env = GNUNET_MQ_msg_extra (sam,
1212 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE);
1213 sam->identity = *pkey;
1214 sam->id = htonl (op->r_id);
1215 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1217 GNUNET_RECLAIM_attestation_serialize (attr, (char *) &sam[1]);
1219 sam->attr_len = htons (attr_len);
1221 GNUNET_MQ_send_copy (h->mq, op->env);
1227 * Delete an attestation. Tickets used to share this attestation are updated
1230 * @param h handle to the re:claimID service
1231 * @param pkey Private key of the identity to add an attribute to
1232 * @param attr The attestation
1233 * @param cont Continuation to call when done
1234 * @param cont_cls Closure for @a cont
1235 * @return handle Used to to abort the request
1237 struct GNUNET_RECLAIM_Operation *
1238 GNUNET_RECLAIM_attestation_delete (
1239 struct GNUNET_RECLAIM_Handle *h,
1240 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1241 const struct GNUNET_RECLAIM_Attestation *attr,
1242 GNUNET_RECLAIM_ContinuationWithStatus cont,
1245 struct GNUNET_RECLAIM_Operation *op;
1246 struct AttributeDeleteMessage *dam;
1249 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1253 op->r_id = h->r_id_gen++;
1254 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1255 attr_len = GNUNET_RECLAIM_attestation_serialize_get_size (attr);
1256 op->env = GNUNET_MQ_msg_extra (dam,
1258 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE);
1259 dam->identity = *pkey;
1260 dam->id = htonl (op->r_id);
1261 GNUNET_RECLAIM_attestation_serialize (attr, (char *) &dam[1]);
1263 dam->attr_len = htons (attr_len);
1265 GNUNET_MQ_send_copy (h->mq, op->env);
1271 * List all attributes for a local identity.
1272 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
1273 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
1274 * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
1275 * immediately, and then again after
1276 * #GNUNET_RECLAIM_get_attributes_next() is invoked.
1278 * On error (disconnect), @a error_cb will be invoked.
1279 * On normal completion, @a finish_cb proc will be
1282 * @param h Handle to the re:claimID service
1283 * @param identity Identity to iterate over
1284 * @param error_cb Function to call on error (i.e. disconnect),
1285 * the handle is afterwards invalid
1286 * @param error_cb_cls Closure for @a error_cb
1287 * @param proc Function to call on each attribute
1288 * @param proc_cls Closure for @a proc
1289 * @param finish_cb Function to call on completion
1290 * the handle is afterwards invalid
1291 * @param finish_cb_cls Closure for @a finish_cb
1292 * @return an iterator Handle to use for iteration
1294 struct GNUNET_RECLAIM_AttributeIterator *
1295 GNUNET_RECLAIM_get_attributes_start (
1296 struct GNUNET_RECLAIM_Handle *h,
1297 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1298 GNUNET_SCHEDULER_TaskCallback error_cb,
1300 GNUNET_RECLAIM_AttributeResult proc,
1302 GNUNET_SCHEDULER_TaskCallback finish_cb,
1303 void *finish_cb_cls)
1305 struct GNUNET_RECLAIM_AttributeIterator *it;
1306 struct GNUNET_MQ_Envelope *env;
1307 struct AttributeIterationStartMessage *msg;
1310 rid = h->r_id_gen++;
1311 it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
1313 it->error_cb = error_cb;
1314 it->error_cb_cls = error_cb_cls;
1315 it->finish_cb = finish_cb;
1316 it->finish_cb_cls = finish_cb_cls;
1318 it->proc_cls = proc_cls;
1320 it->identity = *identity;
1321 GNUNET_CONTAINER_DLL_insert_tail (h->it_head, h->it_tail, it);
1323 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
1324 msg->id = htonl (rid);
1325 msg->identity = *identity;
1329 GNUNET_MQ_send (h->mq, env);
1335 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
1336 * for the next record.
1338 * @param it the iterator
1341 GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
1343 struct GNUNET_RECLAIM_Handle *h = it->h;
1344 struct AttributeIterationNextMessage *msg;
1345 struct GNUNET_MQ_Envelope *env;
1348 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
1349 msg->id = htonl (it->r_id);
1350 GNUNET_MQ_send (h->mq, env);
1355 * Stops iteration and releases the handle for further calls. Must
1356 * be called on any iteration that has not yet completed prior to calling
1357 * #GNUNET_RECLAIM_disconnect.
1359 * @param it the iterator
1362 GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
1364 struct GNUNET_RECLAIM_Handle *h = it->h;
1365 struct GNUNET_MQ_Envelope *env;
1366 struct AttributeIterationStopMessage *msg;
1371 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
1372 msg->id = htonl (it->r_id);
1373 GNUNET_MQ_send (h->mq, env);
1380 * List all attestations for a local identity.
1381 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
1382 * for any other calls than #GNUNET_RECLAIM_get_attestations_next() and
1383 * #GNUNET_RECLAIM_get_attestations_stop. @a proc will be called once
1384 * immediately, and then again after
1385 * #GNUNET_RECLAIM_get_attestations_next() is invoked.
1387 * On error (disconnect), @a error_cb will be invoked.
1388 * On normal completion, @a finish_cb proc will be
1391 * @param h Handle to the re:claimID service
1392 * @param identity Identity to iterate over
1393 * @param error_cb Function to call on error (i.e. disconnect),
1394 * the handle is afterwards invalid
1395 * @param error_cb_cls Closure for @a error_cb
1396 * @param proc Function to call on each attestation
1397 * @param proc_cls Closure for @a proc
1398 * @param finish_cb Function to call on completion
1399 * the handle is afterwards invalid
1400 * @param finish_cb_cls Closure for @a finish_cb
1401 * @return an iterator Handle to use for iteration
1403 struct GNUNET_RECLAIM_AttestationIterator *
1404 GNUNET_RECLAIM_get_attestations_start (
1405 struct GNUNET_RECLAIM_Handle *h,
1406 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1407 GNUNET_SCHEDULER_TaskCallback error_cb,
1409 GNUNET_RECLAIM_AttestationResult proc,
1411 GNUNET_SCHEDULER_TaskCallback finish_cb,
1412 void *finish_cb_cls)
1414 struct GNUNET_RECLAIM_AttestationIterator *ait;
1415 struct GNUNET_MQ_Envelope *env;
1416 struct AttestationIterationStartMessage *msg;
1419 rid = h->r_id_gen++;
1420 ait = GNUNET_new (struct GNUNET_RECLAIM_AttestationIterator);
1422 ait->error_cb = error_cb;
1423 ait->error_cb_cls = error_cb_cls;
1424 ait->finish_cb = finish_cb;
1425 ait->finish_cb_cls = finish_cb_cls;
1427 ait->proc_cls = proc_cls;
1429 ait->identity = *identity;
1430 GNUNET_CONTAINER_DLL_insert_tail (h->ait_head, h->ait_tail, ait);
1432 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_START);
1433 msg->id = htonl (rid);
1434 msg->identity = *identity;
1438 GNUNET_MQ_send (h->mq, env);
1444 * Calls the record processor specified in #GNUNET_RECLAIM_get_attestation_start
1445 * for the next record.
1447 * @param it the iterator
1450 GNUNET_RECLAIM_get_attestations_next (struct 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 GNUNET_RECLAIM_AttestationIterator *ait)
1473 struct GNUNET_RECLAIM_Handle *h = ait->h;
1474 struct GNUNET_MQ_Envelope *env;
1475 struct AttestationIterationStopMessage *msg;
1480 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_STOP);
1481 msg->id = htonl (ait->r_id);
1482 GNUNET_MQ_send (h->mq, env);
1490 * Issues a ticket to another relying party. The identity may use
1491 * @GNUNET_RECLAIM_ticket_consume to consume the ticket
1492 * and retrieve the attributes specified in the attribute list.
1494 * @param h the reclaim to use
1495 * @param iss the issuing identity (= the user)
1496 * @param rp the subject of the ticket (= the relying party)
1497 * @param attrs the attributes that the relying party is given access to
1498 * @param cb the callback
1499 * @param cb_cls the callback closure
1500 * @return handle to abort the operation
1502 struct GNUNET_RECLAIM_Operation *
1503 GNUNET_RECLAIM_ticket_issue (
1504 struct GNUNET_RECLAIM_Handle *h,
1505 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1506 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1507 const struct GNUNET_RECLAIM_AttributeList *attrs,
1508 GNUNET_RECLAIM_TicketCallback cb,
1511 struct GNUNET_RECLAIM_Operation *op;
1512 struct IssueTicketMessage *tim;
1515 fprintf (stderr, "Issuing ticket\n");
1516 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1520 op->r_id = h->r_id_gen++;
1521 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1522 attr_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
1523 op->env = GNUNET_MQ_msg_extra (tim,
1525 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
1526 tim->identity = *iss;
1528 tim->id = htonl (op->r_id);
1530 GNUNET_RECLAIM_attribute_list_serialize (attrs, (char *) &tim[1]);
1532 tim->attr_len = htons (attr_len);
1534 GNUNET_MQ_send_copy (h->mq, op->env);
1540 * Consumes an issued ticket. The ticket is persisted
1541 * and used to retrieve identity information from the issuer
1543 * @param h the reclaim to use
1544 * @param identity the identity that is the subject of the issued ticket (the
1546 * @param ticket the issued ticket to consume
1547 * @param cb the callback to call
1548 * @param cb_cls the callback closure
1549 * @return handle to abort the operation
1551 struct GNUNET_RECLAIM_Operation *
1552 GNUNET_RECLAIM_ticket_consume (
1553 struct GNUNET_RECLAIM_Handle *h,
1554 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1555 const struct GNUNET_RECLAIM_Ticket *ticket,
1556 GNUNET_RECLAIM_AttributeTicketResult cb,
1559 struct GNUNET_RECLAIM_Operation *op;
1560 struct ConsumeTicketMessage *ctm;
1562 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1566 op->r_id = h->r_id_gen++;
1567 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1568 op->env = GNUNET_MQ_msg (ctm, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
1569 ctm->identity = *identity;
1570 ctm->id = htonl (op->r_id);
1571 ctm->ticket = *ticket;
1573 GNUNET_MQ_send_copy (h->mq, op->env);
1579 * Lists all tickets that have been issued to remote
1580 * identites (relying parties)
1582 * @param h the reclaim to use
1583 * @param identity the issuing identity
1584 * @param error_cb function to call on error (i.e. disconnect),
1585 * the handle is afterwards invalid
1586 * @param error_cb_cls closure for @a error_cb
1587 * @param proc function to call on each ticket; it
1588 * will be called repeatedly with a value (if available)
1589 * @param proc_cls closure for @a proc
1590 * @param finish_cb function to call on completion
1591 * the handle is afterwards invalid
1592 * @param finish_cb_cls closure for @a finish_cb
1593 * @return an iterator handle to use for iteration
1595 struct GNUNET_RECLAIM_TicketIterator *
1596 GNUNET_RECLAIM_ticket_iteration_start (
1597 struct GNUNET_RECLAIM_Handle *h,
1598 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1599 GNUNET_SCHEDULER_TaskCallback error_cb,
1601 GNUNET_RECLAIM_TicketCallback proc,
1603 GNUNET_SCHEDULER_TaskCallback finish_cb,
1604 void *finish_cb_cls)
1606 struct GNUNET_RECLAIM_TicketIterator *it;
1607 struct GNUNET_MQ_Envelope *env;
1608 struct TicketIterationStartMessage *msg;
1611 rid = h->r_id_gen++;
1612 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1614 it->error_cb = error_cb;
1615 it->error_cb_cls = error_cb_cls;
1616 it->finish_cb = finish_cb;
1617 it->finish_cb_cls = finish_cb_cls;
1621 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it);
1622 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1623 msg->id = htonl (rid);
1624 msg->identity = *identity;
1628 GNUNET_MQ_send (h->mq, env);
1634 * Calls the ticket processor specified in
1635 * #GNUNET_RECLAIM_ticket_iteration_start for the next record.
1637 * @param it the iterator
1640 GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
1642 struct GNUNET_RECLAIM_Handle *h = it->h;
1643 struct TicketIterationNextMessage *msg;
1644 struct GNUNET_MQ_Envelope *env;
1646 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
1647 msg->id = htonl (it->r_id);
1648 GNUNET_MQ_send (h->mq, env);
1653 * Stops iteration and releases the handle for further calls. Must
1654 * be called on any iteration that has not yet completed prior to calling
1655 * #GNUNET_RECLAIM_disconnect.
1657 * @param it the iterator
1660 GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
1662 struct GNUNET_RECLAIM_Handle *h = it->h;
1663 struct GNUNET_MQ_Envelope *env;
1664 struct TicketIterationStopMessage *msg;
1669 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
1670 msg->id = htonl (it->r_id);
1671 GNUNET_MQ_send (h->mq, env);
1678 * Revoked an issued ticket. The relying party will be unable to retrieve
1679 * attributes. Other issued tickets remain unaffected.
1680 * This includes tickets issued to other relying parties as well as to
1681 * other tickets issued to the audience specified in this ticket.
1683 * @param h the identity provider to use
1684 * @param identity the issuing identity
1685 * @param ticket the ticket to revoke
1686 * @param cb the callback
1687 * @param cb_cls the callback closure
1688 * @return handle to abort the operation
1690 struct GNUNET_RECLAIM_Operation *
1691 GNUNET_RECLAIM_ticket_revoke (
1692 struct GNUNET_RECLAIM_Handle *h,
1693 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1694 const struct GNUNET_RECLAIM_Ticket *ticket,
1695 GNUNET_RECLAIM_ContinuationWithStatus cb,
1698 struct GNUNET_RECLAIM_Operation *op;
1699 struct RevokeTicketMessage *msg;
1702 rid = h->r_id_gen++;
1703 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1708 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1709 op->env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
1710 msg->id = htonl (rid);
1711 msg->identity = *identity;
1712 msg->ticket = *ticket;
1715 GNUNET_MQ_send (h->mq, op->env);
1722 /* end of reclaim_api.c */