aboutsummaryrefslogtreecommitdiff
path: root/src/identity-provider/gnunet-service-identity-provider.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2017-07-08 20:02:12 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2017-07-08 20:02:12 +0200
commitd43a25d25ad68fcc1508e8fcf092c5014a6bdba8 (patch)
tree8d8917eb5ed8768d665bc100eb72821522efbf2c /src/identity-provider/gnunet-service-identity-provider.c
parent591432f733943cdc24110d4b582f60351afb9c05 (diff)
downloadgnunet-d43a25d25ad68fcc1508e8fcf092c5014a6bdba8.tar.gz
gnunet-d43a25d25ad68fcc1508e8fcf092c5014a6bdba8.zip
-towards IdP2
Diffstat (limited to 'src/identity-provider/gnunet-service-identity-provider.c')
-rw-r--r--src/identity-provider/gnunet-service-identity-provider.c768
1 files changed, 119 insertions, 649 deletions
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c
index f4ea352d4..3a7a6eeb9 100644
--- a/src/identity-provider/gnunet-service-identity-provider.c
+++ b/src/identity-provider/gnunet-service-identity-provider.c
@@ -59,21 +59,6 @@
59#define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS 59#define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
60 60
61/** 61/**
62 * Service state (to detect initial update pass)
63 */
64static int state;
65
66/**
67 * Head of ego entry DLL
68 */
69static struct EgoEntry *ego_head;
70
71/**
72 * Tail of ego entry DLL
73 */
74static struct EgoEntry *ego_tail;
75
76/**
77 * Identity handle 62 * Identity handle
78 */ 63 */
79static struct GNUNET_IDENTITY_Handle *identity_handle; 64static struct GNUNET_IDENTITY_Handle *identity_handle;
@@ -118,11 +103,6 @@ static struct GNUNET_SCHEDULER_Task *timeout_task;
118 */ 103 */
119static struct GNUNET_SCHEDULER_Task *update_task; 104static struct GNUNET_SCHEDULER_Task *update_task;
120 105
121/**
122 * Timeout for next update pass
123 */
124static struct GNUNET_TIME_Relative min_rel_exp;
125
126 106
127/** 107/**
128 * Currently processed token 108 * Currently processed token
@@ -140,16 +120,6 @@ static char* label;
140static char* scopes; 120static char* scopes;
141 121
142/** 122/**
143 * Expiration for processed token
144 */
145static uint64_t rd_exp;
146
147/**
148 * ECDHE Privkey for processed token metadata
149 */
150static struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_privkey;
151
152/**
153 * Handle to the statistics service. 123 * Handle to the statistics service.
154 */ 124 */
155static struct GNUNET_STATISTICS_Handle *stats; 125static struct GNUNET_STATISTICS_Handle *stats;
@@ -240,6 +210,11 @@ struct IssueHandle
240 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; 210 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
241 211
242 /** 212 /**
213 * The issuer egos ABE master key
214 */
215 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
216
217 /**
243 * Expiration 218 * Expiration
244 */ 219 */
245 struct GNUNET_TIME_Absolute expiration; 220 struct GNUNET_TIME_Absolute expiration;
@@ -331,574 +306,14 @@ struct EgoEntry
331 */ 306 */
332 struct GNUNET_CONTAINER_MultiHashMap *attr_map; 307 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
333 308
334 /**
335 * Attributes are old and should be updated if GNUNET_YES
336 */
337 int attributes_dirty;
338}; 309};
339 310
340/** 311/**
341 * Continuation for token store call
342 *
343 * @param cls NULL
344 * @param success error code
345 * @param emsg error message
346 */
347static void
348store_token_cont (void *cls,
349 int32_t success,
350 const char *emsg)
351{
352 ns_qe = NULL;
353 if (GNUNET_SYSERR == success)
354 {
355 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
356 "Failed to update token: %s\n",
357 emsg);
358 return;
359 }
360 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
361}
362
363
364/**
365 * This function updates the old token with new attributes,
366 * removes deleted attributes and expiration times.
367 *
368 * @param cls the ego entry
369 */
370static void
371handle_token_update (void *cls)
372{
373 char *token_metadata;
374 char *write_ptr;
375 char *enc_token_str;
376 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
377 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
378 struct GNUNET_CRYPTO_EcdhePrivateKey *new_ecdhe_privkey;
379 struct EgoEntry *ego_entry = cls;
380 struct GNUNET_GNSRECORD_Data token_record[2];
381 struct GNUNET_HashCode key_hash;
382 struct GNUNET_TIME_Relative token_rel_exp;
383 struct GNUNET_TIME_Relative token_ttl;
384 struct GNUNET_TIME_Absolute token_exp;
385 struct GNUNET_TIME_Absolute token_nbf;
386 struct GNUNET_TIME_Absolute new_exp;
387 struct GNUNET_TIME_Absolute new_iat;
388 struct GNUNET_TIME_Absolute new_nbf;
389 struct IdentityToken *new_token;
390 struct TokenAttr *cur_value;
391 struct TokenAttr *attr;
392 size_t token_metadata_len;
393
394 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
395 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
396 &pub_key);
397
398 //Note: We need the token expiration time here. Not the record expiration
399 //time.
400 //There are two types of tokens: Token that expire on GNS level with
401 //an absolute expiration time. Those are basically tokens that will
402 //be automatically revoked on (record)expiration.
403 //Tokens stored with relative expiration times will expire on the token level (token expiration)
404 //but this service will reissue new tokens that can be retrieved from GNS
405 //automatically.
406
407 for (attr = token->attr_head; NULL != attr; attr = attr->next)
408 {
409 if (0 == strcmp (attr->name, "exp"))
410 {
411 GNUNET_assert (1 == sscanf (attr->val_head->value,
412 "%"SCNu64,
413 &token_exp.abs_value_us));
414 } else if (0 == strcmp (attr->name, "nbf")) {
415 GNUNET_assert (1 == sscanf (attr->val_head->value,
416 "%"SCNu64,
417 &token_nbf.abs_value_us));
418 }
419 }
420 token_rel_exp = GNUNET_TIME_absolute_get_difference (token_nbf, token_exp);
421
422 token_ttl = GNUNET_TIME_absolute_get_remaining (token_exp);
423 if (0 != GNUNET_TIME_absolute_get_remaining (token_exp).rel_value_us)
424 {
425 //This token is not yet expired! Save and skip
426 if (min_rel_exp.rel_value_us > token_ttl.rel_value_us)
427 {
428 min_rel_exp = token_ttl;
429 }
430 GNUNET_free (token);
431 token = NULL;
432 GNUNET_free (label);
433 label = NULL;
434 GNUNET_free (scopes);
435 scopes = NULL;
436 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
437 return;
438 }
439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
440 "Token is expired. Create a new one\n");
441 new_token = token_create (&pub_key,
442 &token->aud_key);
443 new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
444 new_nbf = GNUNET_TIME_absolute_get ();
445 new_iat = new_nbf;
446 for (attr = token->attr_head; NULL != attr; attr = attr->next)
447 {
448 if (0 == strcmp (attr->name, "exp"))
449 {
450 token_add_attr_int (new_token, attr->name, new_exp.abs_value_us);
451 }
452 else if (0 == strcmp (attr->name, "nbf"))
453 {
454 token_add_attr_int (new_token, attr->name, new_nbf.abs_value_us);
455 }
456 else if (0 == strcmp (attr->name, "iat"))
457 {
458 token_add_attr_int (new_token, attr->name, new_iat.abs_value_us);
459 }
460 else if ((0 == strcmp (attr->name, "iss"))
461 || (0 == strcmp (attr->name, "aud")))
462 {
463 //Omit
464 }
465 else if (0 == strcmp (attr->name, "sub"))
466 {
467 token_add_attr (new_token,
468 attr->name,
469 attr->val_head->value);
470 }
471 else
472 {
473 GNUNET_CRYPTO_hash (attr->name,
474 strlen (attr->name),
475 &key_hash);
476 //Check if attr still exists. omit of not
477 if (GNUNET_NO !=
478 GNUNET_CONTAINER_multihashmap_contains (ego_entry->attr_map,
479 &key_hash))
480 {
481 cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map,
482 &key_hash);
483 GNUNET_assert (NULL != cur_value);
484 GNUNET_CONTAINER_DLL_insert (new_token->attr_head,
485 new_token->attr_tail,
486 cur_value);
487 }
488 }
489 }
490
491 // reassemble and set
492 GNUNET_assert (token_serialize (new_token,
493 priv_key,
494 &new_ecdhe_privkey,
495 &enc_token_str));
496
497 token_record[0].data = enc_token_str;
498 token_record[0].data_size = strlen (enc_token_str) + 1;
499 token_record[0].expiration_time = rd_exp; //Old expiration time
500 token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
501 token_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
502
503 //Meta
504 token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
505 + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)
506 + strlen (scopes) + 1; //With 0-Terminator
507 token_metadata = GNUNET_malloc (token_metadata_len);
508 write_ptr = token_metadata;
509 GNUNET_memcpy (token_metadata, new_ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
510 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
511 GNUNET_memcpy (write_ptr, &token->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
512 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
513 GNUNET_memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator;
514
515 token_record[1].data = token_metadata;
516 token_record[1].data_size = token_metadata_len;
517 token_record[1].expiration_time = rd_exp;
518 token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
519 token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
520
521 ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
522 priv_key,
523 label,
524 2,
525 token_record,
526 &store_token_cont,
527 ego_entry);
528 token_destroy (new_token);
529 token_destroy (token);
530 GNUNET_free (new_ecdhe_privkey);
531 GNUNET_free (enc_token_str);
532 token = NULL;
533 GNUNET_free (label);
534 label = NULL;
535 GNUNET_free (scopes);
536 scopes = NULL;
537}
538
539
540static void
541update_identities(void *cls);
542
543
544/**
545 *
546 * Cleanup attr_map
547 *
548 * @param cls NULL
549 * @param key the key
550 * @param value the json_t attribute value
551 * @return #GNUNET_YES
552 */
553static int
554clear_ego_attrs (void *cls,
555 const struct GNUNET_HashCode *key,
556 void *value)
557{
558 struct TokenAttr *attr = value;
559 struct TokenAttrValue *val;
560 struct TokenAttrValue *tmp_val;
561 for (val = attr->val_head; NULL != val;)
562 {
563 tmp_val = val->next;
564 GNUNET_CONTAINER_DLL_remove (attr->val_head,
565 attr->val_tail,
566 val);
567 GNUNET_free (val->value);
568 GNUNET_free (val);
569 val = tmp_val;
570 }
571 GNUNET_free (attr->name);
572 GNUNET_free (attr);
573
574 return GNUNET_YES;
575}
576
577
578static void
579token_collect_error_cb (void *cls)
580{
581 struct EgoEntry *ego_entry = cls;
582
583 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
584 ">>> Updating Ego failed!\n");
585 //Clear attribute map for ego
586 GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map,
587 &clear_ego_attrs,
588 ego_entry);
589 GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map);
590 update_task = GNUNET_SCHEDULER_add_now (&update_identities,
591 ego_entry->next);
592
593}
594
595
596static void
597token_collect_finished_cb (void *cls)
598{
599 struct EgoEntry *ego_entry = cls;
600
601 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
602 ">>> Updating Ego finished\n");
603 //Clear attribute map for ego
604 GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map,
605 &clear_ego_attrs,
606 ego_entry);
607 GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map);
608 update_task = GNUNET_SCHEDULER_add_now (&update_identities,
609 ego_entry->next);
610}
611
612
613/**
614 *
615 * Update all ID_TOKEN records for an identity and store them
616 *
617 * @param cls the identity entry
618 * @param zone the identity
619 * @param lbl the name of the record
620 * @param rd_count number of records
621 * @param rd record data
622 */
623static void
624token_collect (void *cls,
625 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
626 const char *lbl,
627 unsigned int rd_count,
628 const struct GNUNET_GNSRECORD_Data *rd)
629{
630 struct EgoEntry *ego_entry = cls;
631 const struct GNUNET_GNSRECORD_Data *token_record;
632 const struct GNUNET_GNSRECORD_Data *token_metadata_record;
633 struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key;
634 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key;
635
636 //There should be only a single record for a token under a label
637 if (2 != rd_count)
638 {
639 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
640 return;
641 }
642
643 if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
644 {
645 token_metadata_record = &rd[0];
646 token_record = &rd[1];
647 }
648 else
649 {
650 token_record = &rd[0];
651 token_metadata_record = &rd[1];
652 }
653 if (token_metadata_record->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
654 {
655 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
656 return;
657 }
658 if (token_record->record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN)
659 {
660 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
661 return;
662 }
663
664 //Get metadata and decrypt token
665 priv_key = (struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data;
666 ecdhe_privkey = *priv_key;
667 aud_key = (struct GNUNET_CRYPTO_EcdsaPublicKey *)&priv_key[1];
668 scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
669
670 token_parse2 (token_record->data,
671 &ecdhe_privkey,
672 aud_key,
673 &token);
674
675 label = GNUNET_strdup (lbl);
676 rd_exp = token_record->expiration_time;
677
678 GNUNET_SCHEDULER_add_now (&handle_token_update,
679 ego_entry);
680}
681
682
683static void
684attribute_collect_error_cb (void *cls)
685{
686 struct EgoEntry *ego_entry = cls;
687
688 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
689 ">>> Updating Attributes failed!\n");
690 ego_entry->attributes_dirty = GNUNET_NO;
691 update_task = GNUNET_SCHEDULER_add_now (&update_identities,
692 ego_entry);
693}
694
695
696static void
697attribute_collect_finished_cb (void *cls)
698{
699 struct EgoEntry *ego_entry = cls;
700
701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
702 ">>> Updating Attributes finished\n");
703 ego_entry->attributes_dirty = GNUNET_NO;
704 update_task = GNUNET_SCHEDULER_add_now (&update_identities,
705 ego_entry);
706}
707
708
709/**
710 *
711 * Collect all ID_ATTR records for an identity and store them
712 *
713 * @param cls the identity entry
714 * @param zone the identity
715 * @param lbl the name of the record
716 * @param rd_count number of records
717 * @param rd record data
718 *
719 */
720static void
721attribute_collect (void *cls,
722 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
723 const char *lbl,
724 unsigned int rd_count,
725 const struct GNUNET_GNSRECORD_Data *rd)
726{
727 struct EgoEntry *ego_entry = cls;
728 struct GNUNET_HashCode key;
729 struct TokenAttr *attr;
730 struct TokenAttrValue *val;
731 char *val_str;
732 int i;
733
734 if (0 == rd_count)
735 {
736 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
737 return;
738 }
739 GNUNET_CRYPTO_hash (lbl,
740 strlen (lbl),
741 &key);
742 if (1 == rd_count)
743 {
744 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
745 {
746 val_str = GNUNET_GNSRECORD_value_to_string (rd->record_type,
747 rd->data,
748 rd->data_size);
749 attr = GNUNET_malloc (sizeof (struct TokenAttr));
750 attr->name = GNUNET_strdup (lbl);
751 val = GNUNET_malloc (sizeof (struct TokenAttrValue));
752 val->value = val_str;
753 GNUNET_CONTAINER_DLL_insert (attr->val_head,
754 attr->val_tail,
755 val);
756 GNUNET_assert (GNUNET_OK ==
757 GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
758 &key,
759 attr,
760 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
761 }
762
763 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
764 return;
765 }
766
767 attr = GNUNET_malloc (sizeof (struct TokenAttr));
768 attr->name = GNUNET_strdup (lbl);
769 for (i = 0; i < rd_count; i++)
770 {
771 if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
772 {
773 val_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
774 rd[i].data,
775 rd[i].data_size);
776 val = GNUNET_malloc (sizeof (struct TokenAttrValue));
777 val->value = val_str;
778 GNUNET_CONTAINER_DLL_insert (attr->val_head,
779 attr->val_tail,
780 val);
781 }
782 }
783 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
784 &key,
785 attr,
786 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
787 GNUNET_NAMESTORE_zone_iterator_next (ns_it);
788}
789
790/**
791 *
792 * Update identity information for ego. If attribute map is
793 * dirty, first update the attributes.
794 *
795 * @param cls the ego to update
796 */
797static void
798update_identities(void *cls)
799{
800 struct EgoEntry *next_ego = cls;
801 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
802
803 update_task = NULL;
804 if (NULL == next_ego)
805 {
806 if (min_rel_exp.rel_value_us < MIN_WAIT_TIME.rel_value_us)
807 min_rel_exp = MIN_WAIT_TIME;
808 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
809 ">>> Finished. Rescheduling in %"SCNu64"\n",
810 min_rel_exp.rel_value_us);
811 ns_it = NULL;
812 //finished -> reschedule
813 update_task = GNUNET_SCHEDULER_add_delayed (min_rel_exp,
814 &update_identities,
815 ego_head);
816 min_rel_exp.rel_value_us = 0;
817 return;
818 }
819 priv_key = GNUNET_IDENTITY_ego_get_private_key (next_ego->ego);
820 if (GNUNET_YES == next_ego->attributes_dirty)
821 {
822 //Starting over. We must update the Attributes for they might have changed.
823 ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
824 priv_key,
825 &attribute_collect_error_cb,
826 next_ego,
827 &attribute_collect,
828 next_ego,
829 &attribute_collect_finished_cb,
830 next_ego);
831
832 }
833 else
834 {
835 //Ego will be dirty next time
836 next_ego->attributes_dirty = GNUNET_YES;
837 ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
838 priv_key,
839 &token_collect_error_cb,
840 next_ego,
841 &token_collect,
842 next_ego,
843 &token_collect_finished_cb,
844 next_ego);
845 }
846}
847
848
849/**
850 * Function called initially to start update task
851 */
852static void
853init_cont ()
854{
855 GNUNET_log (GNUNET_ERROR_TYPE_INFO, ">>> Starting Service\n");
856 //Initially iterate all itenties and refresh all tokens
857 update_task = GNUNET_SCHEDULER_add_now (&update_identities,
858 ego_head);
859}
860
861
862/**
863 * Initial ego collection function.
864 *
865 * @param cls NULL
866 * @param ego ego
867 * @param ctx context
868 * @param identifier ego name
869 */
870static void
871list_ego (void *cls,
872 struct GNUNET_IDENTITY_Ego *ego,
873 void **ctx,
874 const char *identifier)
875{
876 struct EgoEntry *new_entry;
877 if ((NULL == ego) && (STATE_INIT == state))
878 {
879 state = STATE_POST_INIT;
880 init_cont ();
881 return;
882 }
883 if (STATE_INIT == state) {
884 new_entry = GNUNET_malloc (sizeof (struct EgoEntry));
885 new_entry->ego = ego;
886 new_entry->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
887 GNUNET_NO);
888 new_entry->attributes_dirty = GNUNET_YES;
889 GNUNET_CONTAINER_DLL_insert_tail(ego_head, ego_tail, new_entry);
890 }
891}
892
893/**
894 * Cleanup task 312 * Cleanup task
895 */ 313 */
896static void 314static void
897cleanup() 315cleanup()
898{ 316{
899 struct EgoEntry *ego_entry;
900 struct EgoEntry *ego_tmp;
901
902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
903 "Cleaning up\n"); 318 "Cleaning up\n");
904 if (NULL != stats) 319 if (NULL != stats)
@@ -928,21 +343,6 @@ cleanup()
928 if (NULL != label) 343 if (NULL != label)
929 GNUNET_free (label); 344 GNUNET_free (label);
930 345
931 for (ego_entry = ego_head;
932 NULL != ego_entry;)
933 {
934 ego_tmp = ego_entry;
935 if (0 != GNUNET_CONTAINER_multihashmap_size (ego_tmp->attr_map))
936 {
937 GNUNET_CONTAINER_multihashmap_iterate (ego_tmp->attr_map,
938 &clear_ego_attrs,
939 ego_tmp);
940
941 }
942 GNUNET_CONTAINER_multihashmap_destroy (ego_tmp->attr_map);
943 ego_entry = ego_entry->next;
944 GNUNET_free (ego_tmp);
945 }
946} 346}
947 347
948/** 348/**
@@ -1023,7 +423,7 @@ cleanup_issue_handle (struct IssueHandle *handle)
1023} 423}
1024 424
1025static void 425static void
1026store_token_issue_cont (void *cls, 426store_record_issue_cont (void *cls,
1027 int32_t success, 427 int32_t success,
1028 const char *emsg) 428 const char *emsg)
1029{ 429{
@@ -1073,6 +473,82 @@ store_token_issue_cont (void *cls,
1073 GNUNET_free (token_str); 473 GNUNET_free (token_str);
1074} 474}
1075 475
476static int
477create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
478 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
479 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
480{
481 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
482
483 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
484 &new_key_hash_str);
485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
486 static const char ctx_key[] = "gnuid-aes-ctx-key";
487 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
488 new_key_hash, sizeof (struct GNUNET_HashCode),
489 ctx_key, strlen (ctx_key),
490 NULL, 0);
491 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
492 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
493 new_key_hash, sizeof (struct GNUNET_HashCode),
494 ctx_iv, strlen (ctx_iv),
495 NULL, 0);
496 return GNUNET_OK;
497}
498
499int
500serialize_abe_keyinfo (const struct IssueHandle *handle,
501 const struct GNUNET_CRYPTO_AbeKey *rp_key,
502 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
503 char **result)
504{
505 char *enc_keyinfo;
506 char *serialized_key;
507 char *buf;
508 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey;
509 ssize_t size;
510
511 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
512 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
513 struct GNUNET_HashCode new_key_hash;
514 ssize_t enc_size;
515
516 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
517 &serialized_key);
518 buf = GNUNET_malloc (strlen (handle->scopes) + 1 + size);
519 GNUNET_memcpy (buf,
520 handle->scopes,
521 strlen (handle->scopes) + 1);
522 GNUNET_memcpy (buf + strlen (handle->scopes) + 1,
523 serialized_key,
524 size);
525 // ECDH keypair E = eG
526 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
527 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
528 ecdh_pubkey);
529 enc_keyinfo = GNUNET_malloc (size);
530 // Derived key K = H(eB)
531 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
532 &handle->aud_key,
533 &new_key_hash));
534 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
535 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
536 size + strlen (handle->scopes) + 1,
537 &skey, &iv,
538 enc_keyinfo);
539 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
540 enc_size);
541 GNUNET_memcpy (*result,
542 ecdh_pubkey,
543 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
544 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
545 enc_keyinfo,
546 enc_size);
547 GNUNET_free (enc_keyinfo);
548 return GNUNET_OK;
549}
550
551
1076 552
1077/** 553/**
1078 * Build a token and store it 554 * Build a token and store it
@@ -1085,14 +561,18 @@ sign_and_return_token (void *cls)
1085 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; 561 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1086 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; 562 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1087 struct IssueHandle *handle = cls; 563 struct IssueHandle *handle = cls;
1088 struct GNUNET_GNSRECORD_Data token_record[2]; 564 struct GNUNET_GNSRECORD_Data code_record[1];
565 struct GNUNET_CRYPTO_AbeKey *rp_key;
1089 char *nonce_str; 566 char *nonce_str;
1090 char *enc_token_str; 567 char *code_record_data;
1091 char *token_metadata; 568 char **attrs;
1092 char* write_ptr; 569 char *scope;
570 char *scopes_tmp;
571 int attrs_len;
572 int i;
1093 uint64_t time; 573 uint64_t time;
1094 uint64_t exp_time; 574 uint64_t exp_time;
1095 size_t token_metadata_len; 575 size_t code_record_len;
1096 576
1097 //Remote nonce 577 //Remote nonce
1098 nonce_str = NULL; 578 nonce_str = NULL;
@@ -1114,49 +594,39 @@ sign_and_return_token (void *cls)
1114 token_add_attr_int (handle->token, "exp", exp_time); 594 token_add_attr_int (handle->token, "exp", exp_time);
1115 token_add_attr (handle->token, "nonce", nonce_str); 595 token_add_attr (handle->token, "nonce", nonce_str);
1116 596
1117 //Token in a serialized encrypted format 597 //Create new ABE key for RP
1118 GNUNET_assert (token_serialize (handle->token, 598 attrs_len = (GNUNET_CONTAINER_multihashmap_size (handle->attr_map) + 1) * sizeof (char*);
1119 &handle->iss_key, 599 attrs = GNUNET_malloc (attrs_len);
1120 &ecdhe_privkey, 600 i = 0;
1121 &enc_token_str)); 601 scopes_tmp = GNUNET_strdup (handle->scopes);
1122 602 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) {
1123 //Token record E,E_K (Token) 603 attrs[i] = scope;
1124 token_record[0].data = enc_token_str; 604 i++;
1125 token_record[0].data_size = strlen (enc_token_str) + 1; 605 }
1126 token_record[0].expiration_time = exp_time; 606 rp_key = GNUNET_CRYPTO_cpabe_create_key (handle->abe_key,
1127 token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN; 607 attrs);
1128 token_record[0].flags = GNUNET_GNSRECORD_RF_NONE; 608 code_record_len = serialize_abe_keyinfo (handle,
1129 609 rp_key,
1130 610 &ecdhe_privkey,
1131 token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey) 611 &code_record_data);
1132 + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) 612 code_record[0].data = code_record_data;
1133 + strlen (handle->scopes) + 1; //With 0-Terminator 613 code_record[0].data_size = code_record_len;
1134 token_metadata = GNUNET_malloc (token_metadata_len); 614 code_record[0].expiration_time = exp_time;
1135 write_ptr = token_metadata; 615 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1136 GNUNET_memcpy (token_metadata, ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); 616 code_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
1137 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey); 617
1138 GNUNET_memcpy (write_ptr, &handle->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 618
1139 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); 619 //Publish record
1140 GNUNET_memcpy (write_ptr, handle->scopes, strlen (handle->scopes) + 1); //with 0-Terminator;
1141
1142 token_record[1].data = token_metadata;
1143 token_record[1].data_size = token_metadata_len;
1144 token_record[1].expiration_time = exp_time;
1145 token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
1146 token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
1147
1148 //Persist token
1149 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, 620 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1150 &handle->iss_key, 621 &handle->iss_key,
1151 handle->label, 622 handle->label,
1152 2, 623 1,
1153 token_record, 624 code_record,
1154 &store_token_issue_cont, 625 &store_record_issue_cont,
1155 handle); 626 handle);
1156 GNUNET_free (ecdhe_privkey); 627 GNUNET_free (ecdhe_privkey);
1157 GNUNET_free (nonce_str); 628 GNUNET_free (nonce_str);
1158 GNUNET_free (enc_token_str); 629 GNUNET_free (code_record_data);
1159 GNUNET_free (token_metadata);
1160} 630}
1161 631
1162/** 632/**
@@ -1637,7 +1107,7 @@ run (void *cls,
1637 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential"); 1107 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
1638 } 1108 }
1639 identity_handle = GNUNET_IDENTITY_connect (cfg, 1109 identity_handle = GNUNET_IDENTITY_connect (cfg,
1640 &list_ego, 1110 NULL,
1641 NULL); 1111 NULL);
1642 1112
1643 if (GNUNET_OK == 1113 if (GNUNET_OK ==