aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/plugin_rest_reclaim.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/reclaim/plugin_rest_reclaim.c')
-rw-r--r--src/reclaim/plugin_rest_reclaim.c867
1 files changed, 828 insertions, 39 deletions
diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c
index 9a75b2d16..dcda75b65 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -37,7 +37,6 @@
37#include "gnunet_rest_plugin.h" 37#include "gnunet_rest_plugin.h"
38#include "gnunet_signatures.h" 38#include "gnunet_signatures.h"
39#include "json_reclaim.h" 39#include "json_reclaim.h"
40
41/** 40/**
42 * REST root namespace 41 * REST root namespace
43 */ 42 */
@@ -49,6 +48,11 @@
49#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes" 48#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
50 49
51/** 50/**
51 * Attestation namespace
52 */
53#define GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE "/reclaim/attestation"
54
55/**
52 * Ticket namespace 56 * Ticket namespace
53 */ 57 */
54#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets" 58#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets"
@@ -272,6 +276,8 @@ cleanup_handle (struct RequestHandle *handle)
272 claim_tmp = claim_entry; 276 claim_tmp = claim_entry;
273 claim_entry = claim_entry->next; 277 claim_entry = claim_entry->next;
274 GNUNET_free (claim_tmp->claim); 278 GNUNET_free (claim_tmp->claim);
279 GNUNET_free (claim_tmp->attest);
280 GNUNET_free (claim_tmp->reference);
275 GNUNET_free (claim_tmp); 281 GNUNET_free (claim_tmp);
276 } 282 }
277 GNUNET_free (handle->attr_list); 283 GNUNET_free (handle->attr_list);
@@ -360,6 +366,21 @@ finished_cont (void *cls, int32_t success, const char *emsg)
360 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 366 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
361} 367}
362 368
369static void
370delete_finished_cb (void *cls, int32_t success, const char *emsg)
371{
372 struct RequestHandle *handle = cls;
373 struct MHD_Response *resp;
374
375 resp = GNUNET_REST_create_response (emsg);
376 if (GNUNET_OK != success)
377 {
378 GNUNET_SCHEDULER_add_now (&do_error, handle);
379 return;
380 }
381 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
382 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
383}
363 384
364/** 385/**
365 * Return attributes for identity 386 * Return attributes for identity
@@ -434,6 +455,661 @@ ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
434} 455}
435 456
436 457
458static void
459add_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
460 const char *url,
461 void *cls)
462{
463 struct RequestHandle *handle = cls;
464 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
465 const char *identity;
466 struct EgoEntry *ego_entry;
467 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attribute;
468 struct GNUNET_TIME_Relative exp;
469 char term_data[handle->rest_handle->data_size + 1];
470 json_t *data_json;
471 json_error_t err;
472 struct GNUNET_JSON_Specification attrspec[] =
473 { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attribute),
474 GNUNET_JSON_spec_end () };
475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
476 "Adding an attestation reference for %s.\n",
477 handle->url);
478 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
479 "reference/") + 1 >= strlen (
480 handle->url))
481 {
482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
483 GNUNET_SCHEDULER_add_now (&do_error, handle);
484 return;
485 }
486 identity = handle->url + strlen (
487 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
488 + 1;
489 for (ego_entry = handle->ego_head; NULL != ego_entry;
490 ego_entry = ego_entry->next)
491 if (0 == strcmp (identity, ego_entry->identifier))
492 break;
493 if (NULL == ego_entry)
494 {
495 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
496 return;
497 }
498 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
499 if (0 >= handle->rest_handle->data_size)
500 {
501 GNUNET_SCHEDULER_add_now (&do_error, handle);
502 return;
503 }
504
505 term_data[handle->rest_handle->data_size] = '\0';
506 GNUNET_memcpy (term_data,
507 handle->rest_handle->data,
508 handle->rest_handle->data_size);
509 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
510 GNUNET_assert (GNUNET_OK ==
511 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
512 json_decref (data_json);
513 if (NULL == attribute)
514 {
515 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
516 "Unable to parse attestation reference from %s\n",
517 term_data);
518 GNUNET_SCHEDULER_add_now (&do_error, handle);
519 return;
520 }
521 /**
522 * New ID for attribute
523 */
524 if (0 == attribute->id)
525 attribute->id = attribute->id_attest;
526 handle->idp = GNUNET_RECLAIM_connect (cfg);
527 exp = GNUNET_TIME_UNIT_HOURS;
528 handle->idp_op = GNUNET_RECLAIM_attestation_reference_store (handle->idp,
529 identity_priv,
530 attribute,
531 &exp,
532 &finished_cont,
533 handle);
534 GNUNET_JSON_parse_free (attrspec);
535}
536
537static void
538parse_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
539 const char *url,
540 void *cls)
541{
542 struct RequestHandle *handle = cls;
543
544 char term_data[handle->rest_handle->data_size + 1];
545 json_t *data_json;
546 json_error_t err;
547 int unpack_state;
548 struct MHD_Response *resp;
549 char *val_str = NULL;
550 const char *type_str = NULL;
551 term_data[handle->rest_handle->data_size] = '\0';
552 GNUNET_memcpy (term_data,
553 handle->rest_handle->data,
554 handle->rest_handle->data_size);
555 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
556 GNUNET_assert (NULL != data_json);
557 if (! json_is_object (data_json))
558 {
559 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
560 "Error json is not array nor object!\n");
561 GNUNET_SCHEDULER_add_now (&do_error, handle);
562 return;
563 }
564 unpack_state = json_unpack (data_json,
565 "{s:s, s:s!}",
566 "value",
567 &val_str,
568 "type",
569 &type_str);
570 if ((0 != unpack_state) || (NULL == val_str) || (NULL == type_str))
571 {
572 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
573 "Error json object has a wrong format!\n");
574 GNUNET_SCHEDULER_add_now (&do_error, handle);
575 return;
576 }
577 if (0 == strcmp (type_str, "JWT"))
578 {
579 // The value is a JWT
580 char *decoded_jwt;
581 char delim[] = ".";
582 char *jwt_body = strtok (val_str, delim);
583 jwt_body = strtok (NULL, delim);
584 GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
585 (void **) &decoded_jwt);
586 resp = GNUNET_REST_create_response (decoded_jwt);
587 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
588 GNUNET_free (decoded_jwt);
589 }
590 else
591 {
592 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
593 "Error requested parsing type not supported!\n");
594 GNUNET_SCHEDULER_add_now (&do_error, handle);
595 return;
596 }
597 cleanup_handle (handle);
598 json_decref (data_json);
599}
600
601static void
602add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
603 const char *url,
604 void *cls)
605{
606 struct RequestHandle *handle = cls;
607 /* Check for substring "reference" */
608 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
609 handle->url))
610 {
611 if ( strncmp ("reference/", (handle->url + strlen (
612 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
613 + 1), strlen (
614 "reference/")) == 0)
615 {
616 add_attestation_ref_cont (con_handle,url,cls);
617 return;
618 }
619 }
620 /* Check for substring "parse" */
621 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
622 handle->url))
623 {
624 if ( strncmp ("parse", (handle->url + strlen (
625 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
626 + 1), strlen (
627 "parse")) == 0)
628 {
629 parse_attestation_cont (con_handle,url,cls);
630 return;
631 }
632 }
633 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
634 const char *identity;
635 struct EgoEntry *ego_entry;
636 struct GNUNET_RECLAIM_ATTESTATION_Claim *attribute;
637 struct GNUNET_TIME_Relative exp;
638 char term_data[handle->rest_handle->data_size + 1];
639 json_t *data_json;
640 json_error_t err;
641 struct GNUNET_JSON_Specification attrspec[] =
642 { GNUNET_RECLAIM_JSON_spec_claim_attest (&attribute),
643 GNUNET_JSON_spec_end () };
644
645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
646 "Adding an attestation for %s.\n",
647 handle->url);
648 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
649 handle->url))
650 {
651 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
652 GNUNET_SCHEDULER_add_now (&do_error, handle);
653 return;
654 }
655 identity = handle->url + strlen (
656 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
657
658 for (ego_entry = handle->ego_head; NULL != ego_entry;
659 ego_entry = ego_entry->next)
660 if (0 == strcmp (identity, ego_entry->identifier))
661 break;
662
663 if (NULL == ego_entry)
664 {
665 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
666 return;
667 }
668 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
669
670 if (0 >= handle->rest_handle->data_size)
671 {
672 GNUNET_SCHEDULER_add_now (&do_error, handle);
673 return;
674 }
675
676 term_data[handle->rest_handle->data_size] = '\0';
677 GNUNET_memcpy (term_data,
678 handle->rest_handle->data,
679 handle->rest_handle->data_size);
680 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
681 GNUNET_assert (GNUNET_OK ==
682 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
683 json_decref (data_json);
684 if (NULL == attribute)
685 {
686 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
687 "Unable to parse attestation from %s\n",
688 term_data);
689 GNUNET_SCHEDULER_add_now (&do_error, handle);
690 return;
691 }
692 /**
693 * New ID for attribute
694 */
695 if (0 == attribute->id)
696 attribute->id =
697 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
698 handle->idp = GNUNET_RECLAIM_connect (cfg);
699 exp = GNUNET_TIME_UNIT_HOURS;
700 handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp,
701 identity_priv,
702 attribute,
703 &exp,
704 &finished_cont,
705 handle);
706 GNUNET_JSON_parse_free (attrspec);
707}
708
709/**
710 * Collect all references for an ego
711 *
712 */
713static void
714ref_collect (void *cls,
715 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
716 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
717 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
718 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
719{
720 struct RequestHandle *handle = cls;
721 json_t *attr_obj;
722 char *id_str;
723 char *id_attest_str;
724
725 if (NULL == reference)
726 {
727 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
728 return;
729 }
730
731 if ((NULL == reference->name) || (NULL == reference->reference_value))
732 {
733 return;
734 }
735
736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference: %s\n",
737 reference->name);
738 attr_obj = json_object ();
739 json_object_set_new (attr_obj, "name", json_string (reference->name));
740 json_object_set_new (attr_obj, "ref_value", json_string (
741 reference->reference_value));
742 id_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id,
743 sizeof(uint64_t));
744 id_attest_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id_attest,
745 sizeof(uint64_t));
746 json_object_set_new (attr_obj, "id", json_string (id_str));
747 json_object_set_new (attr_obj, "ref_id", json_string (id_attest_str));
748 json_array_append (handle->resp_object, attr_obj);
749 json_decref (attr_obj);
750}
751
752/**
753 * Lists references for identity request
754 *
755 * @param con_handle the connection handle
756 * @param url the url
757 * @param cls the RequestHandle
758 */
759static void
760list_reference_cont (struct GNUNET_REST_RequestHandle *con_handle,
761 const char *url,
762 void *cls)
763{
764 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
765 struct RequestHandle *handle = cls;
766 struct EgoEntry *ego_entry;
767 char *identity;
768
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
770 "Getting references for %s.\n",
771 handle->url);
772 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
773 "reference/") + 1 >= strlen (
774 handle->url))
775 {
776 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
777 GNUNET_SCHEDULER_add_now (&do_error, handle);
778 return;
779 }
780 identity = handle->url + strlen (
781 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
782 + 1;
783 for (ego_entry = handle->ego_head; NULL != ego_entry;
784 ego_entry = ego_entry->next)
785 if (0 == strcmp (identity, ego_entry->identifier))
786 break;
787 handle->resp_object = json_array ();
788
789 if (NULL == ego_entry)
790 {
791 // Done
792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
793 GNUNET_SCHEDULER_add_now (&return_response, handle);
794 return;
795 }
796 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
797 handle->idp = GNUNET_RECLAIM_connect (cfg);
798 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
799 priv_key,
800 &collect_error_cb,
801 handle,
802 &ref_collect,
803 handle,
804 &collect_finished_cb,
805 handle);
806}
807
808/**
809 * Collect all attestations for an ego
810 *
811 */
812static void
813attest_collect (void *cls,
814 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
815 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
816 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
817 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
818{
819 struct RequestHandle *handle = cls;
820 json_t *attr_obj;
821 const char *type;
822 char *tmp_value;
823 char *id_str;
824
825
826 if (NULL != reference)
827 {
828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
829 "Attestation Collection with Reference\n");
830 return;
831 }
832 if (NULL == attest)
833 {
834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
835 "Attestation Collection with empty Attestation\n");
836 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
837 return;
838 }
839
840 if ((NULL == attest->name) || (NULL == attest->data))
841 {
842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
843 "Attestation Collection with empty Name/Value\n");
844 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
845 return;
846 }
847
848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation: %s\n",
849 attest->name);
850
851 tmp_value = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
852 attest->data,
853 attest->data_size);
854 attr_obj = json_object ();
855 json_object_set_new (attr_obj, "value", json_string (tmp_value));
856 json_object_set_new (attr_obj, "name", json_string (attest->name));
857 type = GNUNET_RECLAIM_ATTESTATION_number_to_typename (attest->type);
858 json_object_set_new (attr_obj, "type", json_string (type));
859 id_str = GNUNET_STRINGS_data_to_string_alloc (&attest->id, sizeof(uint64_t));
860 json_object_set_new (attr_obj, "id", json_string (id_str));
861 json_array_append (handle->resp_object, attr_obj);
862 json_decref (attr_obj);
863 GNUNET_free (tmp_value);
864 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
865}
866
867
868/**
869 * Lists attestation for identity request
870 *
871 * @param con_handle the connection handle
872 * @param url the url
873 * @param cls the RequestHandle
874 */
875static void
876list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
877 const char *url,
878 void *cls)
879{
880 struct RequestHandle *handle = cls;
881 /* Check for substring "reference" */
882 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
883 handle->url))
884 {
885 if ( strncmp ("reference/", (handle->url + strlen (
886 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
887 + 1), strlen (
888 "reference/")) == 0)
889 {
890 list_reference_cont (con_handle,url,cls);
891 return;
892 }
893 }
894 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
895 struct EgoEntry *ego_entry;
896 char *identity;
897
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
899 "Getting attestations for %s.\n",
900 handle->url);
901 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
902 handle->url))
903 {
904 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
905 GNUNET_SCHEDULER_add_now (&do_error, handle);
906 return;
907 }
908 identity = handle->url + strlen (
909 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
910
911 for (ego_entry = handle->ego_head; NULL != ego_entry;
912 ego_entry = ego_entry->next)
913 if (0 == strcmp (identity, ego_entry->identifier))
914 break;
915 handle->resp_object = json_array ();
916
917
918 if (NULL == ego_entry)
919 {
920 // Done
921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
922 GNUNET_SCHEDULER_add_now (&return_response, handle);
923 return;
924 }
925 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
926 handle->idp = GNUNET_RECLAIM_connect (cfg);
927 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
928 priv_key,
929 &collect_error_cb,
930 handle,
931 &attest_collect,
932 handle,
933 &collect_finished_cb,
934 handle);
935}
936
937/**
938 * Deletes reference from an identity
939 *
940 * @param con_handle the connection handle
941 * @param url the url
942 * @param cls the RequestHandle
943 */
944static void
945delete_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
946 const char *url,
947 void *cls)
948{
949 struct RequestHandle *handle = cls;
950 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
951 struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
952 struct EgoEntry *ego_entry;
953 char *identity;
954 char *identity_id_str;
955 char *id;
956 char term_data[handle->rest_handle->data_size + 1];
957 json_t *data_json;
958 json_error_t err;
959
960 struct GNUNET_JSON_Specification attrspec[] =
961 { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attr),
962 GNUNET_JSON_spec_end () };
963 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
964 "Deleting attestation reference.\n");
965 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
966 "reference/") + 1 >= strlen (
967 handle->url))
968 {
969 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
970 GNUNET_SCHEDULER_add_now (&do_error, handle);
971 return;
972 }
973 identity_id_str = strdup (handle->url + strlen (
974 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
975 + strlen ("reference/")
976 + 1);
977 identity = strtok (identity_id_str, "/");
978 id = strtok (NULL, "/");
979
980 if ((NULL == identity) || (NULL == id))
981 {
982 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
983 GNUNET_SCHEDULER_add_now (&do_error, handle);
984 return;
985 }
986 for (ego_entry = handle->ego_head; NULL != ego_entry;
987 ego_entry = ego_entry->next)
988 if (0 == strcmp (identity, ego_entry->identifier))
989 break;
990 handle->resp_object = json_array ();
991 if (NULL == ego_entry)
992 {
993 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
994 GNUNET_SCHEDULER_add_now (&return_response, handle);
995 return;
996 }
997 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
998 if (0 >= handle->rest_handle->data_size)
999 {
1000 GNUNET_SCHEDULER_add_now (&do_error, handle);
1001 return;
1002 }
1003
1004 term_data[handle->rest_handle->data_size] = '\0';
1005 GNUNET_memcpy (term_data,
1006 handle->rest_handle->data,
1007 handle->rest_handle->data_size);
1008 data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
1009 GNUNET_assert (GNUNET_OK ==
1010 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
1011 json_decref (data_json);
1012 if (NULL == attr)
1013 {
1014 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1015 "Unable to parse attestation reference from %s\n",
1016 term_data);
1017 GNUNET_SCHEDULER_add_now (&do_error, handle);
1018 return;
1019 }
1020 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr->id, sizeof(uint64_t));
1021
1022 handle->idp = GNUNET_RECLAIM_connect (cfg);
1023 handle->idp_op = GNUNET_RECLAIM_attestation_reference_delete (handle->idp,
1024 priv_key,
1025 attr,
1026 &
1027 delete_finished_cb,
1028 handle);
1029 GNUNET_JSON_parse_free (attrspec);
1030}
1031
1032
1033/**
1034 * Deletes attestation from an identity
1035 *
1036 * @param con_handle the connection handle
1037 * @param url the url
1038 * @param cls the RequestHandle
1039 */
1040static void
1041delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
1042 const char *url,
1043 void *cls)
1044{
1045 struct RequestHandle *handle = cls;
1046 /* Check for substring "reference" */
1047 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
1048 handle->url))
1049 {
1050 if ( strncmp ("reference", (handle->url + strlen (
1051 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
1052 + 1), strlen (
1053 "reference")) == 0)
1054 {
1055 delete_attestation_ref_cont (con_handle,url,cls);
1056 return;
1057 }
1058 }
1059 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1060 struct GNUNET_RECLAIM_ATTESTATION_Claim attr;
1061 struct EgoEntry *ego_entry;
1062 char *identity_id_str;
1063 char *identity;
1064 char *id;
1065
1066 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attestation.\n");
1067 if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
1068 handle->url))
1069 {
1070 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
1071 GNUNET_SCHEDULER_add_now (&do_error, handle);
1072 return;
1073 }
1074 identity_id_str =
1075 strdup (handle->url + strlen (
1076 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1);
1077 identity = strtok (identity_id_str, "/");
1078 id = strtok (NULL, "/");
1079 if ((NULL == identity) || (NULL == id))
1080 {
1081 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
1082 GNUNET_free (identity_id_str);
1083 GNUNET_SCHEDULER_add_now (&do_error, handle);
1084 return;
1085 }
1086
1087 for (ego_entry = handle->ego_head; NULL != ego_entry;
1088 ego_entry = ego_entry->next)
1089 if (0 == strcmp (identity, ego_entry->identifier))
1090 break;
1091 handle->resp_object = json_array ();
1092 if (NULL == ego_entry)
1093 {
1094 // Done
1095 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
1096 GNUNET_free (identity_id_str);
1097 GNUNET_SCHEDULER_add_now (&return_response, handle);
1098 return;
1099 }
1100 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1101 handle->idp = GNUNET_RECLAIM_connect (cfg);
1102 memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim));
1103 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
1104 attr.name = "";
1105 handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp,
1106 priv_key,
1107 &attr,
1108 &delete_finished_cb,
1109 handle);
1110 GNUNET_free (identity_id_str);
1111}
1112
437/** 1113/**
438 * List tickets for identity request 1114 * List tickets for identity request
439 * 1115 *
@@ -568,6 +1244,72 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
568 GNUNET_JSON_parse_free (attrspec); 1244 GNUNET_JSON_parse_free (attrspec);
569} 1245}
570 1246
1247/**
1248 * Parse a JWT and return the respective claim value as Attribute
1249 *
1250 * @param attest the jwt attestation
1251 * @param claim the name of the claim in the JWT
1252 *
1253 * @return a GNUNET_RECLAIM_ATTRIBUTE_Claim, containing the new value
1254 */
1255struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
1256parse_jwt (const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1257 const char *claim)
1258{
1259 char *jwt_string;
1260 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
1261 char delim[] = ".";
1262 const char *type_str = NULL;
1263 const char *val_str = NULL;
1264 char *data;
1265 size_t data_size;
1266 uint32_t type;
1267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
1268 char *decoded_jwt;
1269 json_t *json_val;
1270 json_error_t *json_err = NULL;
1271
1272 jwt_string = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
1273 attest->data,
1274 attest->data_size);
1275 char *jwt_body = strtok (jwt_string, delim);
1276 jwt_body = strtok (NULL, delim);
1277 GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
1278 (void **) &decoded_jwt);
1279 json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
1280 const char *key;
1281 json_t *value;
1282 json_object_foreach (json_val, key, value) {
1283 if (0 == strcasecmp (key,claim))
1284 {
1285 val_str = json_dumps (value, JSON_ENCODE_ANY);
1286 }
1287 }
1288 type_str = "String";
1289 type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
1290 if (GNUNET_SYSERR ==(GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,val_str,
1291 (void **) &data,
1292 &data_size)))
1293 {
1294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1295 "Attribute value from JWT Parser invalid!\n");
1296 GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
1297 "Error: Referenced Claim Name not Found",
1298 (void **) &data,
1299 &data_size);
1300 attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
1301 attr->id = attest->id;
1302 attr->flag = 1;
1303 }
1304 else
1305 {
1306 attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
1307 attr->id = attest->id;
1308 attr->flag = 1;
1309 }
1310 return attr;
1311}
1312
571 1313
572/** 1314/**
573 * Collect all attributes for an ego 1315 * Collect all attributes for an ego
@@ -576,40 +1318,93 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
576static void 1318static void
577attr_collect (void *cls, 1319attr_collect (void *cls,
578 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 1320 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
579 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 1321 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1322 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1323 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
580{ 1324{
581 struct RequestHandle *handle = cls; 1325 struct RequestHandle *handle = cls;
582 json_t *attr_obj; 1326 json_t *attr_obj;
583 const char *type; 1327 const char *type;
584 char *tmp_value;
585 char *id_str; 1328 char *id_str;
586 1329
587 if ((NULL == attr->name) || (NULL == attr->data)) 1330 if ((NULL == attr) && (NULL == reference))
588 { 1331 {
1332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1333 "Attribute Collection with empty Attribute/Reference\n");
589 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1334 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
590 return; 1335 return;
591 } 1336 }
592 1337
593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name); 1338 if (NULL == attr)
594 1339 {
595 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
596 attr->data,
597 attr->data_size);
598 1340
599 attr_obj = json_object (); 1341 if ((NULL == reference->name) || (NULL == reference->reference_value))
600 json_object_set_new (attr_obj, "value", json_string (tmp_value)); 1342 {
601 json_object_set_new (attr_obj, "name", json_string (attr->name)); 1343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
602 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type); 1344 "Attribute Collection with empty Reference Name/Value\n");
603 json_object_set_new (attr_obj, "type", json_string (type)); 1345 return;
604 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t)); 1346 }
605 json_object_set_new (attr_obj, "id", json_string (id_str)); 1347 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr2;
606 json_array_append (handle->resp_object, attr_obj); 1348 attr2 = parse_jwt (attest, reference->reference_value);
607 json_decref (attr_obj); 1349 if (NULL == attr2)
608 GNUNET_free (tmp_value); 1350 {
609 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1351 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1352 "Attribute Collection with unparsed Attestation\n");
1353 return;
1354 }
1355 attr2->name = reference->name;
1356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference as attribute: %s\n",
1357 reference->name);
1358 char *tmp_value;
1359 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr2->type,
1360 attr2->data,
1361 attr2->data_size);
1362 attr_obj = json_object ();
1363
1364 json_object_set_new (attr_obj, "value", json_string (tmp_value));
1365 json_object_set_new (attr_obj, "name", json_string (attr2->name));
1366 json_object_set_new (attr_obj, "flag", json_string ("1"));
1367 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr2->type);
1368 json_object_set_new (attr_obj, "type", json_string (type));
1369 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr2->id, sizeof(uint64_t));
1370 json_object_set_new (attr_obj, "id", json_string (id_str));
1371 json_array_append (handle->resp_object, attr_obj);
1372 json_decref (attr_obj);
1373 GNUNET_free (tmp_value);
1374 }
1375 else
1376 {
1377 if ((NULL == attr->name) || (NULL == attr->data))
1378 {
1379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1380 "Attribute Collection with empty Attribute Name/Value\n");
1381 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1382 return;
1383 }
1384 char *tmp_value;
1385 char *flag_str;
1386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
1387
1388 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
1389 attr->data,
1390 attr->data_size);
1391
1392 attr_obj = json_object ();
1393 json_object_set_new (attr_obj, "value", json_string (tmp_value));
1394 json_object_set_new (attr_obj, "name", json_string (attr->name));
1395 GNUNET_asprintf (&flag_str,"%d",attr->flag);
1396 json_object_set_new (attr_obj, "flag", json_string (flag_str));
1397 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
1398 json_object_set_new (attr_obj, "type", json_string (type));
1399 id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
1400 json_object_set_new (attr_obj, "id", json_string (id_str));
1401 json_array_append (handle->resp_object, attr_obj);
1402 json_decref (attr_obj);
1403 GNUNET_free (tmp_value);
1404 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
1405 }
610} 1406}
611 1407
612
613/** 1408/**
614 * List attributes for identity request 1409 * List attributes for identity request
615 * 1410 *
@@ -665,23 +1460,6 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
665} 1460}
666 1461
667 1462
668static void
669delete_finished_cb (void *cls, int32_t success, const char *emsg)
670{
671 struct RequestHandle *handle = cls;
672 struct MHD_Response *resp;
673
674 resp = GNUNET_REST_create_response (emsg);
675 if (GNUNET_OK != success)
676 {
677 GNUNET_SCHEDULER_add_now (&do_error, handle);
678 return;
679 }
680 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
681 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
682}
683
684
685/** 1463/**
686 * List attributes for identity request 1464 * List attributes for identity request
687 * 1465 *
@@ -825,7 +1603,9 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
825static void 1603static void
826consume_cont (void *cls, 1604consume_cont (void *cls,
827 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 1605 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
828 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 1606 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
1607 const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
1608 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
829{ 1609{
830 struct RequestHandle *handle = cls; 1610 struct RequestHandle *handle = cls;
831 char *val_str; 1611 char *val_str;
@@ -969,6 +1749,15 @@ init_cont (struct RequestHandle *handle)
969 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, 1749 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
970 &delete_attribute_cont }, 1750 &delete_attribute_cont },
971 { MHD_HTTP_METHOD_GET, 1751 { MHD_HTTP_METHOD_GET,
1752 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
1753 &list_attestation_cont },
1754 { MHD_HTTP_METHOD_POST,
1755 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
1756 &add_attestation_cont },
1757 { MHD_HTTP_METHOD_DELETE,
1758 GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
1759 &delete_attestation_cont },
1760 { MHD_HTTP_METHOD_GET,
972 GNUNET_REST_API_NS_IDENTITY_TICKETS, 1761 GNUNET_REST_API_NS_IDENTITY_TICKETS,
973 &list_tickets_cont }, 1762 &list_tickets_cont },
974 { MHD_HTTP_METHOD_POST, 1763 { MHD_HTTP_METHOD_POST,