GNUnet  0.10.x
plugin_rest_credential.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012-2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
27 #include "platform.h"
28 #include "gnunet_rest_plugin.h"
30 #include <gnunet_gnsrecord_lib.h>
33 #include <gnunet_rest_lib.h>
34 #include <gnunet_jsonapi_lib.h>
35 #include <gnunet_jsonapi_util.h>
36 #include <jansson.h>
37 
38 #define GNUNET_REST_API_NS_CREDENTIAL "/credential"
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_API_NS_CREDENTIAL_COLLECT "/credential/collect"
45 
46 #define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration"
47 
48 #define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key"
49 
50 #define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO "subject"
51 
52 #define GNUNET_REST_JSONAPI_CREDENTIAL "credential"
53 
54 #define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential"
55 
56 #define GNUNET_REST_JSONAPI_DELEGATIONS "delegations"
57 
58 #define GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR "attribute"
59 
60 #define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_ATTR "credential"
61 
65 struct Plugin
66 {
68 };
69 
71 
73 {
78 
83 
88 
93 
98 
103 
108 
113 
117  json_t *json_root;
118 
123 
127  void *proc_cls;
128 
132  char *issuer_attr;
133 
138 
143 
148 
153 
158 };
159 
160 
166 static void
168 {
170  "Cleaning up\n");
171  if (NULL != handle->json_root)
172  json_decref (handle->json_root);
173 
174  if (NULL != handle->issuer_attr)
175  GNUNET_free (handle->issuer_attr);
176  if (NULL != handle->subject_attr)
177  GNUNET_free (handle->subject_attr);
178  if (NULL != handle->verify_request)
180  if (NULL != handle->credential)
182  if (NULL != handle->id_op)
183  GNUNET_IDENTITY_cancel (handle->id_op);
184  if (NULL != handle->ego_lookup)
186  if (NULL != handle->identity)
188  if (NULL != handle->timeout_task)
189  {
191  }
192  GNUNET_free (handle);
193 }
194 
195 
196 static void
197 do_error (void *cls)
198 {
199  struct RequestHandle *handle = cls;
200  struct MHD_Response *resp;
201 
202  resp = GNUNET_REST_create_response (NULL);
203  handle->proc (handle->proc_cls, resp, handle->response_code);
204  cleanup_handle (handle);
205 }
206 
213 static json_t*
216  delegation_chain_entry)
217 {
218  char *subject;
219  char *issuer;
220  json_t *attr_obj;
221 
223  &delegation_chain_entry->issuer_key);
224  if (NULL == issuer)
225  {
227  "Issuer in delegation malformed\n");
228  return NULL;
229  }
231  &delegation_chain_entry->subject_key);
232  if (NULL == subject)
233  {
235  "Subject in credential malformed\n");
236  GNUNET_free (issuer);
237  return NULL;
238  }
239  attr_obj = json_object ();
240 
241  json_object_set_new (attr_obj, "issuer", json_string (issuer));
242  json_object_set_new (attr_obj, "issuer_attribute",
243  json_string (delegation_chain_entry->issuer_attribute));
244 
245  json_object_set_new (attr_obj, "subject", json_string (subject));
246  if (0 < delegation_chain_entry->subject_attribute_len)
247  {
248  json_object_set_new (attr_obj, "subject_attribute",
249  json_string (
250  delegation_chain_entry->subject_attribute));
251  }
252  GNUNET_free (issuer);
253  GNUNET_free (subject);
254  return attr_obj;
255 }
256 
263 static struct GNUNET_CREDENTIAL_Credential*
265 {
266  struct GNUNET_CREDENTIAL_Credential *cred;
267  json_t *tmp;
268  const char *attribute;
269  const char *signature;
270  char *sig;
271 
272  tmp = json_object_get (res, "attribute");
273  if (0 == json_is_string (tmp))
274  {
275  return NULL;
276  }
277  attribute = json_string_value (tmp);
278  cred = GNUNET_malloc (sizeof(struct GNUNET_CREDENTIAL_Credential)
279  + strlen (attribute));
280  cred->issuer_attribute = attribute;
281  cred->issuer_attribute_len = strlen (attribute);
282  tmp = json_object_get (res, "issuer");
283  if (0 == json_is_string (tmp))
284  {
285  GNUNET_free (cred);
286  return NULL;
287  }
288 
289  GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value (tmp),
290  strlen (json_string_value (tmp)),
291  &cred->issuer_key);
292  tmp = json_object_get (res, "subject");
293  if (0 == json_is_string (tmp))
294  {
295  GNUNET_free (cred);
296  return NULL;
297  }
298  GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value (tmp),
299  strlen (json_string_value (tmp)),
300  &cred->subject_key);
301 
302  tmp = json_object_get (res, "signature");
303  if (0 == json_is_string (tmp))
304  {
305  GNUNET_free (cred);
306  return NULL;
307  }
308  signature = json_string_value (tmp);
309  GNUNET_STRINGS_base64_decode (signature,
310  strlen (signature),
311  (char**) &sig);
312  GNUNET_memcpy (&cred->signature,
313  sig,
314  sizeof(struct GNUNET_CRYPTO_EcdsaSignature));
315  GNUNET_free (sig);
316 
317  tmp = json_object_get (res, "expiration");
318  if (0 == json_is_integer (tmp))
319  {
320  GNUNET_free (cred);
321  return NULL;
322  }
323  cred->expiration.abs_value_us = json_integer_value (tmp);
324  return cred;
325 }
326 
327 
334 static json_t*
336 {
337  char *issuer;
338  char *subject;
339  char *signature;
340  char attribute[cred->issuer_attribute_len + 1];
341  json_t *cred_obj;
342 
344  if (NULL == issuer)
345  {
347  "Issuer in credential malformed\n");
348  return NULL;
349  }
351  if (NULL == subject)
352  {
354  "Subject in credential malformed\n");
355  GNUNET_free (issuer);
356  return NULL;
357  }
358  GNUNET_STRINGS_base64_encode ((char*) &cred->signature,
359  sizeof(struct GNUNET_CRYPTO_EcdsaSignature),
360  &signature);
361  GNUNET_memcpy (attribute,
362  cred->issuer_attribute,
363  cred->issuer_attribute_len);
364  attribute[cred->issuer_attribute_len] = '\0';
365  cred_obj = json_object ();
366  json_object_set_new (cred_obj, "issuer", json_string (issuer));
367  json_object_set_new (cred_obj, "subject", json_string (subject));
368  json_object_set_new (cred_obj, "attribute", json_string (attribute));
369  json_object_set_new (cred_obj, "signature", json_string (signature));
370  json_object_set_new (cred_obj, "expiration", json_integer (
371  cred->expiration.abs_value_us));
372  GNUNET_free (issuer);
373  GNUNET_free (subject);
374  GNUNET_free (signature);
375  return cred_obj;
376 }
377 
378 static void
380  unsigned int d_count,
381  struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
382  unsigned int c_count,
383  struct GNUNET_CREDENTIAL_Credential *cred)
384 {
385  struct RequestHandle *handle = cls;
386  struct MHD_Response *resp;
387  struct GNUNET_JSONAPI_Document *json_document;
388  struct GNUNET_JSONAPI_Resource *json_resource;
389  json_t *cred_obj;
390  json_t *cred_array;
391  char *result;
392  char *issuer;
393  char *id;
394  uint32_t i;
395 
396  handle->verify_request = NULL;
397  if (NULL == cred)
398  {
400  "Verify failed.\n");
401  handle->response_code = MHD_HTTP_NOT_FOUND;
403  return;
404  }
406  if (NULL == issuer)
407  {
409  "Issuer in delegation malformed\n");
410  return;
411  }
412  GNUNET_asprintf (&id,
413  "%s.%s",
414  issuer,
415  handle->issuer_attr);
416  GNUNET_free (issuer);
417  json_document = GNUNET_JSONAPI_document_new ();
418  json_resource = GNUNET_JSONAPI_resource_new (
420  id);
421  GNUNET_free (id);
422  cred_array = json_array ();
423  for (i = 0; i < c_count; i++)
424  {
425  cred_obj = credential_to_json (&cred[i]);
426  json_array_append_new (cred_array, cred_obj);
427  }
428  GNUNET_JSONAPI_resource_add_attr (json_resource,
430  cred_array);
431  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
432  GNUNET_JSONAPI_document_serialize (json_document, &result);
434  "Result %s\n",
435  result);
436  json_decref (cred_array);
437  GNUNET_JSONAPI_document_delete (json_document);
438  resp = GNUNET_REST_create_response (result);
439  GNUNET_free (result);
440  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
441  cleanup_handle (handle);
442 }
443 
444 static void
446  const struct GNUNET_IDENTITY_Ego *ego)
447 {
448  struct RequestHandle *handle = cls;
449  const struct GNUNET_CRYPTO_EcdsaPrivateKey *sub_key;
450 
451  handle->ego_lookup = NULL;
452 
453  if (NULL == ego)
454  {
456  "Subject not found\n");
458  return;
459  }
460  sub_key = GNUNET_IDENTITY_ego_get_private_key (ego);
462  &handle->issuer_key,
463  handle->issuer_attr,
464  sub_key,
466  handle);
467 }
468 
469 
470 
471 static void
473  unsigned int d_count,
474  struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
475  unsigned int c_count,
476  struct GNUNET_CREDENTIAL_Credential *cred)
477 {
478  struct RequestHandle *handle = cls;
479  struct MHD_Response *resp;
480  struct GNUNET_JSONAPI_Document *json_document;
481  struct GNUNET_JSONAPI_Resource *json_resource;
482  json_t *cred_obj;
483  json_t *attr_obj;
484  json_t *cred_array;
485  json_t *attr_array;
486  char *result;
487  char *issuer;
488  char *id;
489  uint32_t i;
490 
491  handle->verify_request = NULL;
492  if (NULL == cred)
493  {
495  "Verify failed.\n");
496  handle->response_code = MHD_HTTP_NOT_FOUND;
498  return;
499  }
501  if (NULL == issuer)
502  {
504  "Issuer in delegation malformed\n");
505  return;
506  }
507  GNUNET_asprintf (&id,
508  "%s.%s",
509  issuer,
510  handle->issuer_attr);
511  GNUNET_free (issuer);
512  json_document = GNUNET_JSONAPI_document_new ();
513  json_resource = GNUNET_JSONAPI_resource_new (
515  id);
516  GNUNET_free (id);
517  attr_array = json_array ();
518  for (i = 0; i < d_count; i++)
519  {
520  attr_obj = attribute_delegation_to_json (&delegation_chain[i]);
521  json_array_append_new (attr_array, attr_obj);
522  }
523  cred_array = json_array ();
524  for (i = 0; i < c_count; i++)
525  {
526  cred_obj = credential_to_json (&cred[i]);
527  json_array_append_new (cred_array, cred_obj);
528  }
529  GNUNET_JSONAPI_resource_add_attr (json_resource,
531  cred_array);
532  GNUNET_JSONAPI_resource_add_attr (json_resource,
534  attr_array);
535  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
536  GNUNET_JSONAPI_document_serialize (json_document, &result);
538  "Result %s\n",
539  result);
540  json_decref (attr_array);
541  json_decref (cred_array);
542  GNUNET_JSONAPI_document_delete (json_document);
543  resp = GNUNET_REST_create_response (result);
544  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
545  GNUNET_free (result);
546  cleanup_handle (handle);
547 }
548 
549 static void
551  const char*url,
552  void *cls)
553 {
554  struct RequestHandle *handle = cls;
555  struct GNUNET_HashCode key;
556  char *tmp;
557  char *entity_attr;
558 
560  "Connecting...\n");
561  handle->credential = GNUNET_CREDENTIAL_connect (cfg);
563  &do_error, handle);
565  "Connected\n");
566  if (NULL == handle->credential)
567  {
569  "Connecting to CREDENTIAL failed\n");
571  return;
572  }
575  &key);
576  if (GNUNET_NO ==
578  &key))
579  {
581  "Missing issuer attribute\n");
583  return;
584  }
585  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
586  &key);
587  entity_attr = GNUNET_strdup (tmp);
588  tmp = strtok (entity_attr, ".");
589  if (NULL == tmp)
590  {
592  "Malformed issuer or attribute\n");
593  GNUNET_free (entity_attr);
595  return;
596  }
597  if (GNUNET_OK !=
599  strlen (tmp),
600  &handle->issuer_key))
601  {
603  "Malformed issuer key\n");
604  GNUNET_free (entity_attr);
606  return;
607  }
608  tmp = strtok (NULL, "."); // Issuer attribute
609  if (NULL == tmp)
610  {
612  "Malformed attribute\n");
613  GNUNET_free (entity_attr);
615  return;
616  }
617  handle->issuer_attr = GNUNET_strdup (tmp);
618  GNUNET_free (entity_attr);
619 
622  &key);
623  if (GNUNET_NO ==
625  &key))
626  {
628  "Missing subject\n");
630  return;
631  }
632  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
633  &key);
634  if (NULL == tmp)
635  {
637  "Malformed subject\n");
639  return;
640  }
641  handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg,
642  tmp,
644  handle);
645 }
646 
647 
648 
649 static void
651  const char*url,
652  void *cls)
653 {
654  struct RequestHandle *handle = cls;
655  struct GNUNET_HashCode key;
656  struct GNUNET_JSONAPI_Document *json_obj;
657  struct GNUNET_JSONAPI_Resource *res;
658  struct GNUNET_CREDENTIAL_Credential *cred;
659  char *tmp;
660  char *entity_attr;
661  int i;
662  uint32_t credential_count;
663  uint32_t resource_count;
664  json_t *cred_json;
665  json_t *data_js;
666  json_error_t err;
667 
669  "Connecting...\n");
670  handle->credential = GNUNET_CREDENTIAL_connect (cfg);
672  &do_error, handle);
674  "Connected\n");
675  if (NULL == handle->credential)
676  {
678  "Connecting to CREDENTIAL failed\n");
680  return;
681  }
684  &key);
685  if (GNUNET_NO ==
687  &key))
688  {
690  "Missing issuer attribute\n");
692  return;
693  }
694  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
695  &key);
696  entity_attr = GNUNET_strdup (tmp);
697  tmp = strtok (entity_attr, ".");
698  if (NULL == tmp)
699  {
701  "Malformed issuer or attribute\n");
702  GNUNET_free (entity_attr);
704  return;
705  }
706  if (GNUNET_OK !=
708  strlen (tmp),
709  &handle->issuer_key))
710  {
712  "Malformed issuer key\n");
713  GNUNET_free (entity_attr);
715  return;
716  }
717  tmp = strtok (NULL, "."); // Issuer attribute
718  if (NULL == tmp)
719  {
721  "Malformed attribute\n");
722  GNUNET_free (entity_attr);
724  return;
725  }
726  handle->issuer_attr = GNUNET_strdup (tmp);
727  GNUNET_free (entity_attr);
728 
731  &key);
732  if (GNUNET_NO ==
734  &key))
735  {
737  "Missing subject key\n");
739  return;
740  }
741  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
742  &key);
743  if (NULL == tmp)
744  {
746  "Malformed subject\n");
748  return;
749  }
750  if (GNUNET_OK !=
752  strlen (tmp),
753  &handle->subject_key))
754  {
756  "Malformed subject key\n");
758  return;
759  }
760 
761  if (0 >= handle->rest_handle->data_size)
762  {
764  "Missing credentials\n");
766  return;
767  }
768 
769  struct GNUNET_JSON_Specification docspec[] = {
770  GNUNET_JSON_spec_jsonapi_document (&json_obj),
772  };
773  char term_data[handle->rest_handle->data_size + 1];
774  term_data[handle->rest_handle->data_size] = '\0';
775  credential_count = 0;
776  GNUNET_memcpy (term_data,
777  handle->rest_handle->data,
778  handle->rest_handle->data_size);
779  data_js = json_loads (term_data,
780  JSON_DECODE_ANY,
781  &err);
782  GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, docspec,
783  NULL, NULL));
784  json_decref (data_js);
785  if (NULL == json_obj)
786  {
788  "Unable to parse JSONAPI Object from %s\n",
789  term_data);
791  return;
792  }
793 
794  resource_count = GNUNET_JSONAPI_document_resource_count (json_obj);
795  GNUNET_assert (1 == resource_count);
796  res = (GNUNET_JSONAPI_document_get_resource (json_obj, 0));
797  if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (res,
799  {
801  "Resource not a credential!\n");
803  "Unable to parse JSONAPI Object from %s\n",
804  term_data);
805  GNUNET_JSONAPI_document_delete (json_obj);
807  return;
808  }
809  cred_json = GNUNET_JSONAPI_resource_read_attr (res,
811 
812  GNUNET_assert (json_is_array (cred_json));
813 
814  credential_count = json_array_size (cred_json);
815 
816  struct GNUNET_CREDENTIAL_Credential credentials[credential_count];
817  for (i = 0; i < credential_count; i++)
818  {
819  cred = json_to_credential (json_array_get (cred_json, i));
820  if (NULL == cred)
821  {
823  "Unable to parse credential!\n");
824  continue;
825  }
826  GNUNET_memcpy (&credentials[i],
827  cred,
828  sizeof(struct GNUNET_CREDENTIAL_Credential));
829  credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute);
830  GNUNET_free (cred);
831  }
832  GNUNET_JSONAPI_document_delete (json_obj);
834  &handle->issuer_key,
835  handle->issuer_attr,
836  &handle->subject_key,
837  credential_count,
838  credentials,
840  handle);
841  for (i = 0; i < credential_count; i++)
842  GNUNET_free ((char*) credentials[i].issuer_attribute);
843 }
844 
845 void
847  struct GNUNET_CREDENTIAL_Credential *cred)
848 {
849  struct MHD_Response *resp;
850  struct GNUNET_JSONAPI_Document *json_document;
851  struct GNUNET_JSONAPI_Resource *json_resource;
852  json_t *cred_obj;
853  char *result;
854  char *issuer;
855  char *subject;
856  char *signature;
857  char *id;
858 
859  GNUNET_assert (NULL != cred);
861  if (NULL == issuer)
862  {
864  "Subject malformed\n");
865  GNUNET_free (issuer);
866  return;
867  }
868  GNUNET_asprintf (&id,
869  "%s.%s",
870  issuer,
871  (char*) &cred[1]);
872  subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
873  if (NULL == subject)
874  {
876  "Subject malformed\n");
877  GNUNET_free (id);
878  GNUNET_free (issuer);
879  return;
880  }
881  GNUNET_STRINGS_base64_encode ((char*) &cred->signature,
882  sizeof(struct GNUNET_CRYPTO_EcdsaSignature),
883  &signature);
884  json_document = GNUNET_JSONAPI_document_new ();
885  json_resource = GNUNET_JSONAPI_resource_new (
887  id);
888  GNUNET_free (id);
889  cred_obj = json_object ();
890  json_object_set_new (cred_obj, "issuer", json_string (issuer));
891  json_object_set_new (cred_obj, "subject", json_string (subject));
892  json_object_set_new (cred_obj, "expiration", json_integer (
893  cred->expiration.abs_value_us));
894  json_object_set_new (cred_obj, "signature", json_string (signature));
895  GNUNET_JSONAPI_resource_add_attr (json_resource,
897  cred_obj);
898  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
899  GNUNET_JSONAPI_document_serialize (json_document, &result);
901  "Result %s\n",
902  result);
903  json_decref (cred_obj);
904  GNUNET_JSONAPI_document_delete (json_document);
905  resp = GNUNET_REST_create_response (result);
906  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
907  GNUNET_free (result);
908  GNUNET_free (signature);
909  GNUNET_free (issuer);
910  GNUNET_free (subject);
911  cleanup_handle (handle);
912 }
913 
914 void
916  struct GNUNET_IDENTITY_Ego *ego,
917  void **ctx,
918  const char *name)
919 {
920  struct RequestHandle *handle = cls;
921  struct GNUNET_TIME_Absolute etime_abs;
922  struct GNUNET_TIME_Relative etime_rel;
924  struct GNUNET_HashCode key;
925  struct GNUNET_CREDENTIAL_Credential *cred;
926  char*expiration_str;
927  char*tmp;
928 
929  handle->id_op = NULL;
930 
931  if (NULL == name)
932  {
934  "Issuer not configured!\n");
936  return;
937  }
938 
940  "Connecting to credential service...\n");
941  handle->credential = GNUNET_CREDENTIAL_connect (cfg);
943  "Connected\n");
944  if (NULL == handle->credential)
945  {
947  "Connecting to CREDENTIAL failed\n");
949  return;
950  }
953  &key);
954  if (GNUNET_NO ==
956  handle->rest_handle->url_param_map,
957  &key))
958  {
960  "Missing expiration\n");
962  return;
963  }
964  expiration_str = GNUNET_CONTAINER_multihashmap_get (
965  handle->rest_handle->url_param_map,
966  &key);
967  if (NULL == expiration_str)
968  {
970  "Expiration malformed\n");
972  return;
973  }
974 
975  if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str,
976  &etime_rel))
977  {
978  etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
979  }
980  else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration_str,
981  &etime_abs))
982  {
984  "Malformed expiration: %s\n", expiration_str);
986  return;
987  }
990  &key);
991  if (GNUNET_NO ==
993  handle->rest_handle->url_param_map,
994  &key))
995  {
997  "Missing issuer attribute\n");
999  return;
1000  }
1002  (handle->rest_handle->url_param_map,
1003  &key));
1006  &key);
1007  if (GNUNET_NO ==
1009  handle->rest_handle->url_param_map,
1010  &key))
1011  {
1013  "Missing subject\n");
1015  return;
1016  }
1018  &key);
1019  if (NULL == tmp)
1020  {
1022  "Malformed subject\n");
1024  return;
1025  }
1026  if (GNUNET_OK !=
1028  strlen (tmp),
1029  &handle->subject_key))
1030  {
1032  "Malformed subject key\n");
1034  return;
1035  }
1036  issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego);
1037  cred = GNUNET_CREDENTIAL_credential_issue (issuer_key,
1038  &handle->subject_key,
1039  handle->issuer_attr,
1040  &etime_abs);
1041  if (NULL == cred)
1042  {
1044  "Failed to create credential\n");
1046  return;
1047  }
1048  send_cred_response (handle, cred);
1049 }
1050 
1051 
1052 static void
1054  const char*url,
1055  void *cls)
1056 {
1057  struct RequestHandle *handle = cls;
1058 
1059  handle->identity = GNUNET_IDENTITY_connect (cfg,
1060  NULL,
1061  NULL);
1062  handle->id_op = GNUNET_IDENTITY_get (handle->identity,
1063  "credential-issuer",
1065  handle);
1067  &do_error,
1068  handle);
1069 }
1070 
1071 static void
1073  const char*url,
1074  void *cls)
1075 {
1076  struct MHD_Response *resp;
1077  struct RequestHandle *handle = cls;
1078 
1079  // For GNS, independent of path return all options
1080  resp = GNUNET_REST_create_response (NULL);
1081  MHD_add_response_header (resp,
1082  "Access-Control-Allow-Methods",
1083  MHD_HTTP_METHOD_GET);
1084  handle->proc (handle->proc_cls,
1085  resp,
1086  MHD_HTTP_OK);
1087  cleanup_handle (handle);
1088 }
1089 
1090 
1091 static void
1093  GNUNET_REST_RequestHandle *conndata_handle,
1095  void *proc_cls)
1096 {
1097  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1099 
1101  handle->proc_cls = proc_cls;
1102  handle->proc = proc;
1103  handle->rest_handle = conndata_handle;
1104 
1105  static const struct GNUNET_REST_RequestHandler handlers[] = {
1106  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CREDENTIAL_VERIFY,
1107  &verify_cred_cont },
1108  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_COLLECT,
1109  &collect_cred_cont },
1110  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE,
1111  &issue_cred_cont },
1112  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont },
1114  };
1115 
1116  if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle,
1117  handlers,
1118  &err,
1119  handle))
1120  {
1121  handle->response_code = err.error_code;
1123  }
1124 }
1125 
1126 
1133 void *
1135 {
1136  static struct Plugin plugin;
1137 
1138  cfg = cls;
1139  struct GNUNET_REST_Plugin *api;
1140 
1141  if (NULL != plugin.cfg)
1142  return NULL; /* can only initialize once! */
1143  memset (&plugin, 0, sizeof(struct Plugin));
1144  plugin.cfg = cfg;
1145  api = GNUNET_new (struct GNUNET_REST_Plugin);
1146  api->cls = &plugin;
1150  _ ("GNS REST API initialized\n"));
1151  return api;
1152 }
1153 
1154 
1161 void *
1163 {
1164  struct GNUNET_REST_Plugin *api = cls;
1165  struct Plugin *plugin = api->cls;
1166 
1167  plugin->cfg = NULL;
1168  GNUNET_free (api);
1170  "GNS REST plugin is finished\n");
1171  return NULL;
1172 }
1173 
1174 /* end of plugin_rest_gns.c */
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:527
uint32_t subject_attribute_len
Length of the attribute.
char * name
Plugin name.
void GNUNET_IDENTITY_cancel(struct GNUNET_IDENTITY_Operation *op)
Cancel an identity operation.
Definition: identity_api.c:818
const char * subject_attribute
The attribute.
void(* GNUNET_REST_ResultProcessor)(void *cls, struct MHD_Response *resp, int status)
Iterator called on obtained result for a REST result.
const char * issuer_attribute
The attribute.
#define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION
void GNUNET_IDENTITY_ego_lookup_cancel(struct GNUNET_IDENTITY_EgoLookup *el)
Abort ego lookup attempt.
Handle for ego lookup.
void GNUNET_CREDENTIAL_request_cancel(struct GNUNET_CREDENTIAL_Request *lr)
Cancel pending verify request.
void get_cred_issuer_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Public key of the subject this credential was issued to.
void * cls
The closure of the plugin.
size_t data_size
The POST data size.
#define GNUNET_REST_API_NS_CREDENTIAL_COLLECT
struct GNUNET_CREDENTIAL_Request * issue_request
Handle to issue request.
#define GNUNET_REST_API_NS_CREDENTIAL_VERIFY
void * libgnunet_plugin_rest_credential_done(void *cls)
Exit point from the plugin.
static char * subject_key
Subject pubkey string.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
int GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:351
struct GNUNET_IDENTITY_Operation * id_op
Handle to identity operation.
static struct GNUNET_CREDENTIAL_Credential * json_to_credential(json_t *res)
JSONAPI resource to Credential.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:555
static void handle_verify_response(void *cls, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *delegation_chain, unsigned int c_count, struct GNUNET_CREDENTIAL_Credential *cred)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct returned by the initialization function of the plugin
int GNUNET_STRINGS_fancy_time_to_absolute(const char *fancy_time, struct GNUNET_TIME_Absolute *atime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:402
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_get(struct GNUNET_IDENTITY_Handle *h, const char *service_name, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Obtain the identity that is currently preferred/default for a service.
Definition: identity_api.c:586
#define GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR
static void rest_credential_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
The public key of the subject.
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
Entry in parser specification for GNUNET_JSON_parse().
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The public key of the issuer.
static void verify_cred_cont(struct GNUNET_REST_RequestHandle *conndata_handle, const char *url, void *cls)
struct GNUNET_CREDENTIAL_Handle * credential
Handle to Credential service.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
void(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer of the credential.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
uint64_t abs_value_us
The actual value.
void send_cred_response(struct RequestHandle *handle, struct GNUNET_CREDENTIAL_Credential *cred)
Handle for an operation with the identity service.
Definition: identity_api.c:39
#define GNUNET_REST_HANDLER_END
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
The request handle.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void GNUNET_CREDENTIAL_disconnect(struct GNUNET_CREDENTIAL_Handle *handle)
Shutdown connection with the CREDENTIAL service.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
Handle for an ego.
Definition: identity.h:245
void * libgnunet_plugin_rest_credential_init(void *cls)
Entry point for the plugin.
static void collect_cred_cont(struct GNUNET_REST_RequestHandle *conndata_handle, const char *url, void *cls)
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:119
struct GNUNET_IDENTITY_Handle * identity
Handle to identity.
int GNUNET_JSON_parse(const json_t *root, struct GNUNET_JSON_Specification *spec, const char **error_json_name, unsigned int *error_line)
Navigate and parse data in a JSON tree.
Definition: json.c:45
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY
Handle for the service.
Definition: identity_api.c:95
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
struct GNUNET_CREDENTIAL_Request * verify_request
Handle to lookup request.
char * name
Plugin name.
struct GNUNET_TIME_Relative timeout
Timeout.
struct GNUNET_CREDENTIAL_Handle * GNUNET_CREDENTIAL_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the CREDENTIAL service.
an ECC signature using ECDSA
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature of this credential.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int result
Global testing status.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:837
Connection to the CREDENTIAL service.
A 512-bit hashcode.
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
int response_code
HTTP response code.
static int res
static char * plugin
Solver plugin name as string.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1921
struct GNUNET_CREDENTIAL_Request * GNUNET_CREDENTIAL_collect(struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls)
Performs attribute collection.
size_t GNUNET_STRINGS_base64_encode(const void *in, size_t len, char **output)
Encode into Base64.
Definition: strings.c:1857
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:332
const char * data
The POST data.
static void issue_cred_cont(struct GNUNET_REST_RequestHandle *conndata_handle, const char *url, void *cls)
Handle to a verify request.
char * subject_attr
The subject attribute.
static char * issuer_key
Issuer pubkey string.
#define GNUNET_REST_API_NS_CREDENTIAL_ISSUE
static void subject_ego_lookup(void *cls, const struct GNUNET_IDENTITY_Ego *ego)
struct GNUNET_TIME_Absolute expiration
Expiration of this credential.
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Public key of the subject this attribute was delegated to.
const char * issuer_attribute
The attribute.
struct GNUNET_IDENTITY_EgoLookup * GNUNET_IDENTITY_ego_lookup(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name, GNUNET_IDENTITY_EgoCallback cb, void *cb_cls)
Lookup an ego by name.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer of the delegation.
static json_t * credential_to_json(struct GNUNET_CREDENTIAL_Credential *cred)
Credential to JSON.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:466
#define GNUNET_REST_JSONAPI_CREDENTIAL
configuration data
Definition: configuration.c:85
Handle for a plugin.
Definition: block.c:37
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
char * issuer_attr
The issuer attribute to verify.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
struct GNUNET_CREDENTIAL_Credential * GNUNET_CREDENTIAL_credential_issue(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, struct GNUNET_CRYPTO_EcdsaPublicKey *subject, const char *attribute, struct GNUNET_TIME_Absolute *expiration)
Issue an attribute to a subject.
json_t * json_root
The root of the received JSON or NULL.
static void do_error(void *cls)
#define GNUNET_REST_JSONAPI_DELEGATIONS
Time for absolute times used by GNUnet, in microseconds.
static json_t * attribute_delegation_to_json(struct GNUNET_CREDENTIAL_Delegation *delegation_chain_entry)
Attribute delegation to JSON.
#define GNUNET_REST_API_NS_CREDENTIAL
#define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO
struct GNUNET_JSON_Specification GNUNET_JSON_spec_end(void)
End of a parser specification.
Definition: json_helper.c:35
struct GNUNET_IDENTITY_EgoLookup * ego_lookup
Handle to ego lookup.
static void handle_collect_response(void *cls, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *delegation_chain, unsigned int c_count, struct GNUNET_CREDENTIAL_Credential *cred)
struct GNUNET_CREDENTIAL_Request * GNUNET_CREDENTIAL_verify(struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, uint32_t credential_count, const struct GNUNET_CREDENTIAL_Credential *credentials, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls)
Performs attribute verification.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint32_t issuer_attribute_len
Length of the attribute.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
char * url
The url.