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 
50 {
55 
60 
65 
70 
75 
80 };
81 
86 {
91 
96 
100  uint32_t refcount;
101 
106 };
107 
113 {
118 
123 
128 
133 
138 
143 };
144 
150 {
155 
160 
165 
170 
175 
180 
185 
190 
195 
200 
205 
210 
215 
220 };
221 
222 
227 {
232 
237 
242 
247 
252 
257 
262 
267 
272 
277 
282 
287 
291  uint32_t cred_chain_size;
292 
297 
302 
306  uint32_t request_id;
307 
311  uint64_t pending_lookups;
312 
317 
322 };
323 
324 
329 
334 
339 
343 static struct GNUNET_GNS_Handle *gns;
344 
345 
350 
351 static void
353 {
354  struct DelegationQueueEntry *dq_entry;
356 
357  if (NULL == ds_entry)
358  return;
359 
360  for (dq_entry = ds_entry->queue_entries_head; NULL != dq_entry;
361  dq_entry = ds_entry->queue_entries_head)
362  {
364  ds_entry->queue_entries_tail,
365  dq_entry);
366  for (child = dq_entry->set_entries_head; NULL != child;
367  child = dq_entry->set_entries_head)
368  {
370  dq_entry->set_entries_tail,
371  child);
372  cleanup_delegation_set (child);
373  }
374  GNUNET_free (dq_entry);
375  }
376  GNUNET_free_non_null (ds_entry->issuer_key);
381  if (NULL != ds_entry->lookup_request)
382  {
384  ds_entry->lookup_request = NULL;
385  }
386  if (NULL != ds_entry->delegation_chain_entry)
387  {
391  }
392  GNUNET_free (ds_entry);
393 }
394 
395 static void
397 {
398  struct CredentialRecordEntry *cr_entry;
399 
400  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n");
401  if (NULL != vrh->lookup_request)
402  {
404  vrh->lookup_request = NULL;
405  }
408  for (cr_entry = vrh->cred_chain_head; NULL != vrh->cred_chain_head;
409  cr_entry = vrh->cred_chain_head)
410  {
412  vrh->cred_chain_tail,
413  cr_entry);
414  GNUNET_free_non_null (cr_entry->credential);
415  GNUNET_free (cr_entry);
416  }
417  GNUNET_free (vrh);
418 }
419 
420 static void
421 shutdown_task (void *cls)
422 {
423  struct VerifyRequestHandle *vrh;
424 
425  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n");
426 
427  while (NULL != (vrh = vrh_head))
428  {
429  // CREDENTIAL_resolver_lookup_cancel (clh->lookup);
430  GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
431  cleanup_handle (vrh);
432  }
433 
434  if (NULL != gns)
435  {
436  GNUNET_GNS_disconnect (gns);
437  gns = NULL;
438  }
439  if (NULL != namestore)
440  {
441  GNUNET_NAMESTORE_disconnect (namestore);
442  namestore = NULL;
443  }
444  if (NULL != statistics)
445  {
446  GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
447  statistics = NULL;
448  }
449 }
450 
451 
452 static void
454 {
455  struct GNUNET_MQ_Envelope *env;
456  struct DelegationChainResultMessage *rmsg;
457  struct DelegationChainEntry *dce;
458  struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
459  struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
460  struct CredentialRecordEntry *cd;
461  struct CredentialRecordEntry *tmp;
462  size_t size;
463 
464  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
465  dce = vrh->delegation_chain_head;
466  for (uint32_t i = 0; i < vrh->delegation_chain_size; i++)
467  {
468  dd[i].issuer_key = dce->issuer_key;
469  dd[i].subject_key = dce->subject_key;
470  dd[i].issuer_attribute = dce->issuer_attribute;
471  dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1;
472  dd[i].subject_attribute_len = 0;
473  dd[i].subject_attribute = NULL;
474  if (NULL != dce->subject_attribute)
475  {
477  dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1;
478  }
479  dce = dce->next;
480  }
481 
485  for (cd = vrh->cred_chain_head; NULL != cd;)
486  {
487  if (cd->refcount > 0)
488  {
489  cd = cd->next;
490  continue;
491  }
492  tmp = cd;
493  cd = cd->next;
494  GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head,
495  vrh->cred_chain_tail,
496  tmp);
497  GNUNET_free (tmp->credential);
498  GNUNET_free (tmp);
499  vrh->cred_chain_size--;
500  }
501 
506  cd = vrh->cred_chain_head;
507  for (uint32_t i = 0; i < vrh->cred_chain_size; i++)
508  {
509  cred[i].issuer_key = cd->credential->issuer_key;
510  cred[i].subject_key = cd->credential->subject_key;
511  cred[i].issuer_attribute_len
512  = strlen (cd->credential->issuer_attribute) + 1;
514  cred[i].expiration = cd->credential->expiration;
515  cred[i].signature = cd->credential->signature;
516  cd = cd->next;
517  }
518  size
519  = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size,
520  dd,
521  vrh->cred_chain_size,
522  cred);
523  env = GNUNET_MQ_msg_extra (rmsg,
524  size,
526  // Assign id so that client can find associated request
527  rmsg->id = vrh->request_id;
528  rmsg->d_count = htonl (vrh->delegation_chain_size);
529  rmsg->c_count = htonl (vrh->cred_chain_size);
530 
531  if (0 < vrh->cred_chain_size)
532  rmsg->cred_found = htonl (GNUNET_YES);
533  else
534  rmsg->cred_found = htonl (GNUNET_NO);
535 
536  GNUNET_assert (
537  -1
538  != GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size,
539  dd,
540  vrh->cred_chain_size,
541  cred,
542  size,
543  (char *) &rmsg[1]));
544 
545  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env);
546  GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
547  cleanup_handle (vrh);
548 
549  GNUNET_STATISTICS_update (statistics,
550  "Completed verifications",
551  1,
552  GNUNET_NO);
553 }
554 
555 
556 static void
558  uint32_t rd_count,
559  const struct GNUNET_GNSRECORD_Data *rd)
560 {
561  struct VerifyRequestHandle *vrh;
562  const struct GNUNET_CREDENTIAL_DelegationRecord *sets;
563  struct CredentialRecordEntry *cred_pointer;
564  struct DelegationSetQueueEntry *current_set;
565  struct DelegationSetQueueEntry *ds_entry;
566  struct DelegationSetQueueEntry *tmp_set;
567  struct DelegationQueueEntry *dq_entry;
568  char *expanded_attr;
569  char *lookup_attribute;
570 
571 
572  current_set = cls;
573  current_set->lookup_request = NULL;
574  vrh = current_set->handle;
575  vrh->pending_lookups--;
576  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got %d attrs\n", rd_count);
577 
578  // Each OR
579  for (uint32_t i = 0; i < rd_count; i++)
580  {
581  if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
582  continue;
583 
584  sets = rd[i].data;
585  struct GNUNET_CREDENTIAL_DelegationSet set[ntohl (sets->set_count)];
586  GNUNET_log (
588  "Found new attribute delegation with %d sets. Creating new Job...\n",
589  ntohl (sets->set_count));
590 
591  if (GNUNET_OK
593  GNUNET_ntohll (sets->data_size),
594  (const char *) &sets[1],
595  ntohl (sets->set_count),
596  set))
597  {
598  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
599  continue;
600  }
601  dq_entry = GNUNET_new (struct DelegationQueueEntry);
602  dq_entry->required_solutions = ntohl (sets->set_count);
603  dq_entry->parent_set = current_set;
605  current_set->queue_entries_tail,
606  dq_entry);
607  // Each AND
608  for (uint32_t j = 0; j < ntohl (sets->set_count); j++)
609  {
610  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
611  if (NULL != current_set->attr_trailer)
612  {
613  if (0 == set[j].subject_attribute_len)
614  {
615  GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer);
616  }
617  else
618  {
619  GNUNET_asprintf (&expanded_attr,
620  "%s.%s",
621  set[j].subject_attribute,
622  current_set->attr_trailer);
623  }
624  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
625  ds_entry->unresolved_attribute_delegation = expanded_attr;
626  }
627  else
628  {
629  if (0 != set[j].subject_attribute_len)
630  {
632  "Not Expanding %s\n",
633  set[j].subject_attribute);
635  = GNUNET_strdup (set[j].subject_attribute);
636  }
637  }
638 
639  // Add a credential chain entry
640  ds_entry->delegation_chain_entry
641  = GNUNET_new (struct DelegationChainEntry);
642  ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
644  GNUNET_memcpy (ds_entry->issuer_key,
645  &set[j].subject_key,
646  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
647  if (0 < set[j].subject_attribute_len)
649  = GNUNET_strdup (set[j].subject_attribute);
650  ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
652  = GNUNET_strdup (current_set->lookup_attribute);
653 
654  ds_entry->parent_queue_entry = dq_entry; // current_delegation;
656  dq_entry->set_entries_tail,
657  ds_entry);
658 
659  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking for cred match\n");
663  for (cred_pointer = vrh->cred_chain_head; cred_pointer != NULL;
664  cred_pointer = cred_pointer->next)
665  {
666  if (0
667  != GNUNET_memcmp (&set->subject_key,
668  &cred_pointer->credential->issuer_key))
669  continue;
671  "Checking if %s matches %s\n",
673  cred_pointer->credential->issuer_attribute);
674 
675  if (0
676  != strcmp (ds_entry->unresolved_attribute_delegation,
677  cred_pointer->credential->issuer_attribute))
678  continue;
679 
680  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
681  cred_pointer->refcount++;
682  // Backtrack
683  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
684  tmp_set = tmp_set->parent_queue_entry->parent_set)
685  {
687  if (NULL != tmp_set->delegation_chain_entry)
688  {
689  vrh->delegation_chain_size++;
692  tmp_set->delegation_chain_entry);
693  }
694  if (0 < tmp_set->parent_queue_entry->required_solutions)
695  break;
696  }
697 
698  if (NULL == tmp_set->parent_queue_entry)
699  {
700  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "All solutions found\n");
701  // Found match
702  send_lookup_response (vrh);
703  return;
704  }
705  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Not all solutions found yet.\n");
706  continue;
707  }
709  "Building new lookup request from %s\n",
711  // Continue with backward resolution
712  char
713  issuer_attribute_name[strlen (ds_entry->unresolved_attribute_delegation)
714  + 1];
715  strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
716  char *next_attr = strtok (issuer_attribute_name, ".");
717  if (NULL == next_attr)
718  {
720  "Failed to parse next attribute\n");
721  continue;
722  }
723  GNUNET_asprintf (&lookup_attribute, "%s", next_attr);
724  GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr);
725  if (strlen (next_attr)
726  == strlen (ds_entry->unresolved_attribute_delegation))
727  {
728  ds_entry->attr_trailer = NULL;
729  }
730  else
731  {
732  next_attr += strlen (next_attr) + 1;
733  ds_entry->attr_trailer = GNUNET_strdup (next_attr);
734  }
735 
737  "Looking up %s\n",
738  ds_entry->lookup_attribute);
739  if (NULL != ds_entry->attr_trailer)
741  "%s still to go...\n",
742  ds_entry->attr_trailer);
743 
744  vrh->pending_lookups++;
745  ds_entry->handle = vrh;
746  ds_entry->lookup_request
747  = GNUNET_GNS_lookup (gns,
748  lookup_attribute,
749  ds_entry->issuer_key, // issuer_key,
753  ds_entry);
754  GNUNET_free (lookup_attribute);
755  }
756  }
757 
758  if (0 == vrh->pending_lookups)
759  {
760  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
761  send_lookup_response (vrh);
762  return;
763  }
764 }
765 
766 
772 static void
774 {
775  struct VerifyRequestHandle *vrh = cls;
776  struct DelegationSetQueueEntry *ds_entry;
777  struct CredentialRecordEntry *cr_entry;
778 
779  vrh->lookup_request = NULL;
780 
781  if (0 == vrh->cred_chain_size)
782  {
783  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No credentials found\n");
784  send_lookup_response (vrh);
785  return;
786  }
787 
788  for (cr_entry = vrh->cred_chain_head; cr_entry != NULL;
789  cr_entry = cr_entry->next)
790  {
791  if (0
792  != GNUNET_memcmp (&cr_entry->credential->issuer_key,
793  &vrh->issuer_key))
794  continue;
795  if (0
796  != strcmp (cr_entry->credential->issuer_attribute,
797  vrh->issuer_attribute))
798  continue;
799  cr_entry->refcount++;
800  // Found match prematurely
801  send_lookup_response (vrh);
802  return;
803  }
804 
809  char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1];
810  strcpy (issuer_attribute_name, vrh->issuer_attribute);
812  "Looking up %s\n",
813  issuer_attribute_name);
814  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
816  GNUNET_memcpy (ds_entry->issuer_key,
817  &vrh->issuer_key,
818  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
820  ds_entry->handle = vrh;
822  vrh->root_set = ds_entry;
823  vrh->pending_lookups = 1;
824  // Start with backward resolution
825  ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
826  issuer_attribute_name,
827  &vrh->issuer_key, // issuer_key,
831  ds_entry);
832 }
833 
834 static int
835 check_verify (void *cls, const struct VerifyMessage *v_msg)
836 {
837  size_t msg_size;
838  const char *attr;
839 
840  msg_size = ntohs (v_msg->header.size);
841  if (msg_size < sizeof(struct VerifyMessage))
842  {
843  GNUNET_break (0);
844  return GNUNET_SYSERR;
845  }
847  {
848  GNUNET_break (0);
849  return GNUNET_SYSERR;
850  }
851  attr = (const char *) &v_msg[1];
852 
853  if (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH)
854  {
855  GNUNET_break (0);
856  return GNUNET_SYSERR;
857  }
858  return GNUNET_OK;
859 }
860 
861 static void
862 handle_verify (void *cls, const struct VerifyMessage *v_msg)
863 {
864  struct VerifyRequestHandle *vrh;
865  struct GNUNET_SERVICE_Client *client = cls;
866  struct CredentialRecordEntry *cr_entry;
867  uint32_t credentials_count;
868  uint32_t credential_data_size;
869  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
871  char *attrptr = attr;
872  char *credential_data;
873  const char *utf_in;
874 
875  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
876  utf_in = (const char *) &v_msg[1];
877  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
878  GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
879  issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
880  vrh = GNUNET_new (struct VerifyRequestHandle);
881  GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
882  vrh->client = client;
883  vrh->request_id = v_msg->id;
884  vrh->issuer_key = v_msg->issuer_key;
885  vrh->subject_key = v_msg->subject_key;
886  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
888  if (0 == strlen (issuer_attribute))
889  {
890  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
891  send_lookup_response (vrh);
892  return;
893  }
898  credentials_count = ntohl (v_msg->c_count);
899  credential_data_size = ntohs (v_msg->header.size)
900  - sizeof(struct VerifyMessage)
901  - ntohs (v_msg->issuer_attribute_len) - 1;
902  struct GNUNET_CREDENTIAL_Credential credentials[credentials_count];
903  memset (credentials,
904  0,
905  sizeof(struct GNUNET_CREDENTIAL_Credential) * credentials_count);
906  credential_data = (char *) &v_msg[1] + ntohs (v_msg->issuer_attribute_len)
907  + 1;
908  if (GNUNET_OK
909  != GNUNET_CREDENTIAL_credentials_deserialize (credential_data_size,
910  credential_data,
911  credentials_count,
912  credentials))
913  {
914  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize credentials!\n");
915  send_lookup_response (vrh);
916  return;
917  }
918 
919  for (uint32_t i = 0; i < credentials_count; i++)
920  {
921  cr_entry = GNUNET_new (struct CredentialRecordEntry);
922  cr_entry->credential
924  + credentials[i].issuer_attribute_len + 1);
925  GNUNET_memcpy (cr_entry->credential,
926  &credentials[i],
927  sizeof(struct GNUNET_CREDENTIAL_Credential));
928  GNUNET_memcpy (&cr_entry->credential[1],
929  credentials[i].issuer_attribute,
930  credentials[i].issuer_attribute_len);
932  = credentials[i].issuer_attribute_len;
933  cr_entry->credential->issuer_attribute = (char *) &cr_entry->credential[1];
935  vrh->cred_chain_tail,
936  cr_entry);
937  vrh->cred_chain_size++;
938  }
939 
941 }
942 
943 static void
945 {
946  struct VerifyRequestHandle *vrh = cls;
947 
949  "Got disconnected from namestore database.\n");
950  vrh->cred_collection_iter = NULL;
951  send_lookup_response (vrh);
952 }
953 
954 static void
955 collect_next (void *cls)
956 {
957  struct VerifyRequestHandle *vrh = cls;
958 
959  vrh->collect_next_task = NULL;
960  GNUNET_assert (NULL != vrh->cred_collection_iter);
962 }
963 
964 
965 static void
967  const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
968  const char *label,
969  unsigned int rd_count,
970  const struct GNUNET_GNSRECORD_Data *rd)
971 {
972  struct VerifyRequestHandle *vrh = cls;
973  struct GNUNET_CREDENTIAL_Credential *crd;
974  struct CredentialRecordEntry *cr_entry;
975  int cred_record_count;
976 
977  cred_record_count = 0;
978  for (uint32_t i = 0; i < rd_count; i++)
979  {
980  if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
981  continue;
982  cred_record_count++;
983  crd
985  if (NULL == crd)
986  {
987  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid credential found\n");
988  continue;
989  }
990  cr_entry = GNUNET_new (struct CredentialRecordEntry);
991  cr_entry->credential = crd;
993  vrh->cred_chain_tail,
994  cr_entry);
995  vrh->cred_chain_size++;
996  }
998 }
999 
1000 static void
1002 {
1003  struct VerifyRequestHandle *vrh = cls;
1004 
1005  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting credentials.\n");
1006  vrh->cred_collection_iter = NULL;
1008 }
1009 
1010 static void
1011 handle_collect (void *cls, const struct CollectMessage *c_msg)
1012 {
1013  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
1015  struct VerifyRequestHandle *vrh;
1016  struct GNUNET_SERVICE_Client *client = cls;
1017  char *attrptr = attr;
1018  const char *utf_in;
1019 
1020  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
1021 
1022  utf_in = (const char *) &c_msg[1];
1023  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1024 
1025  GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
1026  issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0';
1027  vrh = GNUNET_new (struct VerifyRequestHandle);
1028  GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
1029  vrh->client = client;
1030  vrh->request_id = c_msg->id;
1031  vrh->issuer_key = c_msg->issuer_key;
1033  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1034 
1035  if (0 == strlen (issuer_attribute))
1036  {
1037  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1038  send_lookup_response (vrh);
1039  return;
1040  }
1041  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting credentials for subject\n");
1046  namestore,
1047  &c_msg->subject_key,
1049  vrh,
1051  vrh,
1053  vrh);
1055 }
1056 
1057 
1058 static int
1059 check_collect (void *cls, const struct CollectMessage *c_msg)
1060 {
1061  size_t msg_size;
1062  const char *attr;
1063 
1064  msg_size = ntohs (c_msg->header.size);
1065  if (msg_size < sizeof(struct CollectMessage))
1066  {
1067  GNUNET_break (0);
1068  return GNUNET_SYSERR;
1069  }
1071  {
1072  GNUNET_break (0);
1073  return GNUNET_SYSERR;
1074  }
1075  attr = (const char *) &c_msg[1];
1076 
1077  if (('\0' != attr[msg_size - sizeof(struct CollectMessage) - 1])
1078  || (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH))
1079  {
1080  GNUNET_break (0);
1081  return GNUNET_SYSERR;
1082  }
1083  return GNUNET_OK;
1084 }
1085 
1086 static void
1088  struct GNUNET_SERVICE_Client *client,
1089  void *app_ctx)
1090 {
1091  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1092 }
1093 
1094 static void *
1096  struct GNUNET_SERVICE_Client *client,
1097  struct GNUNET_MQ_Handle *mq)
1098 {
1099  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1100  return client;
1101 }
1102 
1110 static void
1111 run (void *cls,
1112  const struct GNUNET_CONFIGURATION_Handle *c,
1113  struct GNUNET_SERVICE_Handle *handle)
1114 {
1115  gns = GNUNET_GNS_connect (c);
1116  if (NULL == gns)
1117  {
1118  fprintf (stderr, _ ("Failed to connect to GNS\n"));
1119  }
1120  namestore = GNUNET_NAMESTORE_connect (c);
1121  if (NULL == namestore)
1122  {
1123  fprintf (stderr, _ ("Failed to connect to namestore\n"));
1124  }
1125 
1126  statistics = GNUNET_STATISTICS_create ("credential", c);
1128 }
1129 
1130 
1135  "credential",
1137  &run,
1140  NULL,
1143  struct VerifyMessage,
1144  NULL),
1147  struct CollectMessage,
1148  NULL),
1150 
1151 /* 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:69
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:118
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:116
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:94
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:2437
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:99
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:1300
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:108
#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:50
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:79
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:250
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:1280
struct DelegationSetQueueEntry * prev
DLL.
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:284
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:74
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:262
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:67
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:239
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:60
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY.
Definition: credential.h:40
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:45
Handle to a message queue.
Definition: mq.c:85
uint32_t c_count
Number of credentials.
Definition: credential.h:89
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:85
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:123
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:134
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:308
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:55
#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:353
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:84
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:336
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:2243
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:128
#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:133
#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:553
uint32_t issuer_attribute_len
Length of the attribute.
char * lookup_attribute
The current attribute to look up.