diff options
Diffstat (limited to 'src/credential/plugin_rest_credential.c')
-rw-r--r-- | src/credential/plugin_rest_credential.c | 255 |
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 | */ |
372 | static void | 383 | static void |
384 | handle_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 | |||
447 | static void | ||
448 | subject_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 | */ | ||
480 | static void | ||
373 | handle_verify_response (void *cls, | 481 | handle_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 | ||
557 | static void | ||
558 | collect_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 | ||
450 | static void | 659 | static void |
451 | verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, | 660 | verify_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 |