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 * Revocation result callback
77 GNUNET_RECLAIM_ContinuationWithStatus rvk_cb;
80 * Ticket result callback
82 GNUNET_RECLAIM_TicketCallback tr_cb;
85 * Envelope with the message for this queue entry.
87 struct GNUNET_MQ_Envelope *env;
95 * Closure for @e cont or @e cb.
102 * Handle for a ticket iterator operation
104 struct GNUNET_RECLAIM_TicketIterator
109 struct GNUNET_RECLAIM_TicketIterator *next;
114 struct GNUNET_RECLAIM_TicketIterator *prev;
117 * Main handle to access the idp.
119 struct GNUNET_RECLAIM_Handle *h;
122 * Function to call on completion.
124 GNUNET_SCHEDULER_TaskCallback finish_cb;
127 * Closure for @e finish_cb.
132 * The continuation to call with the results
134 GNUNET_RECLAIM_TicketCallback tr_cb;
137 * Closure for @e tr_cb.
142 * Function to call on errors.
144 GNUNET_SCHEDULER_TaskCallback error_cb;
147 * Closure for @e error_cb.
152 * Envelope of the message to send to the service, if not yet
155 struct GNUNET_MQ_Envelope *env;
158 * The operation id this zone iteration operation has
165 * Handle for a attribute iterator operation
167 struct GNUNET_RECLAIM_AttributeIterator
172 struct GNUNET_RECLAIM_AttributeIterator *next;
177 struct GNUNET_RECLAIM_AttributeIterator *prev;
180 * Main handle to access the service.
182 struct GNUNET_RECLAIM_Handle *h;
185 * Function to call on completion.
187 GNUNET_SCHEDULER_TaskCallback finish_cb;
190 * Closure for @e finish_cb.
195 * The continuation to call with the results
197 GNUNET_RECLAIM_AttributeResult proc;
200 * Closure for @e proc.
205 * Function to call on errors.
207 GNUNET_SCHEDULER_TaskCallback error_cb;
210 * Closure for @e error_cb.
215 * Envelope of the message to send to the service, if not yet
218 struct GNUNET_MQ_Envelope *env;
221 * Private key of the zone.
223 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
226 * The operation id this zone iteration operation has
233 * Handle to the service.
235 struct GNUNET_RECLAIM_Handle
238 * Configuration to use.
240 const struct GNUNET_CONFIGURATION_Handle *cfg;
243 * Socket (if available).
245 struct GNUNET_CLIENT_Connection *client;
253 * Head of active operations.
255 struct GNUNET_RECLAIM_Operation *op_head;
258 * Tail of active operations.
260 struct GNUNET_RECLAIM_Operation *op_tail;
263 * Head of active iterations
265 struct GNUNET_RECLAIM_AttributeIterator *it_head;
268 * Tail of active iterations
270 struct GNUNET_RECLAIM_AttributeIterator *it_tail;
273 * Head of active iterations
275 struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
278 * Tail of active iterations
280 struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
283 * Currently pending transmission request, or NULL for none.
285 struct GNUNET_CLIENT_TransmitHandle *th;
288 * Task doing exponential back-off trying to reconnect.
290 struct GNUNET_SCHEDULER_Task *reconnect_task;
293 * Time for next connect retry.
295 struct GNUNET_TIME_Relative reconnect_backoff;
298 * Connection to service (if available).
300 struct GNUNET_MQ_Handle *mq;
303 * Request Id generator. Incremented by one for each request.
308 * Are we polling for incoming messages right now?
315 * Try again to connect to the service.
317 * @param h handle to the reclaim service.
320 reconnect (struct GNUNET_RECLAIM_Handle *h);
326 * @param cls the handle
329 reconnect_task (void *cls)
331 struct GNUNET_RECLAIM_Handle *handle = cls;
333 handle->reconnect_task = NULL;
339 * Disconnect from service and then reconnect.
341 * @param handle our service
344 force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
346 GNUNET_MQ_destroy (handle->mq);
348 handle->reconnect_backoff =
349 GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
350 handle->reconnect_task =
351 GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
360 * @param it entry to free
363 free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
365 struct GNUNET_RECLAIM_Handle *h = it->h;
367 GNUNET_CONTAINER_DLL_remove (h->it_head, h->it_tail, it);
369 GNUNET_MQ_discard (it->env);
377 * @param op the operation to free
380 free_op (struct GNUNET_RECLAIM_Operation *op)
385 GNUNET_MQ_discard (op->env);
391 * Generic error handler, called with the appropriate error code and
392 * the same closure specified at the creation of the message queue.
393 * Not every message queue implementation supports an error handler.
395 * @param cls closure with the `struct GNUNET_GNS_Handle *`
396 * @param error error code
399 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
401 struct GNUNET_RECLAIM_Handle *handle = cls;
403 force_reconnect (handle);
408 * Handle an incoming message of type
409 * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE
412 * @param msg the message we received
415 handle_success_response (void *cls, const struct SuccessResultMessage *msg)
417 struct GNUNET_RECLAIM_Handle *h = cls;
418 struct GNUNET_RECLAIM_Operation *op;
419 uint32_t r_id = ntohl (msg->id);
423 for (op = h->op_head; NULL != op; op = op->next)
424 if (op->r_id == r_id)
429 res = ntohl (msg->op_result);
430 LOG (GNUNET_ERROR_TYPE_DEBUG,
431 "Received SUCCESS_RESPONSE with result %d\n",
434 /* TODO: add actual error message to response... */
435 if (GNUNET_SYSERR == res)
436 emsg = _ ("failed to store record\n");
439 if (NULL != op->as_cb)
440 op->as_cb (op->cls, res, emsg);
441 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
447 * Handle an incoming message of type
448 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
451 * @param msg the message we received
452 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
455 check_consume_ticket_result (void *cls,
456 const struct ConsumeTicketResultMessage *msg)
461 msg_len = ntohs (msg->header.size);
462 attrs_len = ntohs (msg->attrs_len);
463 if (msg_len != sizeof(struct ConsumeTicketResultMessage) + attrs_len)
466 return GNUNET_SYSERR;
473 * Handle an incoming message of type
474 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
477 * @param msg the message we received
480 handle_consume_ticket_result (void *cls,
481 const struct ConsumeTicketResultMessage *msg)
483 struct GNUNET_RECLAIM_Handle *h = cls;
484 struct GNUNET_RECLAIM_Operation *op;
486 uint32_t r_id = ntohl (msg->id);
488 attrs_len = ntohs (msg->attrs_len);
489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
492 for (op = h->op_head; NULL != op; op = op->next)
493 if (op->r_id == r_id)
499 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
500 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
501 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
503 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &msg[1], attrs_len);
504 if (NULL != op->ar_cb)
508 op->ar_cb (op->cls, &msg->identity, NULL, NULL, NULL);
512 for (le = attrs->list_head; NULL != le; le = le->next)
514 if (le->reference != NULL && le->attest == NULL)
516 for (le2 = attrs->list_head; NULL != le2; le2 = le2->next)
518 if (le2->attest != NULL && le2->attest->id == le->reference->id_attest)
520 op->ar_cb (op->cls, &msg->identity, le->claim, le2->attest, le->reference);
527 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
530 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
532 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
534 GNUNET_free_non_null (attrs);
542 * Handle an incoming message of type
543 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
546 * @param msg the message we received
547 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
550 check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
555 msg_len = ntohs (msg->header.size);
556 attr_len = ntohs (msg->attr_len);
557 if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
560 return GNUNET_SYSERR;
567 * Handle an incoming message of type
568 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
571 * @param msg the message we received
574 handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
576 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
577 struct GNUNET_RECLAIM_Handle *h = cls;
578 struct GNUNET_RECLAIM_AttributeIterator *it;
579 struct GNUNET_RECLAIM_Operation *op;
581 uint32_t r_id = ntohl (msg->id);
583 attr_len = ntohs (msg->attr_len);
584 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
587 for (it = h->it_head; NULL != it; it = it->next)
588 if (it->r_id == r_id)
590 for (op = h->op_head; NULL != op; op = op->next)
591 if (op->r_id == r_id)
593 if ((NULL == it) && (NULL == op))
597 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
599 if ((NULL == it) && (NULL == op))
607 if (NULL != it->finish_cb)
608 it->finish_cb (it->finish_cb_cls);
613 if (NULL != op->ar_cb)
614 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
615 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
622 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
623 attr = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &msg[1], attr_len);
626 if (NULL != it->proc)
627 it->proc (it->proc_cls, &msg->identity, attr, NULL, NULL);
631 if (NULL != op->ar_cb)
632 op->ar_cb (op->cls, &msg->identity, attr, NULL, NULL);
641 * Handle an incoming message of type
642 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
645 * @param msg the message we received
646 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
649 check_attestation_result (void *cls, const struct AttributeResultMessage *msg)
654 msg_len = ntohs (msg->header.size);
655 attr_len = ntohs (msg->attr_len);
656 if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
659 return GNUNET_SYSERR;
666 * Handle an incoming message of type
667 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
670 * @param msg the message we received
673 handle_attestation_result (void *cls, const struct AttributeResultMessage *msg)
675 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
676 struct GNUNET_RECLAIM_Handle *h = cls;
677 struct GNUNET_RECLAIM_AttributeIterator *it;
678 struct GNUNET_RECLAIM_Operation *op;
680 uint32_t r_id = ntohl (msg->id);
682 attr_len = ntohs (msg->attr_len);
683 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attestation result.\n");
686 for (it = h->it_head; NULL != it; it = it->next)
687 if (it->r_id == r_id)
689 for (op = h->op_head; NULL != op; op = op->next)
690 if (op->r_id == r_id)
692 if ((NULL == it) && (NULL == op))
696 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
698 if ((NULL == it) && (NULL == op))
706 if (NULL != it->finish_cb)
707 it->finish_cb (it->finish_cb_cls);
712 if (NULL != op->ar_cb)
713 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
714 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
721 struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
722 attr = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1], attr_len);
725 if (NULL != it->proc)
726 it->proc (it->proc_cls, &msg->identity, NULL, attr, NULL);
730 if (NULL != op->ar_cb)
731 op->ar_cb (op->cls, &msg->identity, NULL, attr, NULL);
740 * Handle an incoming message of type
741 * #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
744 * @param msg the message we received
745 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
748 check_reference_result (void *cls, const struct ReferenceResultMessage *msg)
754 msg_len = ntohs (msg->header.size);
755 attr_len = ntohs (msg->attest_len);
756 ref_len = ntohs (msg->ref_len);
757 if (msg_len != sizeof(struct ReferenceResultMessage) + attr_len + ref_len)
760 return GNUNET_SYSERR;
766 * Handle an incoming message of type
767 * #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
770 * @param msg the message we received
773 handle_reference_result (void *cls, const struct ReferenceResultMessage *msg)
775 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
776 struct GNUNET_RECLAIM_Handle *h = cls;
777 struct GNUNET_RECLAIM_AttributeIterator *it;
778 struct GNUNET_RECLAIM_Operation *op;
781 uint32_t r_id = ntohl (msg->id);
782 attest_len = ntohs (msg->attest_len);
783 ref_len = ntohs (msg->ref_len);
784 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing reference result.\n");
785 for (it = h->it_head; NULL != it; it = it->next)
786 if (it->r_id == r_id)
788 for (op = h->op_head; NULL != op; op = op->next)
789 if (op->r_id == r_id)
791 if ((NULL == it) && (NULL == op))
795 (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
797 if ((NULL == it) && (NULL == op))
805 if (NULL != it->finish_cb)
806 it->finish_cb (it->finish_cb_cls);
811 if (NULL != op->ar_cb)
812 op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
813 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
820 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
821 struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
822 attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1],
824 ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &msg[1]
829 if (NULL != it->proc)
830 it->proc (it->proc_cls, &msg->identity, NULL, attest, ref);
834 if (NULL != op->ar_cb)
835 op->ar_cb (op->cls, &msg->identity, NULL, attest, ref);
838 GNUNET_free (attest);
845 * Handle an incoming message of type
846 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
849 * @param msg the message we received
852 handle_ticket_result (void *cls, const struct TicketResultMessage *msg)
854 struct GNUNET_RECLAIM_Handle *handle = cls;
855 struct GNUNET_RECLAIM_Operation *op;
856 struct GNUNET_RECLAIM_TicketIterator *it;
857 uint32_t r_id = ntohl (msg->id);
858 static const struct GNUNET_RECLAIM_Ticket ticket;
860 for (op = handle->op_head; NULL != op; op = op->next)
861 if (op->r_id == r_id)
863 for (it = handle->ticket_it_head; NULL != it; it = it->next)
864 if (it->r_id == r_id)
866 if ((NULL == op) && (NULL == it))
870 GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
872 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
874 if (NULL != op->tr_cb)
875 op->tr_cb (op->cls, NULL);
879 if (NULL != op->tr_cb)
880 op->tr_cb (op->cls, &msg->ticket);
888 memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
890 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
891 handle->ticket_it_tail,
893 it->finish_cb (it->finish_cb_cls);
898 if (NULL != it->tr_cb)
899 it->tr_cb (it->cls, &msg->ticket);
908 * Handle an incoming message of type
909 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
912 * @param msg the message we received
915 handle_revoke_ticket_result (void *cls,
916 const struct RevokeTicketResultMessage *msg)
918 struct GNUNET_RECLAIM_Handle *h = cls;
919 struct GNUNET_RECLAIM_Operation *op;
920 uint32_t r_id = ntohl (msg->id);
923 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
926 for (op = h->op_head; NULL != op; op = op->next)
927 if (op->r_id == r_id)
931 success = ntohl (msg->success);
933 if (NULL != op->rvk_cb)
935 op->rvk_cb (op->cls, success, NULL);
937 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
946 * Try again to connect to the service.
948 * @param h handle to the reclaim service.
951 reconnect (struct GNUNET_RECLAIM_Handle *h)
953 struct GNUNET_MQ_MessageHandler handlers[] =
954 { GNUNET_MQ_hd_fixed_size (success_response,
955 GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
956 struct SuccessResultMessage,
958 GNUNET_MQ_hd_var_size (attribute_result,
959 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
960 struct AttributeResultMessage,
962 GNUNET_MQ_hd_var_size (attestation_result,
963 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT,
964 struct AttributeResultMessage,
966 GNUNET_MQ_hd_var_size (reference_result,
967 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT,
968 struct ReferenceResultMessage,
970 GNUNET_MQ_hd_fixed_size (ticket_result,
971 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
972 struct TicketResultMessage,
974 GNUNET_MQ_hd_var_size (consume_ticket_result,
975 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
976 struct ConsumeTicketResultMessage,
978 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
979 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
980 struct RevokeTicketResultMessage,
982 GNUNET_MQ_handler_end () };
983 struct GNUNET_RECLAIM_Operation *op;
985 GNUNET_assert (NULL == h->mq);
986 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
989 GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
992 for (op = h->op_head; NULL != op; op = op->next)
993 GNUNET_MQ_send_copy (h->mq, op->env);
998 * Connect to the reclaim service.
1000 * @param cfg the configuration to use
1001 * @return handle to use
1003 struct GNUNET_RECLAIM_Handle *
1004 GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
1006 struct GNUNET_RECLAIM_Handle *h;
1008 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
1021 * Cancel an operation. Note that the operation MAY still
1022 * be executed; this merely cancels the continuation; if the request
1023 * was already transmitted, the service may still choose to complete
1026 * @param op operation to cancel
1029 GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
1031 struct GNUNET_RECLAIM_Handle *h = op->h;
1033 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
1039 * Disconnect from service
1041 * @param h handle to destroy
1044 GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
1046 GNUNET_assert (NULL != h);
1049 GNUNET_MQ_destroy (h->mq);
1052 if (NULL != h->reconnect_task)
1054 GNUNET_SCHEDULER_cancel (h->reconnect_task);
1055 h->reconnect_task = NULL;
1057 GNUNET_assert (NULL == h->op_head);
1063 * Store an attribute. If the attribute is already present,
1064 * it is replaced with the new attribute.
1066 * @param h handle to the re:claimID service
1067 * @param pkey private key of the identity
1068 * @param attr the attribute value
1069 * @param exp_interval the relative expiration interval for the attribute
1070 * @param cont continuation to call when done
1071 * @param cont_cls closure for @a cont
1072 * @return handle to abort the request
1074 struct GNUNET_RECLAIM_Operation *
1075 GNUNET_RECLAIM_attribute_store (
1076 struct GNUNET_RECLAIM_Handle *h,
1077 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1078 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1079 const struct GNUNET_TIME_Relative *exp_interval,
1080 GNUNET_RECLAIM_ContinuationWithStatus cont,
1083 struct GNUNET_RECLAIM_Operation *op;
1084 struct AttributeStoreMessage *sam;
1087 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1091 op->r_id = h->r_id_gen++;
1092 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1093 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (attr);
1094 op->env = GNUNET_MQ_msg_extra (sam,
1096 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
1097 sam->identity = *pkey;
1098 sam->id = htonl (op->r_id);
1099 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1101 GNUNET_RECLAIM_ATTRIBUTE_serialize (attr, (char *) &sam[1]);
1103 sam->attr_len = htons (attr_len);
1105 GNUNET_MQ_send_copy (h->mq, op->env);
1111 * Delete an attribute. Tickets used to share this attribute are updated
1114 * @param h handle to the re:claimID service
1115 * @param pkey Private key of the identity to add an attribute to
1116 * @param attr The attribute
1117 * @param cont Continuation to call when done
1118 * @param cont_cls Closure for @a cont
1119 * @return handle Used to to abort the request
1121 struct GNUNET_RECLAIM_Operation *
1122 GNUNET_RECLAIM_attribute_delete (
1123 struct GNUNET_RECLAIM_Handle *h,
1124 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1125 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1126 GNUNET_RECLAIM_ContinuationWithStatus cont,
1129 struct GNUNET_RECLAIM_Operation *op;
1130 struct AttributeDeleteMessage *dam;
1133 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1137 op->r_id = h->r_id_gen++;
1138 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1139 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (attr);
1140 op->env = GNUNET_MQ_msg_extra (dam,
1142 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE);
1143 dam->identity = *pkey;
1144 dam->id = htonl (op->r_id);
1145 GNUNET_RECLAIM_ATTRIBUTE_serialize (attr, (char *) &dam[1]);
1147 dam->attr_len = htons (attr_len);
1149 GNUNET_MQ_send_copy (h->mq, op->env);
1154 * Store an attestation. If the attestation is already present,
1155 * it is replaced with the new attestation.
1157 * @param h handle to the re:claimID service
1158 * @param pkey private key of the identity
1159 * @param attr the attestation value
1160 * @param exp_interval the relative expiration interval for the attestation
1161 * @param cont continuation to call when done
1162 * @param cont_cls closure for @a cont
1163 * @return handle to abort the request
1165 struct GNUNET_RECLAIM_Operation *
1166 GNUNET_RECLAIM_attestation_store (
1167 struct GNUNET_RECLAIM_Handle *h,
1168 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1169 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
1170 const struct GNUNET_TIME_Relative *exp_interval,
1171 GNUNET_RECLAIM_ContinuationWithStatus cont,
1174 struct GNUNET_RECLAIM_Operation *op;
1175 struct AttributeStoreMessage *sam;
1178 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1182 op->r_id = h->r_id_gen++;
1183 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1184 attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attr);
1185 op->env = GNUNET_MQ_msg_extra (sam,
1187 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE);
1188 sam->identity = *pkey;
1189 sam->id = htonl (op->r_id);
1190 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1192 GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &sam[1]);
1194 sam->attr_len = htons (attr_len);
1196 GNUNET_MQ_send_copy (h->mq, op->env);
1201 * Delete an attestation. Tickets used to share this attestation are updated
1204 * @param h handle to the re:claimID service
1205 * @param pkey Private key of the identity to add an attribute to
1206 * @param attr The attestation
1207 * @param cont Continuation to call when done
1208 * @param cont_cls Closure for @a cont
1209 * @return handle Used to to abort the request
1211 struct GNUNET_RECLAIM_Operation *
1212 GNUNET_RECLAIM_attestation_delete (
1213 struct GNUNET_RECLAIM_Handle *h,
1214 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1215 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
1216 GNUNET_RECLAIM_ContinuationWithStatus cont,
1219 struct GNUNET_RECLAIM_Operation *op;
1220 struct AttributeDeleteMessage *dam;
1223 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1227 op->r_id = h->r_id_gen++;
1228 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1229 attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attr);
1230 op->env = GNUNET_MQ_msg_extra (dam,
1232 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE);
1233 dam->identity = *pkey;
1234 dam->id = htonl (op->r_id);
1235 GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &dam[1]);
1237 dam->attr_len = htons (attr_len);
1239 GNUNET_MQ_send_copy (h->mq, op->env);
1244 * Store an attestation reference. If the reference is already present,
1245 * it is replaced with the new reference.
1247 * @param h handle to the re:claimID service
1248 * @param pkey private key of the identity
1249 * @param attr the reference value
1250 * @param exp_interval the relative expiration interval for the reference
1251 * @param cont continuation to call when done
1252 * @param cont_cls closure for @a cont
1253 * @return handle to abort the request
1255 struct GNUNET_RECLAIM_Operation *
1256 GNUNET_RECLAIM_attestation_reference_store (
1257 struct GNUNET_RECLAIM_Handle *h,
1258 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1259 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
1260 const struct GNUNET_TIME_Relative *exp_interval,
1261 GNUNET_RECLAIM_ContinuationWithStatus cont,
1264 struct GNUNET_RECLAIM_Operation *op;
1265 struct AttributeStoreMessage *sam;
1267 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1271 op->r_id = h->r_id_gen++;
1272 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1273 attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
1274 op->env = GNUNET_MQ_msg_extra (sam,
1276 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE);
1277 sam->identity = *pkey;
1278 sam->id = htonl (op->r_id);
1279 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
1281 GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &sam[1]);
1283 sam->attr_len = htons (attr_len);
1285 GNUNET_MQ_send_copy (h->mq, op->env);
1290 * Delete an attestation reference. Tickets used to share this reference are updated
1293 * @param h handle to the re:claimID service
1294 * @param pkey Private key of the identity to delete the reference from
1295 * @param attr The reference
1296 * @param cont Continuation to call when done
1297 * @param cont_cls Closure for @a cont
1298 * @return handle Used to to abort the request
1300 struct GNUNET_RECLAIM_Operation *
1301 GNUNET_RECLAIM_attestation_reference_delete (
1302 struct GNUNET_RECLAIM_Handle *h,
1303 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1304 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
1305 GNUNET_RECLAIM_ContinuationWithStatus cont,
1309 struct GNUNET_RECLAIM_Operation *op;
1310 struct AttributeDeleteMessage *dam;
1313 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1317 op->r_id = h->r_id_gen++;
1318 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1319 attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
1320 op->env = GNUNET_MQ_msg_extra (dam,
1322 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE);
1323 dam->identity = *pkey;
1324 dam->id = htonl (op->r_id);
1325 GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &dam[1]);
1327 dam->attr_len = htons (attr_len);
1329 GNUNET_MQ_send_copy (h->mq, op->env);
1334 * List all attributes for a local identity.
1335 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
1336 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
1337 * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
1338 * immediately, and then again after
1339 * #GNUNET_RECLAIM_get_attributes_next() is invoked.
1341 * On error (disconnect), @a error_cb will be invoked.
1342 * On normal completion, @a finish_cb proc will be
1345 * @param h Handle to the re:claimID service
1346 * @param identity Identity to iterate over
1347 * @param error_cb Function to call on error (i.e. disconnect),
1348 * the handle is afterwards invalid
1349 * @param error_cb_cls Closure for @a error_cb
1350 * @param proc Function to call on each attribute
1351 * @param proc_cls Closure for @a proc
1352 * @param finish_cb Function to call on completion
1353 * the handle is afterwards invalid
1354 * @param finish_cb_cls Closure for @a finish_cb
1355 * @return an iterator Handle to use for iteration
1357 struct GNUNET_RECLAIM_AttributeIterator *
1358 GNUNET_RECLAIM_get_attributes_start (
1359 struct GNUNET_RECLAIM_Handle *h,
1360 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1361 GNUNET_SCHEDULER_TaskCallback error_cb,
1363 GNUNET_RECLAIM_AttributeResult proc,
1365 GNUNET_SCHEDULER_TaskCallback finish_cb,
1366 void *finish_cb_cls)
1368 struct GNUNET_RECLAIM_AttributeIterator *it;
1369 struct GNUNET_MQ_Envelope *env;
1370 struct AttributeIterationStartMessage *msg;
1373 rid = h->r_id_gen++;
1374 it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
1376 it->error_cb = error_cb;
1377 it->error_cb_cls = error_cb_cls;
1378 it->finish_cb = finish_cb;
1379 it->finish_cb_cls = finish_cb_cls;
1381 it->proc_cls = proc_cls;
1383 it->identity = *identity;
1384 GNUNET_CONTAINER_DLL_insert_tail (h->it_head, h->it_tail, it);
1386 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
1387 msg->id = htonl (rid);
1388 msg->identity = *identity;
1392 GNUNET_MQ_send (h->mq, env);
1398 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
1399 * for the next record.
1401 * @param it the iterator
1404 GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
1406 struct GNUNET_RECLAIM_Handle *h = it->h;
1407 struct AttributeIterationNextMessage *msg;
1408 struct GNUNET_MQ_Envelope *env;
1411 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
1412 msg->id = htonl (it->r_id);
1413 GNUNET_MQ_send (h->mq, env);
1418 * Stops iteration and releases the handle for further calls. Must
1419 * be called on any iteration that has not yet completed prior to calling
1420 * #GNUNET_RECLAIM_disconnect.
1422 * @param it the iterator
1425 GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
1427 struct GNUNET_RECLAIM_Handle *h = it->h;
1428 struct GNUNET_MQ_Envelope *env;
1429 struct AttributeIterationStopMessage *msg;
1434 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
1435 msg->id = htonl (it->r_id);
1436 GNUNET_MQ_send (h->mq, env);
1443 * Issues a ticket to another relying party. The identity may use
1444 * @GNUNET_RECLAIM_ticket_consume to consume the ticket
1445 * and retrieve the attributes specified in the attribute list.
1447 * @param h the reclaim to use
1448 * @param iss the issuing identity (= the user)
1449 * @param rp the subject of the ticket (= the relying party)
1450 * @param attrs the attributes that the relying party is given access to
1451 * @param cb the callback
1452 * @param cb_cls the callback closure
1453 * @return handle to abort the operation
1455 struct GNUNET_RECLAIM_Operation *
1456 GNUNET_RECLAIM_ticket_issue (
1457 struct GNUNET_RECLAIM_Handle *h,
1458 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1459 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1460 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
1461 GNUNET_RECLAIM_TicketCallback cb,
1464 struct GNUNET_RECLAIM_Operation *op;
1465 struct IssueTicketMessage *tim;
1468 fprintf (stderr, "Issuing ticket\n");
1469 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1473 op->r_id = h->r_id_gen++;
1474 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1475 attr_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
1476 op->env = GNUNET_MQ_msg_extra (tim,
1478 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
1479 tim->identity = *iss;
1481 tim->id = htonl (op->r_id);
1483 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, (char *) &tim[1]);
1485 tim->attr_len = htons (attr_len);
1487 GNUNET_MQ_send_copy (h->mq, op->env);
1493 * Consumes an issued ticket. The ticket is persisted
1494 * and used to retrieve identity information from the issuer
1496 * @param h the reclaim to use
1497 * @param identity the identity that is the subject of the issued ticket (the
1499 * @param ticket the issued ticket to consume
1500 * @param cb the callback to call
1501 * @param cb_cls the callback closure
1502 * @return handle to abort the operation
1504 struct GNUNET_RECLAIM_Operation *
1505 GNUNET_RECLAIM_ticket_consume (
1506 struct GNUNET_RECLAIM_Handle *h,
1507 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1508 const struct GNUNET_RECLAIM_Ticket *ticket,
1509 GNUNET_RECLAIM_AttributeResult cb,
1512 struct GNUNET_RECLAIM_Operation *op;
1513 struct ConsumeTicketMessage *ctm;
1515 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1519 op->r_id = h->r_id_gen++;
1520 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1521 op->env = GNUNET_MQ_msg (ctm, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
1522 ctm->identity = *identity;
1523 ctm->id = htonl (op->r_id);
1524 ctm->ticket = *ticket;
1526 GNUNET_MQ_send_copy (h->mq, op->env);
1532 * Lists all tickets that have been issued to remote
1533 * identites (relying parties)
1535 * @param h the reclaim to use
1536 * @param identity the issuing identity
1537 * @param error_cb function to call on error (i.e. disconnect),
1538 * the handle is afterwards invalid
1539 * @param error_cb_cls closure for @a error_cb
1540 * @param proc function to call on each ticket; it
1541 * will be called repeatedly with a value (if available)
1542 * @param proc_cls closure for @a proc
1543 * @param finish_cb function to call on completion
1544 * the handle is afterwards invalid
1545 * @param finish_cb_cls closure for @a finish_cb
1546 * @return an iterator handle to use for iteration
1548 struct GNUNET_RECLAIM_TicketIterator *
1549 GNUNET_RECLAIM_ticket_iteration_start (
1550 struct GNUNET_RECLAIM_Handle *h,
1551 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1552 GNUNET_SCHEDULER_TaskCallback error_cb,
1554 GNUNET_RECLAIM_TicketCallback proc,
1556 GNUNET_SCHEDULER_TaskCallback finish_cb,
1557 void *finish_cb_cls)
1559 struct GNUNET_RECLAIM_TicketIterator *it;
1560 struct GNUNET_MQ_Envelope *env;
1561 struct TicketIterationStartMessage *msg;
1564 rid = h->r_id_gen++;
1565 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1567 it->error_cb = error_cb;
1568 it->error_cb_cls = error_cb_cls;
1569 it->finish_cb = finish_cb;
1570 it->finish_cb_cls = finish_cb_cls;
1574 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it);
1575 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1576 msg->id = htonl (rid);
1577 msg->identity = *identity;
1581 GNUNET_MQ_send (h->mq, env);
1587 * Calls the ticket processor specified in
1588 * #GNUNET_RECLAIM_ticket_iteration_start for the next record.
1590 * @param it the iterator
1593 GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
1595 struct GNUNET_RECLAIM_Handle *h = it->h;
1596 struct TicketIterationNextMessage *msg;
1597 struct GNUNET_MQ_Envelope *env;
1599 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
1600 msg->id = htonl (it->r_id);
1601 GNUNET_MQ_send (h->mq, env);
1606 * Stops iteration and releases the handle for further calls. Must
1607 * be called on any iteration that has not yet completed prior to calling
1608 * #GNUNET_RECLAIM_disconnect.
1610 * @param it the iterator
1613 GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
1615 struct GNUNET_RECLAIM_Handle *h = it->h;
1616 struct GNUNET_MQ_Envelope *env;
1617 struct TicketIterationStopMessage *msg;
1622 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
1623 msg->id = htonl (it->r_id);
1624 GNUNET_MQ_send (h->mq, env);
1631 * Revoked an issued ticket. The relying party will be unable to retrieve
1632 * attributes. Other issued tickets remain unaffected.
1633 * This includes tickets issued to other relying parties as well as to
1634 * other tickets issued to the audience specified in this ticket.
1636 * @param h the identity provider to use
1637 * @param identity the issuing identity
1638 * @param ticket the ticket to revoke
1639 * @param cb the callback
1640 * @param cb_cls the callback closure
1641 * @return handle to abort the operation
1643 struct GNUNET_RECLAIM_Operation *
1644 GNUNET_RECLAIM_ticket_revoke (
1645 struct GNUNET_RECLAIM_Handle *h,
1646 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1647 const struct GNUNET_RECLAIM_Ticket *ticket,
1648 GNUNET_RECLAIM_ContinuationWithStatus cb,
1651 struct GNUNET_RECLAIM_Operation *op;
1652 struct RevokeTicketMessage *msg;
1655 rid = h->r_id_gen++;
1656 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1661 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1662 op->env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
1663 msg->id = htonl (rid);
1664 msg->identity = *identity;
1665 msg->ticket = *ticket;
1668 GNUNET_MQ_send (h->mq, op->env);
1675 /* end of reclaim_api.c */