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 
161 
167 static void
169 {
171  "Cleaning up\n");
172  if (NULL != handle->json_root)
173  json_decref (handle->json_root);
174 
175  if (NULL != handle->issuer_attr)
176  GNUNET_free (handle->issuer_attr);
177  if (NULL != handle->subject_attr)
178  GNUNET_free (handle->subject_attr);
179  if (NULL != handle->verify_request)
181  if (NULL != handle->credential)
183  if (NULL != handle->id_op)
184  GNUNET_IDENTITY_cancel (handle->id_op);
185  if (NULL != handle->ego_lookup)
187  if (NULL != handle->identity)
189  if (NULL != handle->timeout_task)
190  {
192  }
193  GNUNET_free (handle);
194 }
195 
196 
197 static void
198 do_error (void *cls)
199 {
200  struct RequestHandle *handle = cls;
201  struct MHD_Response *resp;
202 
203  resp = GNUNET_REST_create_response (NULL);
204  handle->proc (handle->proc_cls, resp, handle->response_code);
205  cleanup_handle (handle);
206 }
207 
214 static json_t*
216 {
217  char *subject;
218  char *issuer;
219  json_t *attr_obj;
220 
221  issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->issuer_key);
222  if (NULL == issuer)
223  {
225  "Issuer in delegation malformed\n");
226  return NULL;
227  }
228  subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->subject_key);
229  if (NULL == subject)
230  {
232  "Subject in credential malformed\n");
233  GNUNET_free (issuer);
234  return NULL;
235  }
236  attr_obj = json_object ();
237 
238  json_object_set_new (attr_obj, "issuer", json_string (issuer));
239  json_object_set_new (attr_obj, "issuer_attribute",
240  json_string (delegation_chain_entry->issuer_attribute));
241 
242  json_object_set_new (attr_obj, "subject", json_string (subject));
243  if (0 < delegation_chain_entry->subject_attribute_len)
244  {
245  json_object_set_new (attr_obj, "subject_attribute",
246  json_string (delegation_chain_entry->subject_attribute));
247  }
248  GNUNET_free (issuer);
249  GNUNET_free (subject);
250  return attr_obj;
251 }
252 
259 static struct GNUNET_CREDENTIAL_Credential*
261 {
262  struct GNUNET_CREDENTIAL_Credential *cred;
263  json_t *tmp;
264  const char *attribute;
265  const char *signature;
266  char *sig;
267 
268  tmp = json_object_get (res, "attribute");
269  if (0 == json_is_string (tmp))
270  {
271  return NULL;
272  }
273  attribute = json_string_value (tmp);
274  cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential)
275  + strlen (attribute));
276  cred->issuer_attribute = attribute;
277  cred->issuer_attribute_len = strlen (attribute);
278  tmp = json_object_get (res, "issuer");
279  if (0 == json_is_string (tmp))
280  {
281  GNUNET_free (cred);
282  return NULL;
283  }
284 
285  GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp),
286  strlen (json_string_value(tmp)),
287  &cred->issuer_key);
288  tmp = json_object_get (res, "subject");
289  if (0 == json_is_string (tmp))
290  {
291  GNUNET_free (cred);
292  return NULL;
293  }
294  GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp),
295  strlen (json_string_value(tmp)),
296  &cred->subject_key);
297 
298  tmp = json_object_get (res, "signature");
299  if (0 == json_is_string (tmp))
300  {
301  GNUNET_free (cred);
302  return NULL;
303  }
304  signature = json_string_value (tmp);
305  GNUNET_STRINGS_base64_decode (signature,
306  strlen (signature),
307  (char**)&sig);
308  GNUNET_memcpy (&cred->signature,
309  sig,
310  sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
311  GNUNET_free (sig);
312 
313  tmp = json_object_get (res, "expiration");
314  if (0 == json_is_integer (tmp))
315  {
316  GNUNET_free (cred);
317  return NULL;
318  }
319  cred->expiration.abs_value_us = json_integer_value (tmp);
320  return cred;
321 }
322 
323 
330 static json_t*
332 {
333  char *issuer;
334  char *subject;
335  char *signature;
336  char attribute[cred->issuer_attribute_len + 1];
337  json_t *cred_obj;
338 
340  if (NULL == issuer)
341  {
343  "Issuer in credential malformed\n");
344  return NULL;
345  }
347  if (NULL == subject)
348  {
350  "Subject in credential malformed\n");
351  GNUNET_free (issuer);
352  return NULL;
353  }
355  sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
356  &signature);
357  GNUNET_memcpy (attribute,
358  cred->issuer_attribute,
359  cred->issuer_attribute_len);
360  attribute[cred->issuer_attribute_len] = '\0';
361  cred_obj = json_object ();
362  json_object_set_new (cred_obj, "issuer", json_string (issuer));
363  json_object_set_new (cred_obj, "subject", json_string (subject));
364  json_object_set_new (cred_obj, "attribute", json_string (attribute));
365  json_object_set_new (cred_obj, "signature", json_string (signature));
366  json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us));
367  GNUNET_free (issuer);
368  GNUNET_free (subject);
369  GNUNET_free (signature);
370  return cred_obj;
371 }
372 
373 static void
375  unsigned int d_count,
376  struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
377  unsigned int c_count,
378  struct GNUNET_CREDENTIAL_Credential *cred)
379 {
380  struct RequestHandle *handle = cls;
381  struct MHD_Response *resp;
382  struct GNUNET_JSONAPI_Document *json_document;
383  struct GNUNET_JSONAPI_Resource *json_resource;
384  json_t *cred_obj;
385  json_t *cred_array;
386  char *result;
387  char *issuer;
388  char *id;
389  uint32_t i;
390 
391  handle->verify_request = NULL;
392  if (NULL == cred) {
394  "Verify failed.\n");
395  handle->response_code = MHD_HTTP_NOT_FOUND;
397  return;
398  }
400  if (NULL == issuer)
401  {
403  "Issuer in delegation malformed\n");
404  return;
405  }
406  GNUNET_asprintf (&id,
407  "%s.%s",
408  issuer,
409  handle->issuer_attr);
410  GNUNET_free (issuer);
411  json_document = GNUNET_JSONAPI_document_new ();
412  json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
413  id);
414  GNUNET_free (id);
415  cred_array = json_array ();
416  for (i=0;i<c_count;i++)
417  {
418  cred_obj = credential_to_json (&cred[i]);
419  json_array_append_new (cred_array, cred_obj);
420  }
421  GNUNET_JSONAPI_resource_add_attr (json_resource,
423  cred_array);
424  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
425  GNUNET_JSONAPI_document_serialize (json_document, &result);
427  "Result %s\n",
428  result);
429  json_decref (cred_array);
430  GNUNET_JSONAPI_document_delete (json_document);
431  resp = GNUNET_REST_create_response (result);
432  GNUNET_free(result);
433  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
434  cleanup_handle (handle);
435 }
436 
437 static void
439  const struct GNUNET_IDENTITY_Ego *ego)
440 {
441  struct RequestHandle *handle = cls;
442  const struct GNUNET_CRYPTO_EcdsaPrivateKey *sub_key;
443  handle->ego_lookup = NULL;
444 
445  if (NULL == ego)
446  {
448  "Subject not found\n");
450  return;
451  }
452  sub_key = GNUNET_IDENTITY_ego_get_private_key (ego);
454  &handle->issuer_key,
455  handle->issuer_attr,
456  sub_key,
458  handle);
459 }
460 
461 
462 
463 static void
465  unsigned int d_count,
466  struct GNUNET_CREDENTIAL_Delegation *delegation_chain,
467  unsigned int c_count,
468  struct GNUNET_CREDENTIAL_Credential *cred)
469 {
470 
471  struct RequestHandle *handle = cls;
472  struct MHD_Response *resp;
473  struct GNUNET_JSONAPI_Document *json_document;
474  struct GNUNET_JSONAPI_Resource *json_resource;
475  json_t *cred_obj;
476  json_t *attr_obj;
477  json_t *cred_array;
478  json_t *attr_array;
479  char *result;
480  char *issuer;
481  char *id;
482  uint32_t i;
483 
484  handle->verify_request = NULL;
485  if (NULL == cred) {
487  "Verify failed.\n");
488  handle->response_code = MHD_HTTP_NOT_FOUND;
490  return;
491  }
493  if (NULL == issuer)
494  {
496  "Issuer in delegation malformed\n");
497  return;
498  }
499  GNUNET_asprintf (&id,
500  "%s.%s",
501  issuer,
502  handle->issuer_attr);
503  GNUNET_free (issuer);
504  json_document = GNUNET_JSONAPI_document_new ();
505  json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
506  id);
507  GNUNET_free (id);
508  attr_array = json_array ();
509  for (i = 0; i < d_count; i++)
510  {
511  attr_obj = attribute_delegation_to_json (&delegation_chain[i]);
512  json_array_append_new (attr_array, attr_obj);
513  }
514  cred_array = json_array ();
515  for (i=0;i<c_count;i++)
516  {
517  cred_obj = credential_to_json (&cred[i]);
518  json_array_append_new (cred_array, cred_obj);
519  }
520  GNUNET_JSONAPI_resource_add_attr (json_resource,
522  cred_array);
523  GNUNET_JSONAPI_resource_add_attr (json_resource,
525  attr_array);
526  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
527  GNUNET_JSONAPI_document_serialize (json_document, &result);
529  "Result %s\n",
530  result);
531  json_decref (attr_array);
532  json_decref (cred_array);
533  GNUNET_JSONAPI_document_delete (json_document);
534  resp = GNUNET_REST_create_response (result);
535  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
536  GNUNET_free (result);
537  cleanup_handle (handle);
538 }
539 
540 static void
542  const char* url,
543  void *cls)
544 {
545  struct RequestHandle *handle = cls;
546  struct GNUNET_HashCode key;
547  char *tmp;
548  char *entity_attr;
549 
551  "Connecting...\n");
552  handle->credential = GNUNET_CREDENTIAL_connect (cfg);
554  &do_error, handle);
556  "Connected\n");
557  if (NULL == handle->credential)
558  {
560  "Connecting to CREDENTIAL failed\n");
562  return;
563  }
566  &key);
567  if ( GNUNET_NO ==
569  &key) )
570  {
572  "Missing issuer attribute\n");
574  return;
575  }
576  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
577  &key);
578  entity_attr = GNUNET_strdup (tmp);
579  tmp = strtok(entity_attr, ".");
580  if (NULL == tmp)
581  {
583  "Malformed issuer or attribute\n");
584  GNUNET_free (entity_attr);
586  return;
587  }
588  if (GNUNET_OK !=
590  strlen (tmp),
591  &handle->issuer_key))
592  {
594  "Malformed issuer key\n");
595  GNUNET_free (entity_attr);
597  return;
598  }
599  tmp = strtok (NULL, "."); //Issuer attribute
600  if (NULL == tmp)
601  {
603  "Malformed attribute\n");
604  GNUNET_free (entity_attr);
606  return;
607  }
608  handle->issuer_attr = GNUNET_strdup (tmp);
609  GNUNET_free (entity_attr);
610 
613  &key);
614  if ( GNUNET_NO ==
616  &key) )
617  {
619  "Missing subject\n");
621  return;
622  }
623  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
624  &key);
625  if (NULL == tmp)
626  {
628  "Malformed subject\n");
630  return;
631  }
632  handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg,
633  tmp,
635  handle);
636 }
637 
638 
639 
640 static void
642  const char* url,
643  void *cls)
644 {
645  struct RequestHandle *handle = cls;
646  struct GNUNET_HashCode key;
647  struct GNUNET_JSONAPI_Document *json_obj;
648  struct GNUNET_JSONAPI_Resource *res;
649  struct GNUNET_CREDENTIAL_Credential *cred;
650  char *tmp;
651  char *entity_attr;
652  int i;
653  uint32_t credential_count;
654  uint32_t resource_count;
655  json_t *cred_json;
656  json_t *data_js;
657  json_error_t err;
658 
660  "Connecting...\n");
661  handle->credential = GNUNET_CREDENTIAL_connect (cfg);
663  &do_error, handle);
665  "Connected\n");
666  if (NULL == handle->credential)
667  {
669  "Connecting to CREDENTIAL failed\n");
671  return;
672  }
675  &key);
676  if ( GNUNET_NO ==
678  &key) )
679  {
681  "Missing issuer attribute\n");
683  return;
684  }
685  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
686  &key);
687  entity_attr = GNUNET_strdup (tmp);
688  tmp = strtok(entity_attr, ".");
689  if (NULL == tmp)
690  {
692  "Malformed issuer or attribute\n");
693  GNUNET_free (entity_attr);
695  return;
696  }
697  if (GNUNET_OK !=
699  strlen (tmp),
700  &handle->issuer_key))
701  {
703  "Malformed issuer key\n");
704  GNUNET_free (entity_attr);
706  return;
707  }
708  tmp = strtok (NULL, "."); //Issuer attribute
709  if (NULL == tmp)
710  {
712  "Malformed attribute\n");
713  GNUNET_free (entity_attr);
715  return;
716  }
717  handle->issuer_attr = GNUNET_strdup (tmp);
718  GNUNET_free (entity_attr);
719 
722  &key);
723  if ( GNUNET_NO ==
725  &key) )
726  {
728  "Missing subject key\n");
730  return;
731  }
732  tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
733  &key);
734  if (NULL == tmp)
735  {
737  "Malformed subject\n");
739  return;
740  }
741  if (GNUNET_OK !=
743  strlen (tmp),
744  &handle->subject_key)) {
746  "Malformed subject key\n");
748  return;
749  }
750 
751  if (0 >= handle->rest_handle->data_size)
752  {
754  "Missing credentials\n");
756  return;
757  }
758 
759  struct GNUNET_JSON_Specification docspec[] = {
760  GNUNET_JSON_spec_jsonapi_document (&json_obj),
762  };
763  char term_data[handle->rest_handle->data_size+1];
764  term_data[handle->rest_handle->data_size] = '\0';
765  credential_count = 0;
766  GNUNET_memcpy (term_data,
767  handle->rest_handle->data,
768  handle->rest_handle->data_size);
769  data_js = json_loads (term_data,
770  JSON_DECODE_ANY,
771  &err);
772  GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, docspec,
773  NULL, NULL));
774  json_decref (data_js);
775  if (NULL == json_obj)
776  {
778  "Unable to parse JSONAPI Object from %s\n",
779  term_data);
781  return;
782  }
783 
784  resource_count = GNUNET_JSONAPI_document_resource_count(json_obj);
785  GNUNET_assert (1 == resource_count);
786  res = (GNUNET_JSONAPI_document_get_resource(json_obj, 0));
787  if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type(res,
789  {
791  "Resource not a credential!\n");
793  "Unable to parse JSONAPI Object from %s\n",
794  term_data);
795  GNUNET_JSONAPI_document_delete (json_obj);
797  return;
798  }
799  cred_json = GNUNET_JSONAPI_resource_read_attr (res,
801 
802  GNUNET_assert (json_is_array (cred_json));
803 
804  credential_count = json_array_size(cred_json);
805 
806  struct GNUNET_CREDENTIAL_Credential credentials[credential_count];
807  for (i=0;i<credential_count;i++)
808  {
809  cred = json_to_credential (json_array_get (cred_json, i));
810  if (NULL == cred)
811  {
813  "Unable to parse credential!\n");
814  continue;
815  }
816  GNUNET_memcpy (&credentials[i],
817  cred,
818  sizeof (struct GNUNET_CREDENTIAL_Credential));
819  credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute);
820  GNUNET_free (cred);
821  }
822  GNUNET_JSONAPI_document_delete(json_obj);
824  &handle->issuer_key,
825  handle->issuer_attr,
826  &handle->subject_key,
827  credential_count,
828  credentials,
830  handle);
831  for (i=0;i<credential_count;i++)
832  GNUNET_free ((char*)credentials[i].issuer_attribute);
833 
834 }
835 
836 void
838  struct GNUNET_CREDENTIAL_Credential *cred)
839 {
840  struct MHD_Response *resp;
841  struct GNUNET_JSONAPI_Document *json_document;
842  struct GNUNET_JSONAPI_Resource *json_resource;
843  json_t *cred_obj;
844  char *result;
845  char *issuer;
846  char *subject;
847  char *signature;
848  char *id;
849 
850  GNUNET_assert (NULL != cred);
852  if (NULL == issuer)
853  {
855  "Subject malformed\n");
856  GNUNET_free (issuer);
857  return;
858  }
859  GNUNET_asprintf (&id,
860  "%s.%s",
861  issuer,
862  (char*)&cred[1]);
863  subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
864  if (NULL == subject)
865  {
867  "Subject malformed\n");
868  GNUNET_free (id);
869  GNUNET_free (issuer);
870  return;
871  }
872  GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
873  sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
874  &signature);
875  json_document = GNUNET_JSONAPI_document_new ();
876  json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO,
877  id);
878  GNUNET_free (id);
879  cred_obj = json_object();
880  json_object_set_new (cred_obj, "issuer", json_string (issuer));
881  json_object_set_new (cred_obj, "subject", json_string (subject));
882  json_object_set_new (cred_obj, "expiration", json_integer( cred->expiration.abs_value_us));
883  json_object_set_new (cred_obj, "signature", json_string (signature));
884  GNUNET_JSONAPI_resource_add_attr (json_resource,
886  cred_obj);
887  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
888  GNUNET_JSONAPI_document_serialize (json_document, &result);
890  "Result %s\n",
891  result);
892  json_decref (cred_obj);
893  GNUNET_JSONAPI_document_delete (json_document);
894  resp = GNUNET_REST_create_response (result);
895  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
896  GNUNET_free (result);
897  GNUNET_free (signature);
898  GNUNET_free (issuer);
899  GNUNET_free (subject);
900  cleanup_handle (handle);
901 }
902 
903 void
905  struct GNUNET_IDENTITY_Ego *ego,
906  void **ctx,
907  const char *name)
908 {
909  struct RequestHandle *handle = cls;
910  struct GNUNET_TIME_Absolute etime_abs;
911  struct GNUNET_TIME_Relative etime_rel;
913  struct GNUNET_HashCode key;
914  struct GNUNET_CREDENTIAL_Credential *cred;
915  char* expiration_str;
916  char* tmp;
917 
918  handle->id_op = NULL;
919 
920  if (NULL == name)
921  {
923  "Issuer not configured!\n");
925  return;
926  }
927 
929  "Connecting to credential service...\n");
930  handle->credential = GNUNET_CREDENTIAL_connect (cfg);
932  "Connected\n");
933  if (NULL == handle->credential)
934  {
936  "Connecting to CREDENTIAL failed\n");
938  return;
939  }
942  &key);
943  if ( GNUNET_NO ==
945  &key) )
946  {
948  "Missing expiration\n");
950  return;
951  }
953  &key);
954  if ( NULL == expiration_str )
955  {
957  "Expiration malformed\n");
959  return;
960  }
961 
962  if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str,
963  &etime_rel))
964  {
965  etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
966  } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration_str,
967  &etime_abs))
968  {
970  "Malformed expiration: %s\n", expiration_str);
972  return;
973  }
976  &key);
977  if ( GNUNET_NO ==
979  &key) )
980  {
982  "Missing issuer attribute\n");
984  return;
985  }
987  (handle->rest_handle->url_param_map,
988  &key));
991  &key);
992  if ( GNUNET_NO ==
994  &key) )
995  {
997  "Missing subject\n");
999  return;
1000  }
1002  &key);
1003  if (NULL == tmp)
1004  {
1006  "Malformed subject\n");
1008  return;
1009  }
1010  if (GNUNET_OK !=
1012  strlen (tmp),
1013  &handle->subject_key)) {
1015  "Malformed subject key\n");
1017  return;
1018  }
1019  issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego);
1020  cred = GNUNET_CREDENTIAL_credential_issue (issuer_key,
1021  &handle->subject_key,
1022  handle->issuer_attr,
1023  &etime_abs);
1024  if (NULL == cred)
1025  {
1027  "Failed to create credential\n");
1029  return;
1030  }
1031  send_cred_response (handle, cred);
1032 }
1033 
1034 
1035 static void
1037  const char* url,
1038  void *cls)
1039 {
1040  struct RequestHandle *handle = cls;
1041 
1042  handle->identity = GNUNET_IDENTITY_connect (cfg,
1043  NULL,
1044  NULL);
1045  handle->id_op = GNUNET_IDENTITY_get(handle->identity,
1046  "credential-issuer",
1048  handle);
1050  &do_error,
1051  handle);
1052 }
1053 
1054 static void
1056  const char* url,
1057  void *cls)
1058 {
1059  struct MHD_Response *resp;
1060  struct RequestHandle *handle = cls;
1061 
1062  //For GNS, independent of path return all options
1063  resp = GNUNET_REST_create_response (NULL);
1064  MHD_add_response_header (resp,
1065  "Access-Control-Allow-Methods",
1066  MHD_HTTP_METHOD_GET);
1067  handle->proc (handle->proc_cls,
1068  resp,
1069  MHD_HTTP_OK);
1070  cleanup_handle (handle);
1071 }
1072 
1073 
1074 static void
1077  void *proc_cls)
1078 {
1079  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1081 
1083  handle->proc_cls = proc_cls;
1084  handle->proc = proc;
1085  handle->rest_handle = conndata_handle;
1086 
1087  static const struct GNUNET_REST_RequestHandler handlers[] = {
1088  {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, &verify_cred_cont},
1090  {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, &issue_cred_cont},
1091  {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont},
1093  };
1094 
1095  if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle,
1096  handlers,
1097  &err,
1098  handle))
1099  {
1100  handle->response_code = err.error_code;
1102  }
1103 }
1104 
1105 
1112 void *
1114 {
1115  static struct Plugin plugin;
1116  cfg = cls;
1117  struct GNUNET_REST_Plugin *api;
1118 
1119  if (NULL != plugin.cfg)
1120  return NULL; /* can only initialize once! */
1121  memset (&plugin, 0, sizeof (struct Plugin));
1122  plugin.cfg = cfg;
1123  api = GNUNET_new (struct GNUNET_REST_Plugin);
1124  api->cls = &plugin;
1128  _("GNS REST API initialized\n"));
1129  return api;
1130 }
1131 
1132 
1139 void *
1141 {
1142  struct GNUNET_REST_Plugin *api = cls;
1143  struct Plugin *plugin = api->cls;
1144 
1145  plugin->cfg = NULL;
1146  GNUNET_free (api);
1148  "GNS REST plugin is finished\n");
1149  return NULL;
1150 }
1151 
1152 /* 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:528
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:819
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:245
#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:353
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:556
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)
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:408
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:587
#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:81
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:78
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:208
void GNUNET_CREDENTIAL_disconnect(struct GNUNET_CREDENTIAL_Handle *handle)
Shutdown connection with the CREDENTIAL service.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
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:1246
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:114
#define GNUNET_memcpy(dst, src, n)
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:44
#define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY
Handle for the service.
Definition: identity_api.c:96
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:1273
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:838
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
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:2067
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:2004
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:334
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:468
#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:965
char * url
The url.