aboutsummaryrefslogtreecommitdiff
path: root/src/credential/plugin_rest_credential.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/credential/plugin_rest_credential.c')
-rw-r--r--src/credential/plugin_rest_credential.c255
1 files changed, 240 insertions, 15 deletions
diff --git a/src/credential/plugin_rest_credential.c b/src/credential/plugin_rest_credential.c
index 0d469f5de..59022e794 100644
--- a/src/credential/plugin_rest_credential.c
+++ b/src/credential/plugin_rest_credential.c
@@ -41,10 +41,14 @@
41 41
42#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify" 42#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify"
43 43
44#define GNUNET_REST_API_NS_CREDENTIAL_COLLECT "/credential/collect"
45
44#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration" 46#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration"
45 47
46#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key" 48#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key"
47 49
50#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO "subject"
51
48#define GNUNET_REST_JSONAPI_CREDENTIAL "credential" 52#define GNUNET_REST_JSONAPI_CREDENTIAL "credential"
49 53
50#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential" 54#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential"
@@ -93,6 +97,11 @@ struct RequestHandle
93 struct GNUNET_IDENTITY_Operation *id_op; 97 struct GNUNET_IDENTITY_Operation *id_op;
94 98
95 /** 99 /**
100 * Handle to ego lookup
101 */
102 struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
103
104 /**
96 * Handle to rest request 105 * Handle to rest request
97 */ 106 */
98 struct GNUNET_REST_RequestHandle *rest_handle; 107 struct GNUNET_REST_RequestHandle *rest_handle;
@@ -173,6 +182,8 @@ cleanup_handle (struct RequestHandle *handle)
173 GNUNET_CREDENTIAL_disconnect (handle->credential); 182 GNUNET_CREDENTIAL_disconnect (handle->credential);
174 if (NULL != handle->id_op) 183 if (NULL != handle->id_op)
175 GNUNET_IDENTITY_cancel (handle->id_op); 184 GNUNET_IDENTITY_cancel (handle->id_op);
185 if (NULL != handle->ego_lookup)
186 GNUNET_IDENTITY_ego_lookup_cancel (handle->ego_lookup);
176 if (NULL != handle->identity) 187 if (NULL != handle->identity)
177 GNUNET_IDENTITY_disconnect (handle->identity); 188 GNUNET_IDENTITY_disconnect (handle->identity);
178 if (NULL != handle->timeout_task) 189 if (NULL != handle->timeout_task)
@@ -370,6 +381,103 @@ credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred)
370 * @param cd array of @a cd_count records with the results 381 * @param cd array of @a cd_count records with the results
371 */ 382 */
372static void 383static void
384handle_collect_response (void *cls,
385 unsigned int d_count,
386 struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
387 unsigned int c_count,
388 struct GNUNET_CREDENTIAL_Credential *cred)
389{
390 struct RequestHandle *handle = cls;
391 struct MHD_Response *resp;
392 struct GNUNET_JSONAPI_Document *json_document;
393 struct GNUNET_JSONAPI_Resource *json_resource;
394 json_t *cred_obj;
395 json_t *cred_array;
396 char *result;
397 char *issuer;
398 char *id;
399 uint32_t i;
400
401 handle->verify_request = NULL;
402 if (NULL == cred) {
403 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
404 "Verify failed.\n");
405 handle->response_code = MHD_HTTP_NOT_FOUND;
406 GNUNET_SCHEDULER_add_now (&do_error, handle);
407 return;
408 }
409 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key);
410 if (NULL == issuer)
411 {
412 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
413 "Issuer in delegation malformed\n");
414 return;
415 }
416 GNUNET_asprintf (&id,
417 "%s.%s",
418 issuer,
419 handle->issuer_attr);
420 GNUNET_free (issuer);
421 json_document = GNUNET_JSONAPI_document_new ();
422 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
423 id);
424 GNUNET_free (id);
425 cred_array = json_array ();
426 for (i=0;i<c_count;i++)
427 {
428 cred_obj = credential_to_json (&cred[i]);
429 json_array_append_new (cred_array, cred_obj);
430 }
431 GNUNET_JSONAPI_resource_add_attr (json_resource,
432 GNUNET_REST_JSONAPI_CREDENTIAL,
433 cred_array);
434 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
435 GNUNET_JSONAPI_document_serialize (json_document, &result);
436 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
437 "Result %s\n",
438 result);
439 json_decref (cred_array);
440 GNUNET_JSONAPI_document_delete (json_document);
441 resp = GNUNET_REST_create_response (result);
442 GNUNET_free(result);
443 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
444 cleanup_handle (handle);
445}
446
447static void
448subject_ego_lookup (void *cls,
449 const struct GNUNET_IDENTITY_Ego *ego)
450{
451 struct RequestHandle *handle = cls;
452 const struct GNUNET_CRYPTO_EcdsaPrivateKey *sub_key;
453 handle->ego_lookup = NULL;
454
455 if (NULL == ego)
456 {
457 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
458 "Subject not found\n");
459 GNUNET_SCHEDULER_add_now (&do_error, handle);
460 return;
461 }
462 sub_key = GNUNET_IDENTITY_ego_get_private_key (ego);
463 handle->verify_request = GNUNET_CREDENTIAL_collect (handle->credential,
464 &handle->issuer_key,
465 handle->issuer_attr,
466 sub_key,
467 &handle_collect_response,
468 handle);
469}
470
471
472
473/**
474 * Function called with the result of a Credential lookup.
475 *
476 * @param cls the 'const char *' name that was resolved
477 * @param cd_count number of records returned
478 * @param cd array of @a cd_count records with the results
479 */
480static void
373handle_verify_response (void *cls, 481handle_verify_response (void *cls,
374 unsigned int d_count, 482 unsigned int d_count,
375 struct GNUNET_CREDENTIAL_Delegation *delegation_chain, 483 struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
@@ -446,6 +554,107 @@ handle_verify_response (void *cls,
446 cleanup_handle (handle); 554 cleanup_handle (handle);
447} 555}
448 556
557static void
558collect_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
559 const char* url,
560 void *cls)
561{
562 struct RequestHandle *handle = cls;
563 struct GNUNET_HashCode key;
564 char *tmp;
565 char *entity_attr;
566
567 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
568 "Connecting...\n");
569 handle->credential = GNUNET_CREDENTIAL_connect (cfg);
570 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
571 &do_error, handle);
572 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
573 "Connected\n");
574 if (NULL == handle->credential)
575 {
576 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
577 "Connecting to CREDENTIAL failed\n");
578 GNUNET_SCHEDULER_add_now (&do_error, handle);
579 return;
580 }
581 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR,
582 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR),
583 &key);
584 if ( GNUNET_NO ==
585 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
586 &key) )
587 {
588 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
589 "Missing issuer attribute\n");
590 GNUNET_SCHEDULER_add_now (&do_error, handle);
591 return;
592 }
593 tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
594 &key);
595 entity_attr = GNUNET_strdup (tmp);
596 tmp = strtok(entity_attr, ".");
597 if (NULL == tmp)
598 {
599 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
600 "Malformed issuer or attribute\n");
601 GNUNET_free (entity_attr);
602 GNUNET_SCHEDULER_add_now (&do_error, handle);
603 return;
604 }
605 if (GNUNET_OK !=
606 GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp,
607 strlen (tmp),
608 &handle->issuer_key))
609 {
610 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
611 "Malformed issuer key\n");
612 GNUNET_free (entity_attr);
613 GNUNET_SCHEDULER_add_now (&do_error, handle);
614 return;
615 }
616 tmp = strtok (NULL, "."); //Issuer attribute
617 if (NULL == tmp)
618 {
619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
620 "Malformed attribute\n");
621 GNUNET_free (entity_attr);
622 GNUNET_SCHEDULER_add_now (&do_error, handle);
623 return;
624 }
625 handle->issuer_attr = GNUNET_strdup (tmp);
626 GNUNET_free (entity_attr);
627
628 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO,
629 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO),
630 &key);
631 if ( GNUNET_NO ==
632 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
633 &key) )
634 {
635 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
636 "Missing subject\n");
637 GNUNET_free (entity_attr);
638 GNUNET_SCHEDULER_add_now (&do_error, handle);
639 return;
640 }
641 tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
642 &key);
643 if (NULL == tmp)
644 {
645 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
646 "Malformed subject\n");
647 GNUNET_free (entity_attr);
648 GNUNET_SCHEDULER_add_now (&do_error, handle);
649 return;
650 }
651 handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg,
652 tmp,
653 &subject_ego_lookup,
654 handle);
655}
656
657
449 658
450static void 659static void
451verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, 660verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
@@ -527,15 +736,15 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
527 handle->issuer_attr = GNUNET_strdup (tmp); 736 handle->issuer_attr = GNUNET_strdup (tmp);
528 GNUNET_free (entity_attr); 737 GNUNET_free (entity_attr);
529 738
530 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_ATTR, 739 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY,
531 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_ATTR), 740 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY),
532 &key); 741 &key);
533 if ( GNUNET_NO == 742 if ( GNUNET_NO ==
534 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, 743 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
535 &key) ) 744 &key) )
536 { 745 {
537 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 746 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
538 "Missing subject or attribute\n"); 747 "Missing subject key\n");
539 GNUNET_free (entity_attr); 748 GNUNET_free (entity_attr);
540 GNUNET_SCHEDULER_add_now (&do_error, handle); 749 GNUNET_SCHEDULER_add_now (&do_error, handle);
541 return; 750 return;
@@ -560,7 +769,6 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
560 GNUNET_SCHEDULER_add_now (&do_error, handle); 769 GNUNET_SCHEDULER_add_now (&do_error, handle);
561 return; 770 return;
562 } 771 }
563 GNUNET_free (entity_attr);
564 772
565 if (0 >= handle->rest_handle->data_size) 773 if (0 >= handle->rest_handle->data_size)
566 { 774 {
@@ -596,28 +804,44 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
596 } 804 }
597 805
598 resource_count = GNUNET_JSONAPI_document_resource_count(json_obj); 806 resource_count = GNUNET_JSONAPI_document_resource_count(json_obj);
807 GNUNET_assert (1 == resource_count);
808 res = (GNUNET_JSONAPI_document_get_resource(json_obj, 0));
809 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type(res,
810 GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO))
811 {
812 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
813 "Resource not a credential!\n");
814 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
815 "Unable to parse JSONAPI Object from %s\n",
816 term_data);
817 GNUNET_JSONAPI_document_delete (json_obj);
818 GNUNET_SCHEDULER_add_now (&do_error, handle);
819 return;
820 }
821 cred_json = GNUNET_JSONAPI_resource_read_attr (res,
822 GNUNET_REST_JSONAPI_CREDENTIAL);
823
824 GNUNET_assert (json_is_array (cred_json));
825
826 credential_count = json_array_size(cred_json);
827
599 struct GNUNET_CREDENTIAL_Credential credentials[credential_count]; 828 struct GNUNET_CREDENTIAL_Credential credentials[credential_count];
600 for (i=0;i<resource_count;i++) 829 for (i=0;i<credential_count;i++)
601 { 830 {
602 res = (GNUNET_JSONAPI_document_get_resource(json_obj, i)); 831 cred = json_to_credential (json_array_get (cred_json, i));
603 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type(res, 832 if (NULL == cred)
604 GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO))
605 { 833 {
606 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 834 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
607 "Resource not a credential!\n"); 835 "Unable to parse credential!\n");
608 continue; 836 continue;
609 } 837 }
610 credential_count++;
611 cred_json = GNUNET_JSONAPI_resource_read_attr (res,
612 GNUNET_REST_JSONAPI_CREDENTIAL);
613 cred = json_to_credential (cred_json);
614 GNUNET_memcpy (&credentials[i], 838 GNUNET_memcpy (&credentials[i],
615 cred, 839 cred,
616 sizeof (struct GNUNET_CREDENTIAL_Credential)); 840 sizeof (struct GNUNET_CREDENTIAL_Credential));
617 credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute); 841 credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute);
618 GNUNET_free (cred); 842 GNUNET_free (cred);
619 } 843 }
620 844 GNUNET_JSONAPI_document_delete(json_obj);
621 handle->verify_request = GNUNET_CREDENTIAL_verify (handle->credential, 845 handle->verify_request = GNUNET_CREDENTIAL_verify (handle->credential,
622 &handle->issuer_key, 846 &handle->issuer_key,
623 handle->issuer_attr, 847 handle->issuer_attr,
@@ -888,7 +1112,8 @@ rest_credential_process_request(struct GNUNET_REST_RequestHandle *conndata_handl
888 handle->rest_handle = conndata_handle; 1112 handle->rest_handle = conndata_handle;
889 1113
890 static const struct GNUNET_REST_RequestHandler handlers[] = { 1114 static const struct GNUNET_REST_RequestHandler handlers[] = {
891 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, &verify_cred_cont}, 1115 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, &verify_cred_cont},
1116 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_COLLECT, &collect_cred_cont},
892 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, &issue_cred_cont}, 1117 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, &issue_cred_cont},
893 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont}, 1118 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont},
894 GNUNET_REST_HANDLER_END 1119 GNUNET_REST_HANDLER_END