aboutsummaryrefslogtreecommitdiff
path: root/src/identity-provider/identity_provider_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/identity-provider/identity_provider_api.c')
-rw-r--r--src/identity-provider/identity_provider_api.c1213
1 files changed, 969 insertions, 244 deletions
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c
index 845d1f753..d0ece80fe 100644
--- a/src/identity-provider/identity_provider_api.c
+++ b/src/identity-provider/identity_provider_api.c
@@ -29,12 +29,12 @@
29#include "gnunet_protocols.h" 29#include "gnunet_protocols.h"
30#include "gnunet_mq_lib.h" 30#include "gnunet_mq_lib.h"
31#include "gnunet_identity_provider_service.h" 31#include "gnunet_identity_provider_service.h"
32#include "gnunet_identity_attribute_lib.h"
32#include "identity_provider.h" 33#include "identity_provider.h"
33 34
34#define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__) 35#define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__)
35 36
36 37
37
38/** 38/**
39 * Handle for an operation with the service. 39 * Handle for an operation with the service.
40 */ 40 */
@@ -63,16 +63,24 @@ struct GNUNET_IDENTITY_PROVIDER_Operation
63 const struct GNUNET_MessageHeader *msg; 63 const struct GNUNET_MessageHeader *msg;
64 64
65 /** 65 /**
66 * Continuation to invoke with the result of the transmission; @e cb 66 * Continuation to invoke after attribute store call
67 * will be NULL in this case. 67 */
68 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus as_cb;
69
70 /**
71 * Attribute result callback
72 */
73 GNUNET_IDENTITY_PROVIDER_AttributeResult ar_cb;
74
75 /**
76 * Revocation result callback
68 */ 77 */
69 GNUNET_IDENTITY_PROVIDER_ExchangeCallback ex_cb; 78 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus rvk_cb;
70 79
71 /** 80 /**
72 * Continuation to invoke with the result of the transmission for 81 * Ticket result callback
73 * 'issue' operations (@e cont will be NULL in this case).
74 */ 82 */
75 GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb; 83 GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb;
76 84
77 /** 85 /**
78 * Envelope with the message for this queue entry. 86 * Envelope with the message for this queue entry.
@@ -91,6 +99,140 @@ struct GNUNET_IDENTITY_PROVIDER_Operation
91 99
92}; 100};
93 101
102/**
103 * Handle for a ticket iterator operation
104 */
105struct GNUNET_IDENTITY_PROVIDER_TicketIterator
106{
107
108 /**
109 * Kept in a DLL.
110 */
111 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *next;
112
113 /**
114 * Kept in a DLL.
115 */
116 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *prev;
117
118 /**
119 * Main handle to access the idp.
120 */
121 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
122
123 /**
124 * Function to call on completion.
125 */
126 GNUNET_SCHEDULER_TaskCallback finish_cb;
127
128 /**
129 * Closure for @e error_cb.
130 */
131 void *finish_cb_cls;
132
133 /**
134 * The continuation to call with the results
135 */
136 GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb;
137
138 /**
139 * Closure for @e tr_cb.
140 */
141 void *cls;
142
143 /**
144 * Function to call on errors.
145 */
146 GNUNET_SCHEDULER_TaskCallback error_cb;
147
148 /**
149 * Closure for @e error_cb.
150 */
151 void *error_cb_cls;
152
153 /**
154 * Envelope of the message to send to the service, if not yet
155 * sent.
156 */
157 struct GNUNET_MQ_Envelope *env;
158
159 /**
160 * The operation id this zone iteration operation has
161 */
162 uint32_t r_id;
163
164};
165
166
167/**
168 * Handle for a attribute iterator operation
169 */
170struct GNUNET_IDENTITY_PROVIDER_AttributeIterator
171{
172
173 /**
174 * Kept in a DLL.
175 */
176 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *next;
177
178 /**
179 * Kept in a DLL.
180 */
181 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *prev;
182
183 /**
184 * Main handle to access the idp.
185 */
186 struct GNUNET_IDENTITY_PROVIDER_Handle *h;
187
188 /**
189 * Function to call on completion.
190 */
191 GNUNET_SCHEDULER_TaskCallback finish_cb;
192
193 /**
194 * Closure for @e error_cb.
195 */
196 void *finish_cb_cls;
197
198 /**
199 * The continuation to call with the results
200 */
201 GNUNET_IDENTITY_PROVIDER_AttributeResult proc;
202
203 /**
204 * Closure for @e proc.
205 */
206 void *proc_cls;
207
208 /**
209 * Function to call on errors.
210 */
211 GNUNET_SCHEDULER_TaskCallback error_cb;
212
213 /**
214 * Closure for @e error_cb.
215 */
216 void *error_cb_cls;
217
218 /**
219 * Envelope of the message to send to the service, if not yet
220 * sent.
221 */
222 struct GNUNET_MQ_Envelope *env;
223
224 /**
225 * Private key of the zone.
226 */
227 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
228
229 /**
230 * The operation id this zone iteration operation has
231 */
232 uint32_t r_id;
233
234};
235
94 236
95/** 237/**
96 * Handle for the service. 238 * Handle for the service.
@@ -123,6 +265,27 @@ struct GNUNET_IDENTITY_PROVIDER_Handle
123 struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail; 265 struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail;
124 266
125 /** 267 /**
268 * Head of active iterations
269 */
270 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_head;
271
272 /**
273 * Tail of active iterations
274 */
275 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_tail;
276
277 /**
278 * Head of active iterations
279 */
280 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_head;
281
282 /**
283 * Tail of active iterations
284 */
285 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_tail;
286
287
288 /**
126 * Currently pending transmission request, or NULL for none. 289 * Currently pending transmission request, or NULL for none.
127 */ 290 */
128 struct GNUNET_CLIENT_TransmitHandle *th; 291 struct GNUNET_CLIENT_TransmitHandle *th;
@@ -154,14 +317,13 @@ struct GNUNET_IDENTITY_PROVIDER_Handle
154 317
155}; 318};
156 319
157
158/** 320/**
159 * Try again to connect to the service. 321 * Try again to connect to the service.
160 * 322 *
161 * @param cls handle to the service. 323 * @param h handle to the identity provider service.
162 */ 324 */
163static void 325static void
164reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle); 326reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h);
165 327
166/** 328/**
167 * Reconnect 329 * Reconnect
@@ -181,7 +343,7 @@ reconnect_task (void *cls)
181/** 343/**
182 * Disconnect from service and then reconnect. 344 * Disconnect from service and then reconnect.
183 * 345 *
184 * @param handle our handle 346 * @param handle our service
185 */ 347 */
186static void 348static void
187force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle) 349force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle)
@@ -197,6 +359,26 @@ force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle)
197} 359}
198 360
199/** 361/**
362 * Free @a it.
363 *
364 * @param it entry to free
365 */
366static void
367free_it (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
368{
369 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
370
371 GNUNET_CONTAINER_DLL_remove (h->it_head,
372 h->it_tail,
373 it);
374 if (NULL != it->env)
375 GNUNET_MQ_discard (it->env);
376 GNUNET_free (it);
377}
378
379
380
381/**
200 * Generic error handler, called with the appropriate error code and 382 * Generic error handler, called with the appropriate error code and
201 * the same closure specified at the creation of the message queue. 383 * the same closure specified at the creation of the message queue.
202 * Not every message queue implementation supports an error handler. 384 * Not every message queue implementation supports an error handler.
@@ -213,22 +395,68 @@ mq_error_handler (void *cls,
213} 395}
214 396
215/** 397/**
216 * Check validity of message received from the service 398 * Handle an incoming message of type
399 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
400 *
401 * @param cls
402 * @param msg the message we received
403 */
404static void
405handle_attribute_store_response (void *cls,
406 const struct AttributeStoreResultMessage *msg)
407{
408 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
409 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
410 uint32_t r_id = ntohl (msg->id);
411 int res;
412 const char *emsg;
413
414 for (op = h->op_head; NULL != op; op = op->next)
415 if (op->r_id == r_id)
416 break;
417 if (NULL == op)
418 return;
419
420 res = ntohl (msg->op_result);
421 LOG (GNUNET_ERROR_TYPE_DEBUG,
422 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n",
423 res);
424
425 /* TODO: add actual error message to response... */
426 if (GNUNET_SYSERR == res)
427 emsg = _("failed to store record\n");
428 else
429 emsg = NULL;
430 if (NULL != op->as_cb)
431 op->as_cb (op->cls,
432 res,
433 emsg);
434 GNUNET_CONTAINER_DLL_remove (h->op_head,
435 h->op_tail,
436 op);
437 GNUNET_free (op);
438
439}
440
441
442/**
443 * Handle an incoming message of type
444 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
217 * 445 *
218 * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` 446 * @param cls
219 * @param result_msg the incoming message 447 * @param msg the message we received
448 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
220 */ 449 */
221static int 450static int
222check_exchange_result (void *cls, 451check_consume_ticket_result (void *cls,
223 const struct ExchangeResultMessage *erm) 452 const struct ConsumeTicketResultMessage *msg)
224{ 453{
225 char *str; 454 size_t msg_len;
226 size_t size = ntohs (erm->header.size) - sizeof (*erm); 455 size_t attrs_len;
227
228 456
229 str = (char *) &erm[1]; 457 msg_len = ntohs (msg->header.size);
230 if ( (size > sizeof (struct ExchangeResultMessage)) && 458 attrs_len = ntohs (msg->attrs_len);
231 ('\0' != str[size - sizeof (struct ExchangeResultMessage) - 1]) ) 459 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len)
232 { 460 {
233 GNUNET_break (0); 461 GNUNET_break (0);
234 return GNUNET_SYSERR; 462 return GNUNET_SYSERR;
@@ -238,20 +466,85 @@ check_exchange_result (void *cls,
238 466
239 467
240/** 468/**
241 * Check validity of message received from the service 469 * Handle an incoming message of type
470 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT
471 *
472 * @param cls
473 * @param msg the message we received
474 */
475static void
476handle_consume_ticket_result (void *cls,
477 const struct ConsumeTicketResultMessage *msg)
478{
479 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
480 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
481 size_t attrs_len;
482 uint32_t r_id = ntohl (msg->id);
483
484 attrs_len = ntohs (msg->attrs_len);
485 LOG (GNUNET_ERROR_TYPE_DEBUG,
486 "Processing attribute result.\n");
487
488
489 for (op = h->op_head; NULL != op; op = op->next)
490 if (op->r_id == r_id)
491 break;
492 if (NULL == op)
493 return;
494
495 {
496 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
497 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
498 attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&msg[1],
499 attrs_len);
500 if (NULL != op->ar_cb)
501 {
502 if (NULL == attrs)
503 {
504 op->ar_cb (op->cls,
505 &msg->identity,
506 NULL);
507 }
508 else
509 {
510 for (le = attrs->list_head; NULL != le; le = le->next)
511 op->ar_cb (op->cls,
512 &msg->identity,
513 le->claim);
514 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (attrs);
515 }
516 }
517 op->ar_cb (op->cls,
518 NULL,
519 NULL);
520 GNUNET_CONTAINER_DLL_remove (h->op_head,
521 h->op_tail,
522 op);
523 GNUNET_free (op);
524 return;
525 }
526 GNUNET_assert (0);
527}
528
529
530/**
531 * Handle an incoming message of type
532 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
242 * 533 *
243 * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` 534 * @param cls
244 * @param result_msg the incoming message 535 * @param msg the message we received
536 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
245 */ 537 */
246static int 538static int
247check_result (void *cls, 539check_attribute_result (void *cls,
248 const struct IssueResultMessage *irm) 540 const struct AttributeResultMessage *msg)
249{ 541{
250 char *str; 542 size_t msg_len;
251 size_t size = ntohs (irm->header.size) - sizeof (*irm); 543 size_t attr_len;
252 str = (char*) &irm[1]; 544
253 if ( (size > sizeof (struct IssueResultMessage)) && 545 msg_len = ntohs (msg->header.size);
254 ('\0' != str[size - sizeof (struct IssueResultMessage) - 1]) ) 546 attr_len = ntohs (msg->attr_len);
547 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
255 { 548 {
256 GNUNET_break (0); 549 GNUNET_break (0);
257 return GNUNET_SYSERR; 550 return GNUNET_SYSERR;
@@ -259,119 +552,254 @@ check_result (void *cls,
259 return GNUNET_OK; 552 return GNUNET_OK;
260} 553}
261 554
555
262/** 556/**
263 * Handler for messages received from the GNS service 557 * Handle an incoming message of type
558 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
264 * 559 *
265 * @param cls the `struct GNUNET_GNS_Handle *` 560 * @param cls
266 * @param loookup_msg the incoming message 561 * @param msg the message we received
267 */ 562 */
268static void 563static void
269handle_exchange_result (void *cls, 564handle_attribute_result (void *cls,
270 const struct ExchangeResultMessage *erm) 565 const struct AttributeResultMessage *msg)
271{ 566{
272 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; 567 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
568 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
569 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
273 struct GNUNET_IDENTITY_PROVIDER_Operation *op; 570 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
274 struct GNUNET_IDENTITY_PROVIDER_Token token; 571 size_t attr_len;
275 uint64_t ticket_nonce; 572 uint32_t r_id = ntohl (msg->id);
276 uint32_t r_id = ntohl (erm->id); 573
277 char *str; 574 attr_len = ntohs (msg->attr_len);
278 575 LOG (GNUNET_ERROR_TYPE_DEBUG,
279 for (op = handle->op_head; NULL != op; op = op->next) 576 "Processing attribute result.\n");
577
578
579 for (it = h->it_head; NULL != it; it = it->next)
580 if (it->r_id == r_id)
581 break;
582 for (op = h->op_head; NULL != op; op = op->next)
280 if (op->r_id == r_id) 583 if (op->r_id == r_id)
281 break; 584 break;
282 if (NULL == op) 585 if ((NULL == it) && (NULL == op))
283 return; 586 return;
284 str = GNUNET_strdup ((char*)&erm[1]);
285 op = handle->op_head;
286 GNUNET_CONTAINER_DLL_remove (handle->op_head,
287 handle->op_tail,
288 op);
289 token.data = str;
290 ticket_nonce = ntohl (erm->ticket_nonce);
291 if (NULL != op->ex_cb)
292 op->ex_cb (op->cls, &token, ticket_nonce);
293 GNUNET_free (str);
294 GNUNET_free (op);
295 587
588 if ( (0 == (memcmp (&msg->identity,
589 &identity_dummy,
590 sizeof (identity_dummy)))) )
591 {
592 if ((NULL == it) && (NULL == op))
593 {
594 GNUNET_break (0);
595 force_reconnect (h);
596 return;
597 }
598 if (NULL != it)
599 {
600 if (NULL != it->finish_cb)
601 it->finish_cb (it->finish_cb_cls);
602 free_it (it);
603 }
604 if (NULL != op)
605 {
606 if (NULL != op->ar_cb)
607 op->ar_cb (op->cls,
608 NULL,
609 NULL);
610 GNUNET_CONTAINER_DLL_remove (h->op_head,
611 h->op_tail,
612 op);
613 GNUNET_free (op);
614
615 }
616 return;
617 }
618
619 {
620 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
621 attr = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&msg[1],
622 attr_len);
623 if (NULL != it)
624 {
625 if (NULL != it->proc)
626 it->proc (it->proc_cls,
627 &msg->identity,
628 attr);
629 } else if (NULL != op)
630 {
631 if (NULL != op->ar_cb)
632 op->ar_cb (op->cls,
633 &msg->identity,
634 attr);
635
636 }
637 GNUNET_free (attr);
638 return;
639 }
640 GNUNET_assert (0);
641}
642
643/**
644 * Handle an incoming message of type
645 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
646 *
647 * @param cls
648 * @param msg the message we received
649 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
650 */
651static int
652check_ticket_result (void *cls,
653 const struct TicketResultMessage *msg)
654{
655 size_t msg_len;
656
657 msg_len = ntohs (msg->header.size);
658 if (msg_len < sizeof (struct TicketResultMessage))
659 {
660 GNUNET_break (0);
661 return GNUNET_SYSERR;
662 }
663 return GNUNET_OK;
296} 664}
297 665
666
667
298/** 668/**
299 * Handler for messages received from the GNS service 669 * Handle an incoming message of type
670 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
300 * 671 *
301 * @param cls the `struct GNUNET_GNS_Handle *` 672 * @param cls
302 * @param loookup_msg the incoming message 673 * @param msg the message we received
303 */ 674 */
304static void 675static void
305handle_result (void *cls, 676handle_ticket_result (void *cls,
306 const struct IssueResultMessage *irm) 677 const struct TicketResultMessage *msg)
307{ 678{
308 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; 679 struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
309 struct GNUNET_IDENTITY_PROVIDER_Operation *op; 680 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
310 struct GNUNET_IDENTITY_PROVIDER_Token token; 681 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
311 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; 682 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
312 uint32_t r_id = ntohl (irm->id); 683 uint32_t r_id = ntohl (msg->id);
313 char *str; 684 size_t msg_len;
314 char *label_str;
315 char *ticket_str;
316 char *token_str;
317 685
318 for (op = handle->op_head; NULL != op; op = op->next) 686 for (op = handle->op_head; NULL != op; op = op->next)
319 if (op->r_id == r_id) 687 if (op->r_id == r_id)
320 break; 688 break;
321 if (NULL == op) 689 for (it = handle->ticket_it_head; NULL != it; it = it->next)
690 if (it->r_id == r_id)
691 break;
692 if ((NULL == op) && (NULL == it))
322 return; 693 return;
323 str = GNUNET_strdup ((char*)&irm[1]); 694 msg_len = ntohs (msg->header.size);
324 label_str = strtok (str, ","); 695 if (NULL != op)
325
326 if (NULL == label_str)
327 { 696 {
328 GNUNET_free (str); 697 GNUNET_CONTAINER_DLL_remove (handle->op_head,
329 GNUNET_break (0); 698 handle->op_tail,
699 op);
700 if (msg_len == sizeof (struct TicketResultMessage))
701 {
702 if (NULL != op->tr_cb)
703 op->tr_cb (op->cls, NULL);
704 } else {
705 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
706 if (NULL != op->tr_cb)
707 op->tr_cb (op->cls, ticket);
708 }
709 GNUNET_free (op);
330 return; 710 return;
331 } 711 } else if (NULL != it) {
332 ticket_str = strtok (NULL, ","); 712 if (msg_len == sizeof (struct TicketResultMessage))
333 if (NULL == ticket_str) 713 {
334 { 714 if (NULL != it->tr_cb)
335 GNUNET_free (str); 715 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
336 GNUNET_break (0); 716 handle->ticket_it_tail,
717 it);
718 it->finish_cb (it->finish_cb_cls);
719 GNUNET_free (it);
720 } else {
721 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1];
722 if (NULL != it->tr_cb)
723 it->tr_cb (it->cls, ticket);
724 }
337 return; 725 return;
338 } 726 }
339 token_str = strtok (NULL, ","); 727 GNUNET_break (0);
340 if (NULL == token_str) 728}
729
730/**
731 * Handle an incoming message of type
732 * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT
733 *
734 * @param cls
735 * @param msg the message we received
736 */
737static void
738handle_revoke_ticket_result (void *cls,
739 const struct RevokeTicketResultMessage *msg)
740{
741 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
742 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
743 uint32_t r_id = ntohl (msg->id);
744 int32_t success;
745
746 LOG (GNUNET_ERROR_TYPE_DEBUG,
747 "Processing revocation result.\n");
748
749
750 for (op = h->op_head; NULL != op; op = op->next)
751 if (op->r_id == r_id)
752 break;
753 if (NULL == op)
754 return;
755 success = ntohl (msg->success);
341 { 756 {
342 GNUNET_free (str); 757 if (NULL != op->rvk_cb)
343 GNUNET_break (0); 758 {
759 op->rvk_cb (op->cls,
760 success,
761 NULL);
762 }
763 GNUNET_CONTAINER_DLL_remove (h->op_head,
764 h->op_tail,
765 op);
766 GNUNET_free (op);
344 return; 767 return;
345 } 768 }
346 GNUNET_CONTAINER_DLL_remove (handle->op_head, 769 GNUNET_assert (0);
347 handle->op_tail,
348 op);
349 ticket.data = ticket_str;
350 token.data = token_str;
351 if (NULL != op->iss_cb)
352 op->iss_cb (op->cls, label_str, &ticket, &token);
353 GNUNET_free (str);
354 GNUNET_free (op);
355
356} 770}
357 771
772
773
358/** 774/**
359 * Try again to connect to the service. 775 * Try again to connect to the service.
360 * 776 *
361 * @param cls handle to the identity provider service. 777 * @param h handle to the identity provider service.
362 */ 778 */
363static void 779static void
364reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) 780reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
365{ 781{
366 struct GNUNET_MQ_MessageHandler handlers[] = { 782 struct GNUNET_MQ_MessageHandler handlers[] = {
367 GNUNET_MQ_hd_var_size (result, 783 GNUNET_MQ_hd_fixed_size (attribute_store_response,
368 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT, 784 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE,
369 struct IssueResultMessage, 785 struct AttributeStoreResultMessage,
786 h),
787 GNUNET_MQ_hd_var_size (attribute_result,
788 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT,
789 struct AttributeResultMessage,
370 h), 790 h),
371 GNUNET_MQ_hd_var_size (exchange_result, 791 GNUNET_MQ_hd_var_size (ticket_result,
372 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT, 792 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT,
373 struct ExchangeResultMessage, 793 struct TicketResultMessage,
374 h), 794 h),
795 GNUNET_MQ_hd_var_size (consume_ticket_result,
796 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT,
797 struct ConsumeTicketResultMessage,
798 h),
799 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
800 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT,
801 struct RevokeTicketResultMessage,
802 h),
375 GNUNET_MQ_handler_end () 803 GNUNET_MQ_handler_end ()
376 }; 804 };
377 struct GNUNET_IDENTITY_PROVIDER_Operation *op; 805 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
@@ -417,111 +845,6 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
417 845
418 846
419/** 847/**
420 * Issue an identity token
421 *
422 * @param id identity service to query
423 * @param service_name for which service is an identity wanted
424 * @param cb function to call with the result (will only be called once)
425 * @param cb_cls closure for @a cb
426 * @return handle to abort the operation
427 */
428struct GNUNET_IDENTITY_PROVIDER_Operation *
429GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
430 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key,
431 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
432 const char* scopes,
433 struct GNUNET_TIME_Absolute expiration,
434 uint64_t nonce,
435 GNUNET_IDENTITY_PROVIDER_IssueCallback cb,
436 void *cb_cls)
437{
438 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
439 struct IssueMessage *im;
440 size_t slen;
441
442 slen = strlen (scopes) + 1;
443 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct IssueMessage))
444 {
445 GNUNET_break (0);
446 return NULL;
447 }
448 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
449 op->h = id;
450 op->iss_cb = cb;
451 op->cls = cb_cls;
452 op->r_id = id->r_id_gen++;
453 op->env = GNUNET_MQ_msg_extra (im,
454 slen,
455 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE);
456 im->id = op->r_id;
457 im->iss_key = *iss_key;
458 im->aud_key = *aud_key;
459 im->nonce = htonl (nonce);
460 im->expiration = GNUNET_TIME_absolute_hton (expiration);
461 GNUNET_memcpy (&im[1], scopes, slen);
462 GNUNET_CONTAINER_DLL_insert_tail (id->op_head,
463 id->op_tail,
464 op);
465 if (NULL != id->mq)
466 GNUNET_MQ_send_copy (id->mq,
467 op->env);
468 return op;
469}
470
471
472/**
473 * Exchange a token ticket for a token
474 *
475 * @param id identity provider service
476 * @param ticket ticket to exchange
477 * @param cont function to call once the operation finished
478 * @param cont_cls closure for @a cont
479 * @return handle to abort the operation
480 */
481struct GNUNET_IDENTITY_PROVIDER_Operation *
482GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
483 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
484 const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey,
485 GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont,
486 void *cont_cls)
487{
488 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
489 struct ExchangeMessage *em;
490 size_t slen;
491 char *ticket_str;
492
493 ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket);
494
495 slen = strlen (ticket_str) + 1;
496 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct ExchangeMessage))
497 {
498 GNUNET_free (ticket_str);
499 GNUNET_break (0);
500 return NULL;
501 }
502 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
503 op->h = id;
504 op->ex_cb = cont;
505 op->cls = cont_cls;
506 op->r_id = id->r_id_gen++;
507 op->env = GNUNET_MQ_msg_extra (em,
508 slen,
509 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE);
510 em->aud_privkey = *aud_privkey;
511 em->id = htonl (op->r_id);
512 GNUNET_memcpy (&em[1], ticket_str, slen);
513 GNUNET_free (ticket_str);
514 GNUNET_CONTAINER_DLL_insert_tail (id->op_head,
515 id->op_tail,
516 op);
517 if (NULL != id->mq)
518 GNUNET_MQ_send_copy (id->mq,
519 op->env);
520 return op;
521}
522
523
524/**
525 * Cancel an operation. Note that the operation MAY still 848 * Cancel an operation. Note that the operation MAY still
526 * be executed; this merely cancels the continuation; if the request 849 * be executed; this merely cancels the continuation; if the request
527 * was already transmitted, the service may still choose to complete 850 * was already transmitted, the service may still choose to complete
@@ -566,80 +889,482 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
566} 889}
567 890
568/** 891/**
569 * Convenience API 892 * Store an attribute. If the attribute is already present,
893 * it is replaced with the new attribute.
894 *
895 * @param h handle to the identity provider
896 * @param pkey private key of the identity
897 * @param attr the attribute value
898 * @param cont continuation to call when done
899 * @param cont_cls closure for @a cont
900 * @return handle to abort the request
570 */ 901 */
902struct GNUNET_IDENTITY_PROVIDER_Operation *
903GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
904 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
905 const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
906 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
907 void *cont_cls)
908{
909 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
910 struct AttributeStoreMessage *sam;
911 size_t attr_len;
912
913 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
914 op->h = h;
915 op->as_cb = cont;
916 op->cls = cont_cls;
917 op->r_id = h->r_id_gen++;
918 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
919 h->op_tail,
920 op);
921 attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (attr);
922 op->env = GNUNET_MQ_msg_extra (sam,
923 attr_len,
924 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
925 sam->identity = *pkey;
926 sam->id = htonl (op->r_id);
927
928 GNUNET_IDENTITY_ATTRIBUTE_serialize (attr,
929 (char*)&sam[1]);
930
931 sam->attr_len = htons (attr_len);
932 if (NULL != h->mq)
933 GNUNET_MQ_send_copy (h->mq,
934 op->env);
935 return op;
936
937}
938
939
940/**
941 * List all attributes for a local identity.
942 * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle`
943 * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and
944 * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once
945 * immediately, and then again after
946 * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked.
947 *
948 * On error (disconnect), @a error_cb will be invoked.
949 * On normal completion, @a finish_cb proc will be
950 * invoked.
951 *
952 * @param h handle to the idp
953 * @param identity identity to access
954 * @param error_cb function to call on error (i.e. disconnect),
955 * the handle is afterwards invalid
956 * @param error_cb_cls closure for @a error_cb
957 * @param proc function to call on each attribute; it
958 * will be called repeatedly with a value (if available)
959 * @param proc_cls closure for @a proc
960 * @param finish_cb function to call on completion
961 * the handle is afterwards invalid
962 * @param finish_cb_cls closure for @a finish_cb
963 * @return an iterator handle to use for iteration
964 */
965struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
966GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
967 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
968 GNUNET_SCHEDULER_TaskCallback error_cb,
969 void *error_cb_cls,
970 GNUNET_IDENTITY_PROVIDER_AttributeResult proc,
971 void *proc_cls,
972 GNUNET_SCHEDULER_TaskCallback finish_cb,
973 void *finish_cb_cls)
974{
975 struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
976 struct GNUNET_MQ_Envelope *env;
977 struct AttributeIterationStartMessage *msg;
978 uint32_t rid;
979
980 rid = h->r_id_gen++;
981 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator);
982 it->h = h;
983 it->error_cb = error_cb;
984 it->error_cb_cls = error_cb_cls;
985 it->finish_cb = finish_cb;
986 it->finish_cb_cls = finish_cb_cls;
987 it->proc = proc;
988 it->proc_cls = proc_cls;
989 it->r_id = rid;
990 it->identity = *identity;
991 GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
992 h->it_tail,
993 it);
994 env = GNUNET_MQ_msg (msg,
995 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START);
996 msg->id = htonl (rid);
997 msg->identity = *identity;
998 if (NULL == h->mq)
999 it->env = env;
1000 else
1001 GNUNET_MQ_send (h->mq,
1002 env);
1003 return it;
1004}
571 1005
572 1006
573/** 1007/**
574 * Destroy token 1008 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start
1009 * for the next record.
575 * 1010 *
576 * @param token the token 1011 * @param it the iterator
577 */ 1012 */
578void 1013void
579GNUNET_IDENTITY_PROVIDER_token_destroy(struct GNUNET_IDENTITY_PROVIDER_Token *token) 1014GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1015{
1016 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1017 struct AttributeIterationNextMessage *msg;
1018 struct GNUNET_MQ_Envelope *env;
1019
1020 env = GNUNET_MQ_msg (msg,
1021 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT);
1022 msg->id = htonl (it->r_id);
1023 GNUNET_MQ_send (h->mq,
1024 env);
1025}
1026
1027
1028/**
1029 * Stops iteration and releases the idp handle for further calls. Must
1030 * be called on any iteration that has not yet completed prior to calling
1031 * #GNUNET_IDENTITY_PROVIDER_disconnect.
1032 *
1033 * @param it the iterator
1034 */
1035void
1036GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
1037{
1038 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
1039 struct GNUNET_MQ_Envelope *env;
1040 struct AttributeIterationStopMessage *msg;
1041
1042 if (NULL != h->mq)
1043 {
1044 env = GNUNET_MQ_msg (msg,
1045 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP);
1046 msg->id = htonl (it->r_id);
1047 GNUNET_MQ_send (h->mq,
1048 env);
1049 }
1050 free_it (it);
1051}
1052
1053
1054/** TODO
1055 * Issues a ticket to another identity. The identity may use
1056 * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket
1057 * and retrieve the attributes specified in the AttributeList.
1058 *
1059 * @param h the identity provider to use
1060 * @param iss the issuing identity
1061 * @param rp the subject of the ticket (the relying party)
1062 * @param attrs the attributes that the relying party is given access to
1063 * @param cb the callback
1064 * @param cb_cls the callback closure
1065 * @return handle to abort the operation
1066 */
1067struct GNUNET_IDENTITY_PROVIDER_Operation *
1068GNUNET_IDENTITY_PROVIDER_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1069 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1070 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1071 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
1072 GNUNET_IDENTITY_PROVIDER_TicketCallback cb,
1073 void *cb_cls)
1074{
1075 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1076 struct IssueTicketMessage *tim;
1077 size_t attr_len;
1078
1079 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1080 op->h = h;
1081 op->tr_cb = cb;
1082 op->cls = cb_cls;
1083 op->r_id = h->r_id_gen++;
1084 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1085 h->op_tail,
1086 op);
1087 attr_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (attrs);
1088 op->env = GNUNET_MQ_msg_extra (tim,
1089 attr_len,
1090 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET);
1091 tim->identity = *iss;
1092 tim->rp = *rp;
1093 tim->id = htonl (op->r_id);
1094
1095 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (attrs,
1096 (char*)&tim[1]);
1097
1098 tim->attr_len = htons (attr_len);
1099 if (NULL != h->mq)
1100 GNUNET_MQ_send_copy (h->mq,
1101 op->env);
1102 return op;
1103}
1104
1105/**
1106 * Consumes an issued ticket. The ticket is persisted
1107 * and used to retrieve identity information from the issuer
1108 *
1109 * @param h the identity provider to use
1110 * @param identity the identity that is the subject of the issued ticket (the relying party)
1111 * @param ticket the issued ticket to consume
1112 * @param cb the callback to call
1113 * @param cb_cls the callback closure
1114 * @return handle to abort the operation
1115 */
1116struct GNUNET_IDENTITY_PROVIDER_Operation *
1117GNUNET_IDENTITY_PROVIDER_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1118 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1119 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1120 GNUNET_IDENTITY_PROVIDER_AttributeResult cb,
1121 void *cb_cls)
580{ 1122{
581 GNUNET_assert (NULL != token); 1123 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
582 if (NULL != token->data) 1124 struct ConsumeTicketMessage *ctm;
583 GNUNET_free (token->data); 1125
584 GNUNET_free (token); 1126 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1127 op->h = h;
1128 op->ar_cb = cb;
1129 op->cls = cb_cls;
1130 op->r_id = h->r_id_gen++;
1131 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1132 h->op_tail,
1133 op);
1134 op->env = GNUNET_MQ_msg_extra (ctm,
1135 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket),
1136 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET);
1137 ctm->identity = *identity;
1138 ctm->id = htonl (op->r_id);
1139
1140 GNUNET_memcpy ((char*)&ctm[1],
1141 ticket,
1142 sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket));
1143
1144 if (NULL != h->mq)
1145 GNUNET_MQ_send_copy (h->mq,
1146 op->env);
1147 return op;
1148
585} 1149}
586 1150
1151
587/** 1152/**
588 * Returns string representation of token. A JSON-Web-Token. 1153 * Lists all tickets that have been issued to remote
1154 * identites (relying parties)
589 * 1155 *
590 * @param token the token 1156 * @param h the identity provider to use
591 * @return The JWT (must be freed) 1157 * @param identity the issuing identity
1158 * @param error_cb function to call on error (i.e. disconnect),
1159 * the handle is afterwards invalid
1160 * @param error_cb_cls closure for @a error_cb
1161 * @param proc function to call on each ticket; it
1162 * will be called repeatedly with a value (if available)
1163 * @param proc_cls closure for @a proc
1164 * @param finish_cb function to call on completion
1165 * the handle is afterwards invalid
1166 * @param finish_cb_cls closure for @a finish_cb
1167 * @return an iterator handle to use for iteration
592 */ 1168 */
593char * 1169struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
594GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_Token *token) 1170GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1171 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1172 GNUNET_SCHEDULER_TaskCallback error_cb,
1173 void *error_cb_cls,
1174 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1175 void *proc_cls,
1176 GNUNET_SCHEDULER_TaskCallback finish_cb,
1177 void *finish_cb_cls)
595{ 1178{
596 return GNUNET_strdup (token->data); 1179 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1180 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
1181 struct GNUNET_MQ_Envelope *env;
1182 struct TicketIterationStartMessage *msg;
1183 uint32_t rid;
1184
1185 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
1186 &identity_pub);
1187 rid = h->r_id_gen++;
1188 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1189 it->h = h;
1190 it->error_cb = error_cb;
1191 it->error_cb_cls = error_cb_cls;
1192 it->finish_cb = finish_cb;
1193 it->finish_cb_cls = finish_cb_cls;
1194 it->tr_cb = proc;
1195 it->cls = proc_cls;
1196 it->r_id = rid;
1197 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1198 h->ticket_it_tail,
1199 it);
1200 env = GNUNET_MQ_msg (msg,
1201 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1202 msg->id = htonl (rid);
1203 msg->identity = identity_pub;
1204 msg->is_audience = htonl (GNUNET_NO);
1205 if (NULL == h->mq)
1206 it->env = env;
1207 else
1208 GNUNET_MQ_send (h->mq,
1209 env);
1210 return it;
1211
597} 1212}
598 1213
1214
599/** 1215/**
600 * Returns string representation of ticket. Base64-Encoded 1216 * Lists all tickets that have been issued to remote
1217 * identites (relying parties)
601 * 1218 *
602 * @param ticket the ticket 1219 * @param h the identity provider to use
603 * @return the Base64-Encoded ticket 1220 * @param identity the issuing identity
1221 * @param error_cb function to call on error (i.e. disconnect),
1222 * the handle is afterwards invalid
1223 * @param error_cb_cls closure for @a error_cb
1224 * @param proc function to call on each ticket; it
1225 * will be called repeatedly with a value (if available)
1226 * @param proc_cls closure for @a proc
1227 * @param finish_cb function to call on completion
1228 * the handle is afterwards invalid
1229 * @param finish_cb_cls closure for @a finish_cb
1230 * @return an iterator handle to use for iteration
604 */ 1231 */
605char * 1232struct GNUNET_IDENTITY_PROVIDER_TicketIterator *
606GNUNET_IDENTITY_PROVIDER_ticket_to_string (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) 1233GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1234 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1235 GNUNET_SCHEDULER_TaskCallback error_cb,
1236 void *error_cb_cls,
1237 GNUNET_IDENTITY_PROVIDER_TicketCallback proc,
1238 void *proc_cls,
1239 GNUNET_SCHEDULER_TaskCallback finish_cb,
1240 void *finish_cb_cls)
607{ 1241{
608 return GNUNET_strdup (ticket->data); 1242 struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it;
1243 struct GNUNET_MQ_Envelope *env;
1244 struct TicketIterationStartMessage *msg;
1245 uint32_t rid;
1246
1247 rid = h->r_id_gen++;
1248 it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator);
1249 it->h = h;
1250 it->error_cb = error_cb;
1251 it->error_cb_cls = error_cb_cls;
1252 it->finish_cb = finish_cb;
1253 it->finish_cb_cls = finish_cb_cls;
1254 it->tr_cb = proc;
1255 it->cls = proc_cls;
1256 it->r_id = rid;
1257 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1258 h->ticket_it_tail,
1259 it);
1260 env = GNUNET_MQ_msg (msg,
1261 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START);
1262 msg->id = htonl (rid);
1263 msg->identity = *identity;
1264 msg->is_audience = htonl (GNUNET_YES);
1265 if (NULL == h->mq)
1266 it->env = env;
1267 else
1268 GNUNET_MQ_send (h->mq,
1269 env);
1270 return it;
1271
1272
609} 1273}
610 1274
611/** 1275/**
612 * Created a ticket from a string (Base64 encoded ticket) 1276 * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start
1277 * for the next record.
613 * 1278 *
614 * @param input Base64 encoded ticket 1279 * @param it the iterator
615 * @param ticket pointer where the ticket is stored
616 * @return GNUNET_OK
617 */ 1280 */
618int 1281void
619GNUNET_IDENTITY_PROVIDER_string_to_ticket (const char* input, 1282GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
620 struct GNUNET_IDENTITY_PROVIDER_Ticket **ticket)
621{ 1283{
622 *ticket = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); 1284 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
623 (*ticket)->data = GNUNET_strdup (input); 1285 struct TicketIterationNextMessage *msg;
624 return GNUNET_OK; 1286 struct GNUNET_MQ_Envelope *env;
1287
1288 env = GNUNET_MQ_msg (msg,
1289 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT);
1290 msg->id = htonl (it->r_id);
1291 GNUNET_MQ_send (h->mq,
1292 env);
625} 1293}
626 1294
627 1295
628/** 1296/**
629 * Destroys a ticket 1297 * Stops iteration and releases the idp handle for further calls. Must
1298 * be called on any iteration that has not yet completed prior to calling
1299 * #GNUNET_IDENTITY_PROVIDER_disconnect.
630 * 1300 *
631 * @param ticket the ticket to destroy 1301 * @param it the iterator
632 */ 1302 */
633void 1303void
634GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) 1304GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it)
635{ 1305{
636 GNUNET_assert (NULL != ticket); 1306 struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
637 if (NULL != ticket->data) 1307 struct GNUNET_MQ_Envelope *env;
638 GNUNET_free (ticket->data); 1308 struct TicketIterationStopMessage *msg;
639 GNUNET_free (ticket); 1309
1310 if (NULL != h->mq)
1311 {
1312 env = GNUNET_MQ_msg (msg,
1313 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP);
1314 msg->id = htonl (it->r_id);
1315 GNUNET_MQ_send (h->mq,
1316 env);
1317 }
1318 GNUNET_free (it);
640} 1319}
641 1320
1321/**
1322 * Revoked an issued ticket. The relying party will be unable to retrieve
1323 * updated attributes.
1324 *
1325 * @param h the identity provider to use
1326 * @param identity the issuing identity
1327 * @param ticket the ticket to revoke
1328 * @param cb the callback
1329 * @param cb_cls the callback closure
1330 * @return handle to abort the operation
1331 */
1332struct GNUNET_IDENTITY_PROVIDER_Operation *
1333GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
1334 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1335 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1336 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb,
1337 void *cb_cls)
1338{
1339 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
1340 struct GNUNET_MQ_Envelope *env;
1341 struct RevokeTicketMessage *msg;
1342 uint32_t rid;
642 1343
1344 rid = h->r_id_gen++;
1345 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
1346 op->h = h;
1347 op->rvk_cb = cb;
1348 op->cls = cb_cls;
1349 op->r_id = rid;
1350 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1351 h->op_tail,
1352 op);
1353 env = GNUNET_MQ_msg_extra (msg,
1354 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
1355 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET);
1356 msg->id = htonl (rid);
1357 msg->identity = *identity;
1358 memcpy (&msg[1],
1359 ticket,
1360 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
1361 if (NULL == h->mq)
1362 op->env = env;
1363 else
1364 GNUNET_MQ_send (h->mq,
1365 env);
1366 return op;
1367}
643 1368
644 1369
645 1370