GNUnet  0.10.x
gnunet-service-credential.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2011-2013 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  */
25 #include "platform.h"
26 
27 #include "gnunet_util_lib.h"
28 
29 #include "credential.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_signatures.h"
35 #include <gnunet_dnsparser_lib.h>
36 #include <gnunet_gns_service.h>
37 #include <gnunet_gnsrecord_lib.h>
40 
41 
42 #define GNUNET_CREDENTIAL_MAX_LENGTH 255
43 
44 struct VerifyRequestHandle;
45 
47 
48 
54 
59 
64 
69 
74 
79 };
80 
89 
94 
98  uint32_t refcount;
99 
104 };
105 
115 
120 
125 
130 
135 
140 };
141 
151 
156 
161 
166 
171 
176 
181 
186 
191 
196 
201 
206 
211 
216 };
217 
218 
227 
232 
237 
242 
247 
252 
257 
262 
267 
272 
277 
282 
286  uint32_t cred_chain_size;
287 
292 
297 
301  uint32_t request_id;
302 
306  uint64_t pending_lookups;
307 
312 
317 };
318 
319 
324 
329 
334 
338 static struct GNUNET_GNS_Handle *gns;
339 
340 
345 
346 static void
348 {
349  struct DelegationQueueEntry *dq_entry;
351 
352  if (NULL == ds_entry)
353  return;
354 
355  for (dq_entry = ds_entry->queue_entries_head; NULL != dq_entry;
356  dq_entry = ds_entry->queue_entries_head)
357  {
359  ds_entry->queue_entries_tail,
360  dq_entry);
361  for (child = dq_entry->set_entries_head; NULL != child;
362  child = dq_entry->set_entries_head)
363  {
365  dq_entry->set_entries_tail,
366  child);
367  cleanup_delegation_set(child);
368  }
369  GNUNET_free(dq_entry);
370  }
371  GNUNET_free_non_null(ds_entry->issuer_key);
376  if (NULL != ds_entry->lookup_request)
377  {
379  ds_entry->lookup_request = NULL;
380  }
381  if (NULL != ds_entry->delegation_chain_entry)
382  {
386  }
387  GNUNET_free(ds_entry);
388 }
389 
390 static void
392 {
393  struct CredentialRecordEntry *cr_entry;
394 
395  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n");
396  if (NULL != vrh->lookup_request)
397  {
399  vrh->lookup_request = NULL;
400  }
403  for (cr_entry = vrh->cred_chain_head; NULL != vrh->cred_chain_head;
404  cr_entry = vrh->cred_chain_head)
405  {
407  vrh->cred_chain_tail,
408  cr_entry);
409  GNUNET_free_non_null(cr_entry->credential);
410  GNUNET_free(cr_entry);
411  }
412  GNUNET_free(vrh);
413 }
414 
415 static void
416 shutdown_task(void *cls)
417 {
418  struct VerifyRequestHandle *vrh;
419 
420  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n");
421 
422  while (NULL != (vrh = vrh_head))
423  {
424  // CREDENTIAL_resolver_lookup_cancel (clh->lookup);
425  GNUNET_CONTAINER_DLL_remove(vrh_head, vrh_tail, vrh);
426  cleanup_handle(vrh);
427  }
428 
429  if (NULL != gns)
430  {
432  gns = NULL;
433  }
434  if (NULL != namestore)
435  {
436  GNUNET_NAMESTORE_disconnect(namestore);
437  namestore = NULL;
438  }
439  if (NULL != statistics)
440  {
442  statistics = NULL;
443  }
444 }
445 
446 
447 static void
449 {
450  struct GNUNET_MQ_Envelope *env;
451  struct DelegationChainResultMessage *rmsg;
452  struct DelegationChainEntry *dce;
453  struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
454  struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
455  struct CredentialRecordEntry *cd;
456  struct CredentialRecordEntry *tmp;
457  size_t size;
458 
459  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
460  dce = vrh->delegation_chain_head;
461  for (uint32_t i = 0; i < vrh->delegation_chain_size; i++)
462  {
463  dd[i].issuer_key = dce->issuer_key;
464  dd[i].subject_key = dce->subject_key;
465  dd[i].issuer_attribute = dce->issuer_attribute;
466  dd[i].issuer_attribute_len = strlen(dce->issuer_attribute) + 1;
467  dd[i].subject_attribute_len = 0;
468  dd[i].subject_attribute = NULL;
469  if (NULL != dce->subject_attribute)
470  {
472  dd[i].subject_attribute_len = strlen(dce->subject_attribute) + 1;
473  }
474  dce = dce->next;
475  }
476 
480  for (cd = vrh->cred_chain_head; NULL != cd;)
481  {
482  if (cd->refcount > 0)
483  {
484  cd = cd->next;
485  continue;
486  }
487  tmp = cd;
488  cd = cd->next;
489  GNUNET_CONTAINER_DLL_remove(vrh->cred_chain_head,
490  vrh->cred_chain_tail,
491  tmp);
492  GNUNET_free(tmp->credential);
493  GNUNET_free(tmp);
494  vrh->cred_chain_size--;
495  }
496 
501  cd = vrh->cred_chain_head;
502  for (uint32_t i = 0; i < vrh->cred_chain_size; i++)
503  {
504  cred[i].issuer_key = cd->credential->issuer_key;
505  cred[i].subject_key = cd->credential->subject_key;
506  cred[i].issuer_attribute_len
507  = strlen(cd->credential->issuer_attribute) + 1;
509  cred[i].expiration = cd->credential->expiration;
510  cred[i].signature = cd->credential->signature;
511  cd = cd->next;
512  }
513  size
514  = GNUNET_CREDENTIAL_delegation_chain_get_size(vrh->delegation_chain_size,
515  dd,
516  vrh->cred_chain_size,
517  cred);
518  env = GNUNET_MQ_msg_extra(rmsg,
519  size,
521  // Assign id so that client can find associated request
522  rmsg->id = vrh->request_id;
523  rmsg->d_count = htonl(vrh->delegation_chain_size);
524  rmsg->c_count = htonl(vrh->cred_chain_size);
525 
526  if (0 < vrh->cred_chain_size)
527  rmsg->cred_found = htonl(GNUNET_YES);
528  else
529  rmsg->cred_found = htonl(GNUNET_NO);
530 
532  -1
533  != GNUNET_CREDENTIAL_delegation_chain_serialize(vrh->delegation_chain_size,
534  dd,
535  vrh->cred_chain_size,
536  cred,
537  size,
538  (char *)&rmsg[1]));
539 
540  GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(vrh->client), env);
541  GNUNET_CONTAINER_DLL_remove(vrh_head, vrh_tail, vrh);
542  cleanup_handle(vrh);
543 
544  GNUNET_STATISTICS_update(statistics,
545  "Completed verifications",
546  1,
547  GNUNET_NO);
548 }
549 
550 
551 static void
553  uint32_t rd_count,
554  const struct GNUNET_GNSRECORD_Data *rd)
555 {
556  struct VerifyRequestHandle *vrh;
557  const struct GNUNET_CREDENTIAL_DelegationRecord *sets;
558  struct CredentialRecordEntry *cred_pointer;
559  struct DelegationSetQueueEntry *current_set;
560  struct DelegationSetQueueEntry *ds_entry;
561  struct DelegationSetQueueEntry *tmp_set;
562  struct DelegationQueueEntry *dq_entry;
563  char *expanded_attr;
564  char *lookup_attribute;
565 
566 
567  current_set = cls;
568  current_set->lookup_request = NULL;
569  vrh = current_set->handle;
570  vrh->pending_lookups--;
571  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got %d attrs\n", rd_count);
572 
573  // Each OR
574  for (uint32_t i = 0; i < rd_count; i++)
575  {
576  if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
577  continue;
578 
579  sets = rd[i].data;
580  struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets->set_count)];
581  GNUNET_log(
583  "Found new attribute delegation with %d sets. Creating new Job...\n",
584  ntohl(sets->set_count));
585 
586  if (GNUNET_OK
588  GNUNET_ntohll(sets->data_size),
589  (const char *)&sets[1],
590  ntohl(sets->set_count),
591  set))
592  {
593  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
594  continue;
595  }
596  dq_entry = GNUNET_new(struct DelegationQueueEntry);
597  dq_entry->required_solutions = ntohl(sets->set_count);
598  dq_entry->parent_set = current_set;
600  current_set->queue_entries_tail,
601  dq_entry);
602  // Each AND
603  for (uint32_t j = 0; j < ntohl(sets->set_count); j++)
604  {
605  ds_entry = GNUNET_new(struct DelegationSetQueueEntry);
606  if (NULL != current_set->attr_trailer)
607  {
608  if (0 == set[j].subject_attribute_len)
609  {
610  GNUNET_asprintf(&expanded_attr, "%s", current_set->attr_trailer);
611  }
612  else
613  {
614  GNUNET_asprintf(&expanded_attr,
615  "%s.%s",
616  set[j].subject_attribute,
617  current_set->attr_trailer);
618  }
619  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
620  ds_entry->unresolved_attribute_delegation = expanded_attr;
621  }
622  else
623  {
624  if (0 != set[j].subject_attribute_len)
625  {
627  "Not Expanding %s\n",
628  set[j].subject_attribute);
630  = GNUNET_strdup(set[j].subject_attribute);
631  }
632  }
633 
634  // Add a credential chain entry
635  ds_entry->delegation_chain_entry
637  ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
639  GNUNET_memcpy(ds_entry->issuer_key,
640  &set[j].subject_key,
641  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
642  if (0 < set[j].subject_attribute_len)
645  ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
647  = GNUNET_strdup(current_set->lookup_attribute);
648 
649  ds_entry->parent_queue_entry = dq_entry; // current_delegation;
651  dq_entry->set_entries_tail,
652  ds_entry);
653 
654  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Checking for cred match\n");
658  for (cred_pointer = vrh->cred_chain_head; cred_pointer != NULL;
659  cred_pointer = cred_pointer->next)
660  {
661  if (0
662  != GNUNET_memcmp(&set->subject_key,
663  &cred_pointer->credential->issuer_key))
664  continue;
666  "Checking if %s matches %s\n",
668  cred_pointer->credential->issuer_attribute);
669 
670  if (0
671  != strcmp(ds_entry->unresolved_attribute_delegation,
672  cred_pointer->credential->issuer_attribute))
673  continue;
674 
675  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
676  cred_pointer->refcount++;
677  // Backtrack
678  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
679  tmp_set = tmp_set->parent_queue_entry->parent_set)
680  {
682  if (NULL != tmp_set->delegation_chain_entry)
683  {
684  vrh->delegation_chain_size++;
687  tmp_set->delegation_chain_entry);
688  }
689  if (0 < tmp_set->parent_queue_entry->required_solutions)
690  break;
691  }
692 
693  if (NULL == tmp_set->parent_queue_entry)
694  {
695  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "All solutions found\n");
696  // Found match
698  return;
699  }
700  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Not all solutions found yet.\n");
701  continue;
702  }
704  "Building new lookup request from %s\n",
706  // Continue with backward resolution
707  char
708  issuer_attribute_name[strlen(ds_entry->unresolved_attribute_delegation)
709  + 1];
710  strcpy(issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
711  char *next_attr = strtok(issuer_attribute_name, ".");
712  if (NULL == next_attr)
713  {
715  "Failed to parse next attribute\n");
716  continue;
717  }
718  GNUNET_asprintf(&lookup_attribute, "%s", next_attr);
719  GNUNET_asprintf(&ds_entry->lookup_attribute, "%s", next_attr);
720  if (strlen(next_attr)
721  == strlen(ds_entry->unresolved_attribute_delegation))
722  {
723  ds_entry->attr_trailer = NULL;
724  }
725  else
726  {
727  next_attr += strlen(next_attr) + 1;
728  ds_entry->attr_trailer = GNUNET_strdup(next_attr);
729  }
730 
732  "Looking up %s\n",
733  ds_entry->lookup_attribute);
734  if (NULL != ds_entry->attr_trailer)
736  "%s still to go...\n",
737  ds_entry->attr_trailer);
738 
739  vrh->pending_lookups++;
740  ds_entry->handle = vrh;
741  ds_entry->lookup_request
742  = GNUNET_GNS_lookup(gns,
743  lookup_attribute,
744  ds_entry->issuer_key, // issuer_key,
748  ds_entry);
749  GNUNET_free(lookup_attribute);
750  }
751  }
752 
753  if (0 == vrh->pending_lookups)
754  {
755  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
757  return;
758  }
759 }
760 
761 
767 static void
769 {
770  struct VerifyRequestHandle *vrh = cls;
771  struct DelegationSetQueueEntry *ds_entry;
772  struct CredentialRecordEntry *cr_entry;
773 
774  vrh->lookup_request = NULL;
775 
776  if (0 == vrh->cred_chain_size)
777  {
778  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No credentials found\n");
780  return;
781  }
782 
783  for (cr_entry = vrh->cred_chain_head; cr_entry != NULL;
784  cr_entry = cr_entry->next)
785  {
786  if (0
787  != GNUNET_memcmp(&cr_entry->credential->issuer_key,
788  &vrh->issuer_key))
789  continue;
790  if (0
791  != strcmp(cr_entry->credential->issuer_attribute,
792  vrh->issuer_attribute))
793  continue;
794  cr_entry->refcount++;
795  // Found match prematurely
797  return;
798  }
799 
804  char issuer_attribute_name[strlen(vrh->issuer_attribute) + 1];
805  strcpy(issuer_attribute_name, vrh->issuer_attribute);
807  "Looking up %s\n",
808  issuer_attribute_name);
809  ds_entry = GNUNET_new(struct DelegationSetQueueEntry);
811  GNUNET_memcpy(ds_entry->issuer_key,
812  &vrh->issuer_key,
813  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
815  ds_entry->handle = vrh;
817  vrh->root_set = ds_entry;
818  vrh->pending_lookups = 1;
819  // Start with backward resolution
820  ds_entry->lookup_request = GNUNET_GNS_lookup(gns,
821  issuer_attribute_name,
822  &vrh->issuer_key, // issuer_key,
826  ds_entry);
827 }
828 
829 static int
830 check_verify(void *cls, const struct VerifyMessage *v_msg)
831 {
832  size_t msg_size;
833  const char *attr;
834 
835  msg_size = ntohs(v_msg->header.size);
836  if (msg_size < sizeof(struct VerifyMessage))
837  {
838  GNUNET_break(0);
839  return GNUNET_SYSERR;
840  }
842  {
843  GNUNET_break(0);
844  return GNUNET_SYSERR;
845  }
846  attr = (const char *)&v_msg[1];
847 
848  if (strlen(attr) > GNUNET_CREDENTIAL_MAX_LENGTH)
849  {
850  GNUNET_break(0);
851  return GNUNET_SYSERR;
852  }
853  return GNUNET_OK;
854 }
855 
856 static void
857 handle_verify(void *cls, const struct VerifyMessage *v_msg)
858 {
859  struct VerifyRequestHandle *vrh;
860  struct GNUNET_SERVICE_Client *client = cls;
861  struct CredentialRecordEntry *cr_entry;
862  uint32_t credentials_count;
863  uint32_t credential_data_size;
864  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
866  char *attrptr = attr;
867  char *credential_data;
868  const char *utf_in;
869 
870  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
871  utf_in = (const char *)&v_msg[1];
872  GNUNET_STRINGS_utf8_tolower(utf_in, attrptr);
873  GNUNET_memcpy(issuer_attribute, attr, ntohs(v_msg->issuer_attribute_len));
874  issuer_attribute[ntohs(v_msg->issuer_attribute_len)] = '\0';
875  vrh = GNUNET_new(struct VerifyRequestHandle);
876  GNUNET_CONTAINER_DLL_insert(vrh_head, vrh_tail, vrh);
877  vrh->client = client;
878  vrh->request_id = v_msg->id;
879  vrh->issuer_key = v_msg->issuer_key;
880  vrh->subject_key = v_msg->subject_key;
881  vrh->issuer_attribute = GNUNET_strdup(issuer_attribute);
883  if (0 == strlen(issuer_attribute))
884  {
885  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
887  return;
888  }
893  credentials_count = ntohl(v_msg->c_count);
894  credential_data_size = ntohs(v_msg->header.size)
895  - sizeof(struct VerifyMessage)
896  - ntohs(v_msg->issuer_attribute_len) - 1;
897  struct GNUNET_CREDENTIAL_Credential credentials[credentials_count];
898  memset(credentials,
899  0,
900  sizeof(struct GNUNET_CREDENTIAL_Credential) * credentials_count);
901  credential_data = (char *)&v_msg[1] + ntohs(v_msg->issuer_attribute_len) + 1;
902  if (GNUNET_OK
903  != GNUNET_CREDENTIAL_credentials_deserialize(credential_data_size,
904  credential_data,
905  credentials_count,
906  credentials))
907  {
908  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize credentials!\n");
910  return;
911  }
912 
913  for (uint32_t i = 0; i < credentials_count; i++)
914  {
915  cr_entry = GNUNET_new(struct CredentialRecordEntry);
916  cr_entry->credential
918  + credentials[i].issuer_attribute_len + 1);
919  GNUNET_memcpy(cr_entry->credential,
920  &credentials[i],
921  sizeof(struct GNUNET_CREDENTIAL_Credential));
922  GNUNET_memcpy(&cr_entry->credential[1],
923  credentials[i].issuer_attribute,
924  credentials[i].issuer_attribute_len);
926  = credentials[i].issuer_attribute_len;
927  cr_entry->credential->issuer_attribute = (char *)&cr_entry->credential[1];
929  vrh->cred_chain_tail,
930  cr_entry);
931  vrh->cred_chain_size++;
932  }
933 
935 }
936 
937 static void
939 {
940  struct VerifyRequestHandle *vrh = cls;
941 
943  "Got disconnected from namestore database.\n");
944  vrh->cred_collection_iter = NULL;
946 }
947 
948 static void
949 collect_next(void *cls)
950 {
951  struct VerifyRequestHandle *vrh = cls;
952 
953  vrh->collect_next_task = NULL;
954  GNUNET_assert(NULL != vrh->cred_collection_iter);
956 }
957 
958 
959 static void
961  const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
962  const char *label,
963  unsigned int rd_count,
964  const struct GNUNET_GNSRECORD_Data *rd)
965 {
966  struct VerifyRequestHandle *vrh = cls;
967  struct GNUNET_CREDENTIAL_Credential *crd;
968  struct CredentialRecordEntry *cr_entry;
969  int cred_record_count;
970 
971  cred_record_count = 0;
972  for (uint32_t i = 0; i < rd_count; i++)
973  {
974  if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
975  continue;
976  cred_record_count++;
977  crd
979  if (NULL == crd)
980  {
981  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Invalid credential found\n");
982  continue;
983  }
984  cr_entry = GNUNET_new(struct CredentialRecordEntry);
985  cr_entry->credential = crd;
987  vrh->cred_chain_tail,
988  cr_entry);
989  vrh->cred_chain_size++;
990  }
992 }
993 
994 static void
996 {
997  struct VerifyRequestHandle *vrh = cls;
998 
999  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Done collecting credentials.\n");
1000  vrh->cred_collection_iter = NULL;
1002 }
1003 
1004 static void
1005 handle_collect(void *cls, const struct CollectMessage *c_msg)
1006 {
1007  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
1009  struct VerifyRequestHandle *vrh;
1010  struct GNUNET_SERVICE_Client *client = cls;
1011  char *attrptr = attr;
1012  const char *utf_in;
1013 
1014  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
1015 
1016  utf_in = (const char *)&c_msg[1];
1017  GNUNET_STRINGS_utf8_tolower(utf_in, attrptr);
1018 
1019  GNUNET_memcpy(issuer_attribute, attr, ntohs(c_msg->issuer_attribute_len));
1020  issuer_attribute[ntohs(c_msg->issuer_attribute_len)] = '\0';
1021  vrh = GNUNET_new(struct VerifyRequestHandle);
1022  GNUNET_CONTAINER_DLL_insert(vrh_head, vrh_tail, vrh);
1023  vrh->client = client;
1024  vrh->request_id = c_msg->id;
1025  vrh->issuer_key = c_msg->issuer_key;
1027  vrh->issuer_attribute = GNUNET_strdup(issuer_attribute);
1028 
1029  if (0 == strlen(issuer_attribute))
1030  {
1031  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1032  send_lookup_response(vrh);
1033  return;
1034  }
1035  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Getting credentials for subject\n");
1040  namestore,
1041  &c_msg->subject_key,
1043  vrh,
1045  vrh,
1047  vrh);
1049 }
1050 
1051 
1052 static int
1053 check_collect(void *cls, const struct CollectMessage *c_msg)
1054 {
1055  size_t msg_size;
1056  const char *attr;
1057 
1058  msg_size = ntohs(c_msg->header.size);
1059  if (msg_size < sizeof(struct CollectMessage))
1060  {
1061  GNUNET_break(0);
1062  return GNUNET_SYSERR;
1063  }
1065  {
1066  GNUNET_break(0);
1067  return GNUNET_SYSERR;
1068  }
1069  attr = (const char *)&c_msg[1];
1070 
1071  if (('\0' != attr[msg_size - sizeof(struct CollectMessage) - 1])
1072  || (strlen(attr) > GNUNET_CREDENTIAL_MAX_LENGTH))
1073  {
1074  GNUNET_break(0);
1075  return GNUNET_SYSERR;
1076  }
1077  return GNUNET_OK;
1078 }
1079 
1080 static void
1082  struct GNUNET_SERVICE_Client *client,
1083  void *app_ctx)
1084 {
1085  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1086 }
1087 
1088 static void *
1090  struct GNUNET_SERVICE_Client *client,
1091  struct GNUNET_MQ_Handle *mq)
1092 {
1093  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1094  return client;
1095 }
1096 
1104 static void
1105 run(void *cls,
1106  const struct GNUNET_CONFIGURATION_Handle *c,
1107  struct GNUNET_SERVICE_Handle *handle)
1108 {
1109  gns = GNUNET_GNS_connect(c);
1110  if (NULL == gns)
1111  {
1112  fprintf(stderr, _("Failed to connect to GNS\n"));
1113  }
1114  namestore = GNUNET_NAMESTORE_connect(c);
1115  if (NULL == namestore)
1116  {
1117  fprintf(stderr, _("Failed to connect to namestore\n"));
1118  }
1119 
1120  statistics = GNUNET_STATISTICS_create("credential", c);
1122 }
1123 
1124 
1129  "credential",
1131  &run,
1134  NULL,
1137  struct VerifyMessage,
1138  NULL),
1141  struct CollectMessage,
1142  NULL),
1144 
1145 /* end of gnunet-service-credential.c */
uint64_t pending_lookups
Pending lookups.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct VerifyRequestHandle * next
We keep these in a DLL.
Connection to the GNS service.
Definition: gns_api.h:35
Message from client to Credential service to verify attributes.
Definition: credential.h:68
uint32_t subject_attribute_len
Length of the attribute.
const char * subject_attribute
The attribute.
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:115
const char * issuer_attribute
The attribute.
struct DelegationQueueEntry * parent
Parent attribute delegation.
struct DelegationChainEntry * prev
DLL.
struct DelegationChainEntry * delegation_chain_tail
Children of this attribute.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Public key of the subject this credential was issued to.
Handle to a service.
Definition: service.c:114
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
The subject.
struct VerifyRequestHandle * prev
We keep these in a DLL.
int GNUNET_CREDENTIAL_credentials_deserialize(size_t len, const char *src, unsigned int c_count, struct GNUNET_CREDENTIAL_Credential *cd)
Deserialize the given destination.
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: credential.h:92
static int collect
Collect mode.
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2424
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:97
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1284
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
Starts a new zone iteration (used to periodically PUT all of our records into our DHT)...
Message from CREDENTIAL service to client: new results.
Definition: credential.h:106
#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
char * issuer_attribute
Issuer attribute.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void handle_verify(void *cls, const struct VerifyMessage *v_msg)
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
struct DelegationChainEntry * delegation_chain_entry
The delegation chain entry.
Handle to a lookup request.
Definition: gns_api.c:42
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: credential.h:49
API to serialize and deserialize delegation chains and credentials.
static void delegation_chain_resolution_start(void *cls)
Result from GNS lookup.
IPC messages between CREDENTIAL API and CREDENTIAL service.
#define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT
char * issuer_attribute
Issuer attribute delegated to.
Message from client to Credential service to collect credentials.
Definition: credential.h:35
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static void shutdown_task(void *cls)
char * issuer_attribute
The issued attribute.
int GNUNET_CREDENTIAL_delegation_set_deserialize(size_t len, const char *src, unsigned int d_count, struct GNUNET_CREDENTIAL_DelegationSet *dsr)
Deserialize the given destination.
DLL for delegation sets Used for AND delegation set.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
#define GNUNET_NO
Definition: gnunet_common.h:78
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Subject public key.
Definition: credential.h:77
static struct VerifyRequestHandle * vrh_head
Head of the DLL.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it, uint64_t limit)
Calls the record processor specified in GNUNET_NAMESTORE_zone_iteration_start for the next record...
Private ECC key encoded for transmission.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer of the credential.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct DelegationSetQueueEntry * next
DLL.
Handle for the service.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
uint32_t cred_chain_size
Credential DLL size.
struct GNUNET_GNS_LookupRequest * lookup_request
GNS handle.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct DelegationQueueEntry * queue_entries_head
Queue entries of this set.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_GNSRECORD_TYPE_CREDENTIAL
65546 reserved
static struct GNUNET_NAMESTORE_Handle * namestore
Handle to namestore service.
Handle to a client that is connected to a service.
Definition: service.c:246
struct DelegationChainEntry * next
DLL.
uint32_t request_id
request id
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Issuer public key.
struct CredentialRecordEntry * next
DLL.
struct DelegationQueueEntry * current_delegation
Current Delegation Pointer.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
Handle for a zone iterator operation.
static int verify
Verify mode.
static void handle_collect(void *cls, const struct CollectMessage *c_msg)
const void * data
Binary value stored in the DNS record.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
Connection to the NAMESTORE service.
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:1264
struct DelegationSetQueueEntry * prev
DLL.
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:282
GNUNET_SERVICE_MAIN("credential", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(verify, GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY, struct VerifyMessage, NULL), GNUNET_MQ_hd_var_size(collect, GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT, struct CollectMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
uint32_t issuer_attribute_len
Length of the attribute.
static struct VerifyRequestHandle * vrh_tail
Tail of the DLL.
struct GNUNET_NAMESTORE_ZoneIterator * cred_collection_iter
Credential iterator.
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY.
Definition: credential.h:72
struct GNUNET_SCHEDULER_Task * collect_next_task
Collect task.
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature of this credential.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_GNS_LookupRequest * lookup_request
GNS handle.
struct VerifyRequestHandle * handle
Verify handle.
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:260
static void send_lookup_response(struct VerifyRequestHandle *vrh)
static void collect_next(void *cls)
struct DelegationChainEntry * delegation_chain_head
Children of this attribute.
uint32_t refcount
Number of references in delegation chains.
struct GNUNET_CREDENTIAL_Credential * GNUNET_CREDENTIAL_credential_deserialize(const char *data, size_t data_size)
struct CredentialRecordEntry * cred_chain_head
Credential DLL.
static int check_collect(void *cls, const struct CollectMessage *c_msg)
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:241
Handle to a lookup operation from api.
uint32_t delegation_chain_size
Size of delegation tree.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:59
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY.
Definition: credential.h:39
struct DelegationQueueEntry * queue_entries_tail
Queue entries of this set.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
char * attr_trailer
Trailing attribute context.
struct DelegationSetQueueEntry * set_entries_head
Sets under this Queue.
struct GNUNET_CRYPTO_EcdsaPrivateKey subject_key
Subject public key.
Definition: credential.h:44
Handle to a message queue.
Definition: mq.c:84
uint32_t c_count
Number of credentials.
Definition: credential.h:87
struct GNUNET_TIME_Absolute expiration
Expiration of this credential.
struct CredentialRecordEntry * cred_chain_tail
Credential DLL.
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Public key of the subject this attribute was delegated to.
const char * issuer_attribute
The attribute.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer of the delegation.
static struct GNUNET_OS_Process * child
The child process we spawn.
static void handle_cred_collection_finished_cb(void *cls)
struct CredentialRecordEntry * prev
DLL.
configuration data
Definition: configuration.c:83
ssize_t GNUNET_CREDENTIAL_delegation_chain_serialize(unsigned int d_count, const struct GNUNET_CREDENTIAL_Delegation *dd, unsigned int c_count, const struct GNUNET_CREDENTIAL_Credential *cd, size_t dest_size, char *dest)
Serizalize the given delegation chain entries and credential.
#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *handle)
Process Credential requests.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
struct DelegationQueueEntry * next
DLL.
#define GNUNET_GNSRECORD_TYPE_ATTRIBUTE
Record type for reverse lookups.
uint32_t cred_found
Indicates if credential has been found at all.
Definition: credential.h:120
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
static struct GNUNET_GNS_Handle * gns
Handle to GNS service.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Subject public key.
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:306
struct GNUNET_CRYPTO_EcdsaPublicKey * issuer_key
Issuer key.
struct GNUNET_SERVICE_Client * client
Handle to the requesting client.
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: credential.h:54
#define GNUNET_YES
Definition: gnunet_common.h:77
static void backward_resolution(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
char * subject_attribute
The delegated attribute.
Defaults, look in cache, then in DHT.
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Public key of the subject this attribute was delegated to.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
static void cleanup_delegation_set(struct DelegationSetQueueEntry *ds_entry)
uint32_t required_solutions
Required solutions.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: credential.h:82
static void handle_cred_collection_error_cb(void *cls)
#define GNUNET_CREDENTIAL_MAX_LENGTH
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS.
Definition: gns_api.c:334
uint32_t data
The data value.
static void handle_cred_collection_cb(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
static void cleanup_handle(struct VerifyRequestHandle *vrh)
static size_t data_size
Number of bytes in data.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer.
The attribute delegation record.
size_t GNUNET_CREDENTIAL_delegation_chain_get_size(unsigned int d_count, const struct GNUNET_CREDENTIAL_Delegation *dd, unsigned int c_count, const struct GNUNET_CREDENTIAL_Credential *cd)
Calculate how many bytes we will need to serialize the given delegation chain and credential...
static int check_verify(void *cls, const struct VerifyMessage *v_msg)
struct GNUNET_CREDENTIAL_Credential * credential
Payload.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2234
struct DelegationQueueEntry * parent_queue_entry
Parent QueueEntry.
struct DelegationSetQueueEntry * root_set
Root Delegation Set.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
uint32_t d_count
The number of delegations in the response.
Definition: credential.h:125
#define GNUNET_malloc(size)
Wrapper around malloc.
struct DelegationSetQueueEntry * set_entries_tail
Sets under this Queue.
The attribute delegation record.
char * unresolved_attribute_delegation
Still to resolve delegation as string.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
uint32_t c_count
The number of credentials in the response.
Definition: credential.h:130
#define GNUNET_free(ptr)
Wrapper around free.
struct DelegationQueueEntry * prev
DLL.
DLL used for delegations Used for OR delegations.
struct DelegationSetQueueEntry * parent_set
Parent set.
void GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:552
uint32_t issuer_attribute_len
Length of the attribute.
char * lookup_attribute
The current attribute to look up.