aboutsummaryrefslogtreecommitdiff
path: root/src/credential/plugin_rest_credential.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2016-12-18 16:52:59 +0100
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2016-12-18 16:52:59 +0100
commit33e847bf4edc06be68589467d0f6a31c07d911ac (patch)
treed635352dbea2aa448395d52703351ec8c7242fe4 /src/credential/plugin_rest_credential.c
parent9c5ecc381458c941fdb70f1f4a47e76daac4eda5 (diff)
downloadgnunet-33e847bf4edc06be68589467d0f6a31c07d911ac.tar.gz
gnunet-33e847bf4edc06be68589467d0f6a31c07d911ac.zip
-fixes
Diffstat (limited to 'src/credential/plugin_rest_credential.c')
-rw-r--r--src/credential/plugin_rest_credential.c258
1 files changed, 243 insertions, 15 deletions
diff --git a/src/credential/plugin_rest_credential.c b/src/credential/plugin_rest_credential.c
index 11e6fb276..2df65d7ad 100644
--- a/src/credential/plugin_rest_credential.c
+++ b/src/credential/plugin_rest_credential.c
@@ -37,6 +37,14 @@
37 37
38#define GNUNET_REST_API_NS_CREDENTIAL "/credential" 38#define GNUNET_REST_API_NS_CREDENTIAL "/credential"
39 39
40#define GNUNET_REST_API_NS_CREDENTIAL_ISSUE "/credential/issue"
41
42#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify"
43
44#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration"
45
46#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key"
47
40#define GNUNET_REST_JSONAPI_CREDENTIAL "credential" 48#define GNUNET_REST_JSONAPI_CREDENTIAL "credential"
41 49
42#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential" 50#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential"
@@ -57,7 +65,7 @@ struct Plugin
57 65
58const struct GNUNET_CONFIGURATION_Handle *cfg; 66const struct GNUNET_CONFIGURATION_Handle *cfg;
59 67
60struct VerifyHandle 68struct RequestHandle
61{ 69{
62 /** 70 /**
63 * Handle to Credential service. 71 * Handle to Credential service.
@@ -70,6 +78,21 @@ struct VerifyHandle
70 struct GNUNET_CREDENTIAL_Request *verify_request; 78 struct GNUNET_CREDENTIAL_Request *verify_request;
71 79
72 /** 80 /**
81 * Handle to issue request
82 */
83 struct GNUNET_CREDENTIAL_Request *issue_request;
84
85 /**
86 * Handle to identity
87 */
88 struct GNUNET_IDENTITY_Handle *identity;
89
90 /**
91 * Handle to identity operation
92 */
93 struct GNUNET_IDENTITY_Operation *id_op;
94
95 /**
73 * Handle to rest request 96 * Handle to rest request
74 */ 97 */
75 struct GNUNET_REST_RequestHandle *rest_handle; 98 struct GNUNET_REST_RequestHandle *rest_handle;
@@ -133,7 +156,7 @@ struct VerifyHandle
133 * @param handle Handle to clean up 156 * @param handle Handle to clean up
134 */ 157 */
135static void 158static void
136cleanup_handle (struct VerifyHandle *handle) 159cleanup_handle (struct RequestHandle *handle)
137{ 160{
138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
139 "Cleaning up\n"); 162 "Cleaning up\n");
@@ -145,16 +168,13 @@ cleanup_handle (struct VerifyHandle *handle)
145 if (NULL != handle->subject_attr) 168 if (NULL != handle->subject_attr)
146 GNUNET_free (handle->subject_attr); 169 GNUNET_free (handle->subject_attr);
147 if (NULL != handle->verify_request) 170 if (NULL != handle->verify_request)
148 {
149 GNUNET_CREDENTIAL_verify_cancel (handle->verify_request); 171 GNUNET_CREDENTIAL_verify_cancel (handle->verify_request);
150 handle->verify_request = NULL;
151 }
152 if (NULL != handle->credential) 172 if (NULL != handle->credential)
153 {
154 GNUNET_CREDENTIAL_disconnect (handle->credential); 173 GNUNET_CREDENTIAL_disconnect (handle->credential);
155 handle->credential = NULL; 174 if (NULL != handle->id_op)
156 } 175 GNUNET_IDENTITY_cancel (handle->id_op);
157 176 if (NULL != handle->identity)
177 GNUNET_IDENTITY_disconnect (handle->identity);
158 if (NULL != handle->timeout_task) 178 if (NULL != handle->timeout_task)
159 { 179 {
160 GNUNET_SCHEDULER_cancel (handle->timeout_task); 180 GNUNET_SCHEDULER_cancel (handle->timeout_task);
@@ -172,7 +192,7 @@ cleanup_handle (struct VerifyHandle *handle)
172static void 192static void
173do_error (void *cls) 193do_error (void *cls)
174{ 194{
175 struct VerifyHandle *handle = cls; 195 struct RequestHandle *handle = cls;
176 struct MHD_Response *resp; 196 struct MHD_Response *resp;
177 197
178 resp = GNUNET_REST_create_response (NULL); 198 resp = GNUNET_REST_create_response (NULL);
@@ -280,7 +300,7 @@ handle_verify_response (void *cls,
280 struct GNUNET_CREDENTIAL_Credential *cred) 300 struct GNUNET_CREDENTIAL_Credential *cred)
281{ 301{
282 302
283 struct VerifyHandle *handle = cls; 303 struct RequestHandle *handle = cls;
284 struct MHD_Response *resp; 304 struct MHD_Response *resp;
285 struct GNUNET_JSONAPI_Document *json_document; 305 struct GNUNET_JSONAPI_Document *json_document;
286 struct GNUNET_JSONAPI_Resource *json_resource; 306 struct GNUNET_JSONAPI_Resource *json_resource;
@@ -355,7 +375,7 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
355 const char* url, 375 const char* url,
356 void *cls) 376 void *cls)
357{ 377{
358 struct VerifyHandle *handle = cls; 378 struct RequestHandle *handle = cls;
359 struct GNUNET_HashCode key; 379 struct GNUNET_HashCode key;
360 char *tmp; 380 char *tmp;
361 char *entity_attr; 381 char *entity_attr;
@@ -478,6 +498,213 @@ verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
478 498
479} 499}
480 500
501void
502send_cred_response (struct RequestHandle *handle,
503 struct GNUNET_CREDENTIAL_Credential *cred)
504{
505 struct MHD_Response *resp;
506 struct GNUNET_JSONAPI_Document *json_document;
507 struct GNUNET_JSONAPI_Resource *json_resource;
508 json_t *cred_obj;
509 char *result;
510 char *issuer;
511 char *subject;
512 char *signature;
513 char *id;
514
515 GNUNET_assert (NULL == cred);
516 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
517 if (NULL == issuer)
518 {
519 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
520 "Subject malformed\n");
521 return;
522 }
523 GNUNET_asprintf (&id,
524 "%s.%s",
525 issuer,
526 (char*)&cred[1]);
527 subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
528 if (NULL == subject)
529 {
530 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
531 "Subject malformed\n");
532 return;
533 }
534 GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
535 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
536 &signature);
537 json_document = GNUNET_JSONAPI_document_new ();
538 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
539 id);
540 GNUNET_free (id);
541 cred_obj = json_object();
542 json_object_set_new (cred_obj, "issuer", json_string (issuer));
543 json_object_set_new (cred_obj, "subject", json_string (subject));
544 json_object_set_new (cred_obj, "expiration", json_integer( cred->expiration.abs_value_us));
545 json_object_set_new (cred_obj, "signature", json_string (signature));
546 GNUNET_JSONAPI_resource_add_attr (json_resource,
547 GNUNET_REST_JSONAPI_CREDENTIAL,
548 cred_obj);
549 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
550 GNUNET_JSONAPI_document_serialize (json_document, &result);
551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
552 "Result %s\n",
553 result);
554 json_decref (cred_obj);
555 GNUNET_JSONAPI_document_delete (json_document);
556 resp = GNUNET_REST_create_response (result);
557 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
558 GNUNET_free (result);
559 GNUNET_free (signature);
560 GNUNET_free (issuer);
561 GNUNET_free (subject);
562 cleanup_handle (handle);
563}
564
565void
566get_cred_issuer_cb (void *cls,
567 struct GNUNET_IDENTITY_Ego *ego,
568 void **ctx,
569 const char *name)
570{
571 struct RequestHandle *handle = cls;
572 struct GNUNET_TIME_Absolute etime_abs;
573 struct GNUNET_TIME_Relative etime_rel;
574 const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer_key;
575 struct GNUNET_HashCode key;
576 struct GNUNET_CREDENTIAL_Credential *cred;
577 char* expiration_str;
578 char* tmp;
579
580 handle->id_op = NULL;
581
582 if (NULL == name)
583 {
584 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
585 "Issuer not configured!\n");
586 GNUNET_SCHEDULER_add_now (&do_error, handle);
587 return;
588 }
589
590 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
591 "Connecting to credential service...\n");
592 handle->credential = GNUNET_CREDENTIAL_connect (cfg);
593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
594 "Connected\n");
595 if (NULL == handle->credential)
596 {
597 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
598 "Connecting to CREDENTIAL failed\n");
599 GNUNET_SCHEDULER_add_now (&do_error, handle);
600 return;
601 }
602 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION,
603 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION),
604 &key);
605 if ( GNUNET_NO ==
606 GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
607 &key) )
608 {
609 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
610 "Missing expiration\n");
611 GNUNET_SCHEDULER_add_now (&do_error, handle);
612 return;
613 }
614 expiration_str = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
615 &key);
616 if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str,
617 &etime_rel))
618 {
619 etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
620 } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration_str,
621 &etime_abs))
622 {
623 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
624 "Malformed expiration: %s\n", expiration_str);
625 GNUNET_SCHEDULER_add_now (&do_error, handle);
626 return;
627 }
628 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR,
629 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR),
630 &key);
631 if ( GNUNET_NO ==
632 GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
633 &key) )
634 {
635 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
636 "Missing issuer attribute\n");
637 GNUNET_SCHEDULER_add_now (&do_error, handle);
638 return;
639 }
640 handle->issuer_attr = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get
641 (handle->rest_handle->url_param_map,
642 &key));
643 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY,
644 strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY),
645 &key);
646 if ( GNUNET_NO ==
647 GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
648 &key) )
649 {
650 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
651 "Missing subject\n");
652 GNUNET_SCHEDULER_add_now (&do_error, handle);
653 return;
654 }
655 tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
656 &key);
657 if (NULL == tmp)
658 {
659 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
660 "Malformed subject\n");
661 GNUNET_SCHEDULER_add_now (&do_error, handle);
662 return;
663 }
664 if (GNUNET_OK !=
665 GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp,
666 strlen (tmp),
667 &handle->subject_key)) {
668 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
669 "Malformed subject key\n");
670 GNUNET_SCHEDULER_add_now (&do_error, handle);
671 return;
672 }
673 issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego);
674 cred = GNUNET_CREDENTIAL_credential_issue (issuer_key,
675 &handle->subject_key,
676 handle->issuer_attr,
677 &etime_abs);
678 if (NULL == cred)
679 {
680 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
681 "Failed to create credential\n");
682 GNUNET_SCHEDULER_add_now (&do_error, handle);
683 return;
684 }
685 send_cred_response (handle, cred);
686}
687
688
689static void
690issue_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
691 const char* url,
692 void *cls)
693{
694 struct RequestHandle *handle = cls;
695
696 handle->identity = GNUNET_IDENTITY_connect (cfg,
697 NULL,
698 NULL);
699 handle->id_op = GNUNET_IDENTITY_get(handle->identity,
700 "credential-issuer",
701 &get_cred_issuer_cb,
702 handle);
703 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
704 &do_error,
705 handle);
706}
707
481/** 708/**
482 * Handle rest request 709 * Handle rest request
483 * 710 *
@@ -489,7 +716,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
489 void *cls) 716 void *cls)
490{ 717{
491 struct MHD_Response *resp; 718 struct MHD_Response *resp;
492 struct VerifyHandle *handle = cls; 719 struct RequestHandle *handle = cls;
493 720
494 //For GNS, independent of path return all options 721 //For GNS, independent of path return all options
495 resp = GNUNET_REST_create_response (NULL); 722 resp = GNUNET_REST_create_response (NULL);
@@ -519,7 +746,7 @@ rest_credential_process_request(struct GNUNET_REST_RequestHandle *conndata_handl
519 GNUNET_REST_ResultProcessor proc, 746 GNUNET_REST_ResultProcessor proc,
520 void *proc_cls) 747 void *proc_cls)
521{ 748{
522 struct VerifyHandle *handle = GNUNET_new (struct VerifyHandle); 749 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
523 struct GNUNET_REST_RequestHandlerError err; 750 struct GNUNET_REST_RequestHandlerError err;
524 751
525 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 752 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -528,7 +755,8 @@ rest_credential_process_request(struct GNUNET_REST_RequestHandle *conndata_handl
528 handle->rest_handle = conndata_handle; 755 handle->rest_handle = conndata_handle;
529 756
530 static const struct GNUNET_REST_RequestHandler handlers[] = { 757 static const struct GNUNET_REST_RequestHandler handlers[] = {
531 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL, &verify_cred_cont}, 758 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, &verify_cred_cont},
759 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, &issue_cred_cont},
532 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont}, 760 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont},
533 GNUNET_REST_HANDLER_END 761 GNUNET_REST_HANDLER_END
534 }; 762 };