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 {
228 
233 
238 
243 
248 
253 
258 
263 
268 
273 
278 
283 
288 
292  uint32_t cred_chain_size;
293 
298 
303 
307  uint32_t request_id;
308 
312  uint64_t pending_lookups;
313 
318 
323 };
324 
325 
330 
335 
340 
344 static struct GNUNET_GNS_Handle *gns;
345 
346 
351 
352 static void
354 {
355  struct DelegationQueueEntry *dq_entry;
357 
358  if (NULL == ds_entry)
359  return;
360 
361  for (dq_entry = ds_entry->queue_entries_head; NULL != dq_entry;
362  dq_entry = ds_entry->queue_entries_head) {
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) {
369  dq_entry->set_entries_tail,
370  child);
371  cleanup_delegation_set (child);
372  }
373  GNUNET_free (dq_entry);
374  }
375  GNUNET_free_non_null (ds_entry->issuer_key);
380  if (NULL != ds_entry->lookup_request) {
382  ds_entry->lookup_request = NULL;
383  }
384  if (NULL != ds_entry->delegation_chain_entry) {
388  }
389  GNUNET_free (ds_entry);
390 }
391 
392 static void
394 {
395  struct CredentialRecordEntry *cr_entry;
396  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n");
397  if (NULL != vrh->lookup_request) {
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) {
406  vrh->cred_chain_tail,
407  cr_entry);
408  GNUNET_free_non_null (cr_entry->credential);
409  GNUNET_free (cr_entry);
410  }
411  GNUNET_free (vrh);
412 }
413 
414 static void
415 shutdown_task (void *cls)
416 {
417  struct VerifyRequestHandle *vrh;
418 
419  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n");
420 
421  while (NULL != (vrh = vrh_head)) {
422  // CREDENTIAL_resolver_lookup_cancel (clh->lookup);
423  GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
424  cleanup_handle (vrh);
425  }
426 
427  if (NULL != gns) {
428  GNUNET_GNS_disconnect (gns);
429  gns = NULL;
430  }
431  if (NULL != namestore) {
432  GNUNET_NAMESTORE_disconnect (namestore);
433  namestore = NULL;
434  }
435  if (NULL != statistics) {
436  GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
437  statistics = NULL;
438  }
439 }
440 
441 
442 static void
444 {
445  struct GNUNET_MQ_Envelope *env;
446  struct DelegationChainResultMessage *rmsg;
447  struct DelegationChainEntry *dce;
448  struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
449  struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
450  struct CredentialRecordEntry *cd;
451  struct CredentialRecordEntry *tmp;
452  size_t size;
453 
454  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
455  dce = vrh->delegation_chain_head;
456  for (uint32_t i = 0; i < vrh->delegation_chain_size; i++) {
457  dd[i].issuer_key = dce->issuer_key;
458  dd[i].subject_key = dce->subject_key;
459  dd[i].issuer_attribute = dce->issuer_attribute;
460  dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1;
461  dd[i].subject_attribute_len = 0;
462  dd[i].subject_attribute = NULL;
463  if (NULL != dce->subject_attribute) {
465  dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1;
466  }
467  dce = dce->next;
468  }
469 
473  for (cd = vrh->cred_chain_head; NULL != cd;) {
474  if (cd->refcount > 0) {
475  cd = cd->next;
476  continue;
477  }
478  tmp = cd;
479  cd = cd->next;
480  GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head,
481  vrh->cred_chain_tail,
482  tmp);
483  GNUNET_free (tmp->credential);
484  GNUNET_free (tmp);
485  vrh->cred_chain_size--;
486  }
487 
492  cd = vrh->cred_chain_head;
493  for (uint32_t i = 0; i < vrh->cred_chain_size; i++) {
494  cred[i].issuer_key = cd->credential->issuer_key;
495  cred[i].subject_key = cd->credential->subject_key;
496  cred[i].issuer_attribute_len
497  = strlen (cd->credential->issuer_attribute) + 1;
499  cred[i].expiration = cd->credential->expiration;
500  cred[i].signature = cd->credential->signature;
501  cd = cd->next;
502  }
503  size
504  = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size,
505  dd,
506  vrh->cred_chain_size,
507  cred);
508  env = GNUNET_MQ_msg_extra (rmsg,
509  size,
511  // Assign id so that client can find associated request
512  rmsg->id = vrh->request_id;
513  rmsg->d_count = htonl (vrh->delegation_chain_size);
514  rmsg->c_count = htonl (vrh->cred_chain_size);
515 
516  if (0 < vrh->cred_chain_size)
517  rmsg->cred_found = htonl (GNUNET_YES);
518  else
519  rmsg->cred_found = htonl (GNUNET_NO);
520 
521  GNUNET_assert (
522  -1
523  != GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size,
524  dd,
525  vrh->cred_chain_size,
526  cred,
527  size,
528  (char *)&rmsg[1]));
529 
530  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env);
531  GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
532  cleanup_handle (vrh);
533 
534  GNUNET_STATISTICS_update (statistics,
535  "Completed verifications",
536  1,
537  GNUNET_NO);
538 }
539 
540 
541 static void
543  uint32_t rd_count,
544  const struct GNUNET_GNSRECORD_Data *rd)
545 {
546 
547  struct VerifyRequestHandle *vrh;
548  const struct GNUNET_CREDENTIAL_DelegationRecord *sets;
549  struct CredentialRecordEntry *cred_pointer;
550  struct DelegationSetQueueEntry *current_set;
551  struct DelegationSetQueueEntry *ds_entry;
552  struct DelegationSetQueueEntry *tmp_set;
553  struct DelegationQueueEntry *dq_entry;
554  char *expanded_attr;
555  char *lookup_attribute;
556 
557 
558  current_set = cls;
559  current_set->lookup_request = NULL;
560  vrh = current_set->handle;
561  vrh->pending_lookups--;
562  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got %d attrs\n", rd_count);
563 
564  // Each OR
565  for (uint32_t i = 0; i < rd_count; i++) {
566  if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
567  continue;
568 
569  sets = rd[i].data;
570  struct GNUNET_CREDENTIAL_DelegationSet set[ntohl (sets->set_count)];
571  GNUNET_log (
573  "Found new attribute delegation with %d sets. Creating new Job...\n",
574  ntohl (sets->set_count));
575 
576  if (GNUNET_OK
578  GNUNET_ntohll (sets->data_size),
579  (const char *)&sets[1],
580  ntohl (sets->set_count),
581  set)) {
582  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
583  continue;
584  }
585  dq_entry = GNUNET_new (struct DelegationQueueEntry);
586  dq_entry->required_solutions = ntohl (sets->set_count);
587  dq_entry->parent_set = current_set;
589  current_set->queue_entries_tail,
590  dq_entry);
591  // Each AND
592  for (uint32_t j = 0; j < ntohl (sets->set_count); j++) {
593  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
594  if (NULL != current_set->attr_trailer) {
595  if (0 == set[j].subject_attribute_len) {
596  GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer);
597 
598  } else {
599  GNUNET_asprintf (&expanded_attr,
600  "%s.%s",
601  set[j].subject_attribute,
602  current_set->attr_trailer);
603  }
604  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
605  ds_entry->unresolved_attribute_delegation = expanded_attr;
606  } else {
607  if (0 != set[j].subject_attribute_len) {
609  "Not Expanding %s\n",
610  set[j].subject_attribute);
612  = GNUNET_strdup (set[j].subject_attribute);
613  }
614  }
615 
616  // Add a credential chain entry
617  ds_entry->delegation_chain_entry
618  = GNUNET_new (struct DelegationChainEntry);
619  ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
621  GNUNET_memcpy (ds_entry->issuer_key,
622  &set[j].subject_key,
623  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
624  if (0 < set[j].subject_attribute_len)
626  = GNUNET_strdup (set[j].subject_attribute);
627  ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
629  = GNUNET_strdup (current_set->lookup_attribute);
630 
631  ds_entry->parent_queue_entry = dq_entry; // current_delegation;
633  dq_entry->set_entries_tail,
634  ds_entry);
635 
636  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking for cred match\n");
640  for (cred_pointer = vrh->cred_chain_head; cred_pointer != NULL;
641  cred_pointer = cred_pointer->next) {
642  if (0
643  != GNUNET_memcmp (&set->subject_key,
644  &cred_pointer->credential->issuer_key))
645  continue;
647  "Checking if %s matches %s\n",
649  cred_pointer->credential->issuer_attribute);
650 
651  if (0
652  != strcmp (ds_entry->unresolved_attribute_delegation,
653  cred_pointer->credential->issuer_attribute))
654  continue;
655 
656  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
657  cred_pointer->refcount++;
658  // Backtrack
659  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
660  tmp_set = tmp_set->parent_queue_entry->parent_set) {
662  if (NULL != tmp_set->delegation_chain_entry) {
663  vrh->delegation_chain_size++;
666  tmp_set->delegation_chain_entry);
667  }
668  if (0 < tmp_set->parent_queue_entry->required_solutions)
669  break;
670  }
671 
672  if (NULL == tmp_set->parent_queue_entry) {
673  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "All solutions found\n");
674  // Found match
675  send_lookup_response (vrh);
676  return;
677  }
678  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Not all solutions found yet.\n");
679  continue;
680  }
682  "Building new lookup request from %s\n",
684  // Continue with backward resolution
685  char
686  issuer_attribute_name[strlen (ds_entry->unresolved_attribute_delegation)
687  + 1];
688  strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
689  char *next_attr = strtok (issuer_attribute_name, ".");
690  if (NULL == next_attr) {
692  "Failed to parse next attribute\n");
693  continue;
694  }
695  GNUNET_asprintf (&lookup_attribute, "%s", next_attr);
696  GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr);
697  if (strlen (next_attr)
698  == strlen (ds_entry->unresolved_attribute_delegation)) {
699  ds_entry->attr_trailer = NULL;
700  } else {
701  next_attr += strlen (next_attr) + 1;
702  ds_entry->attr_trailer = GNUNET_strdup (next_attr);
703  }
704 
706  "Looking up %s\n",
707  ds_entry->lookup_attribute);
708  if (NULL != ds_entry->attr_trailer)
710  "%s still to go...\n",
711  ds_entry->attr_trailer);
712 
713  vrh->pending_lookups++;
714  ds_entry->handle = vrh;
715  ds_entry->lookup_request
716  = GNUNET_GNS_lookup (gns,
717  lookup_attribute,
718  ds_entry->issuer_key, // issuer_key,
722  ds_entry);
723  GNUNET_free (lookup_attribute);
724  }
725  }
726 
727  if (0 == vrh->pending_lookups) {
728  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
729  send_lookup_response (vrh);
730  return;
731  }
732 }
733 
734 
740 static void
742 {
743  struct VerifyRequestHandle *vrh = cls;
744  struct DelegationSetQueueEntry *ds_entry;
745  struct CredentialRecordEntry *cr_entry;
746  vrh->lookup_request = NULL;
747 
748  if (0 == vrh->cred_chain_size) {
749  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No credentials found\n");
750  send_lookup_response (vrh);
751  return;
752  }
753 
754  for (cr_entry = vrh->cred_chain_head; cr_entry != NULL;
755  cr_entry = cr_entry->next) {
756  if (0
757  != GNUNET_memcmp (&cr_entry->credential->issuer_key,
758  &vrh->issuer_key))
759  continue;
760  if (0
761  != strcmp (cr_entry->credential->issuer_attribute,
762  vrh->issuer_attribute))
763  continue;
764  cr_entry->refcount++;
765  // Found match prematurely
766  send_lookup_response (vrh);
767  return;
768  }
769 
774  char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1];
775  strcpy (issuer_attribute_name, vrh->issuer_attribute);
777  "Looking up %s\n",
778  issuer_attribute_name);
779  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
781  GNUNET_memcpy (ds_entry->issuer_key,
782  &vrh->issuer_key,
783  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
785  ds_entry->handle = vrh;
787  vrh->root_set = ds_entry;
788  vrh->pending_lookups = 1;
789  // Start with backward resolution
790  ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
791  issuer_attribute_name,
792  &vrh->issuer_key, // issuer_key,
796  ds_entry);
797 }
798 
799 static int
800 check_verify (void *cls, const struct VerifyMessage *v_msg)
801 {
802  size_t msg_size;
803  const char *attr;
804 
805  msg_size = ntohs (v_msg->header.size);
806  if (msg_size < sizeof (struct VerifyMessage)) {
807  GNUNET_break (0);
808  return GNUNET_SYSERR;
809  }
810  if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) {
811  GNUNET_break (0);
812  return GNUNET_SYSERR;
813  }
814  attr = (const char *)&v_msg[1];
815 
816  if (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) {
817  GNUNET_break (0);
818  return GNUNET_SYSERR;
819  }
820  return GNUNET_OK;
821 }
822 
823 static void
824 handle_verify (void *cls, const struct VerifyMessage *v_msg)
825 {
826  struct VerifyRequestHandle *vrh;
827  struct GNUNET_SERVICE_Client *client = cls;
828  struct CredentialRecordEntry *cr_entry;
829  uint32_t credentials_count;
830  uint32_t credential_data_size;
831  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
833  char *attrptr = attr;
834  char *credential_data;
835  const char *utf_in;
836 
837  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
838  utf_in = (const char *)&v_msg[1];
839  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
840  GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
841  issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
842  vrh = GNUNET_new (struct VerifyRequestHandle);
843  GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
844  vrh->client = client;
845  vrh->request_id = v_msg->id;
846  vrh->issuer_key = v_msg->issuer_key;
847  vrh->subject_key = v_msg->subject_key;
848  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
850  if (0 == strlen (issuer_attribute)) {
851  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
852  send_lookup_response (vrh);
853  return;
854  }
859  credentials_count = ntohl (v_msg->c_count);
860  credential_data_size = ntohs (v_msg->header.size)
861  - sizeof (struct VerifyMessage)
862  - ntohs (v_msg->issuer_attribute_len) - 1;
863  struct GNUNET_CREDENTIAL_Credential credentials[credentials_count];
864  memset (credentials,
865  0,
866  sizeof (struct GNUNET_CREDENTIAL_Credential) * credentials_count);
867  credential_data = (char *)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
868  if (GNUNET_OK
869  != GNUNET_CREDENTIAL_credentials_deserialize (credential_data_size,
870  credential_data,
871  credentials_count,
872  credentials)) {
873  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize credentials!\n");
874  send_lookup_response (vrh);
875  return;
876  }
877 
878  for (uint32_t i = 0; i < credentials_count; i++) {
879  cr_entry = GNUNET_new (struct CredentialRecordEntry);
880  cr_entry->credential
882  + credentials[i].issuer_attribute_len + 1);
883  GNUNET_memcpy (cr_entry->credential,
884  &credentials[i],
885  sizeof (struct GNUNET_CREDENTIAL_Credential));
886  GNUNET_memcpy (&cr_entry->credential[1],
887  credentials[i].issuer_attribute,
888  credentials[i].issuer_attribute_len);
890  = credentials[i].issuer_attribute_len;
891  cr_entry->credential->issuer_attribute = (char *)&cr_entry->credential[1];
893  vrh->cred_chain_tail,
894  cr_entry);
895  vrh->cred_chain_size++;
896  }
897 
899 }
900 
901 static void
903 {
904  struct VerifyRequestHandle *vrh = cls;
906  "Got disconnected from namestore database.\n");
907  vrh->cred_collection_iter = NULL;
908  send_lookup_response (vrh);
909 }
910 
911 static void
912 collect_next (void *cls)
913 {
914  struct VerifyRequestHandle *vrh = cls;
915  vrh->collect_next_task = NULL;
916  GNUNET_assert (NULL != vrh->cred_collection_iter);
918 }
919 
920 
921 static void
923  const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
924  const char *label,
925  unsigned int rd_count,
926  const struct GNUNET_GNSRECORD_Data *rd)
927 {
928  struct VerifyRequestHandle *vrh = cls;
929  struct GNUNET_CREDENTIAL_Credential *crd;
930  struct CredentialRecordEntry *cr_entry;
931  int cred_record_count;
932 
933  cred_record_count = 0;
934  for (uint32_t i = 0; i < rd_count; i++) {
935  if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
936  continue;
937  cred_record_count++;
938  crd
940  if (NULL == crd) {
941  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid credential found\n");
942  continue;
943  }
944  cr_entry = GNUNET_new (struct CredentialRecordEntry);
945  cr_entry->credential = crd;
947  vrh->cred_chain_tail,
948  cr_entry);
949  vrh->cred_chain_size++;
950  }
952 }
953 
954 static void
956 {
957  struct VerifyRequestHandle *vrh = cls;
958  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting credentials.\n");
959  vrh->cred_collection_iter = NULL;
961 }
962 
963 static void
964 handle_collect (void *cls, const struct CollectMessage *c_msg)
965 {
966  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
968  struct VerifyRequestHandle *vrh;
969  struct GNUNET_SERVICE_Client *client = cls;
970  char *attrptr = attr;
971  const char *utf_in;
972 
973  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
974 
975  utf_in = (const char *)&c_msg[1];
976  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
977 
978  GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
979  issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0';
980  vrh = GNUNET_new (struct VerifyRequestHandle);
981  GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
982  vrh->client = client;
983  vrh->request_id = c_msg->id;
984  vrh->issuer_key = c_msg->issuer_key;
986  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
987 
988  if (0 == strlen (issuer_attribute)) {
989  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
990  send_lookup_response (vrh);
991  return;
992  }
993  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting credentials for subject\n");
998  namestore,
999  &c_msg->subject_key,
1001  vrh,
1003  vrh,
1005  vrh);
1007 }
1008 
1009 
1010 static int
1011 check_collect (void *cls, const struct CollectMessage *c_msg)
1012 {
1013  size_t msg_size;
1014  const char *attr;
1015 
1016  msg_size = ntohs (c_msg->header.size);
1017  if (msg_size < sizeof (struct CollectMessage)) {
1018  GNUNET_break (0);
1019  return GNUNET_SYSERR;
1020  }
1021  if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) {
1022  GNUNET_break (0);
1023  return GNUNET_SYSERR;
1024  }
1025  attr = (const char *)&c_msg[1];
1026 
1027  if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1])
1028  || (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH)) {
1029  GNUNET_break (0);
1030  return GNUNET_SYSERR;
1031  }
1032  return GNUNET_OK;
1033 }
1034 
1035 static void
1037  struct GNUNET_SERVICE_Client *client,
1038  void *app_ctx)
1039 {
1040  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1041 }
1042 
1043 static void *
1045  struct GNUNET_SERVICE_Client *client,
1046  struct GNUNET_MQ_Handle *mq)
1047 {
1048  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1049  return client;
1050 }
1051 
1059 static void
1060 run (void *cls,
1061  const struct GNUNET_CONFIGURATION_Handle *c,
1062  struct GNUNET_SERVICE_Handle *handle)
1063 {
1064 
1065  gns = GNUNET_GNS_connect (c);
1066  if (NULL == gns) {
1067  fprintf (stderr, _ ("Failed to connect to GNS\n"));
1068  }
1069  namestore = GNUNET_NAMESTORE_connect (c);
1070  if (NULL == namestore) {
1071  fprintf (stderr, _ ("Failed to connect to namestore\n"));
1072  }
1073 
1074  statistics = GNUNET_STATISTICS_create ("credential", c);
1076 }
1077 
1078 
1083  "credential",
1085  &run,
1088  NULL,
1091  struct VerifyMessage,
1092  NULL),
1095  struct CollectMessage,
1096  NULL),
1098 
1099 /* 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:70
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:120
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:95
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:2734
uint32_t id
Unique identifier for this request (for key collisions).
Definition: credential.h:100
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:1293
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:110
#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
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:81
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Subject public key.
Definition: credential.h:80
static struct VerifyRequestHandle * vrh_head
Head of the DLL.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:208
#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:249
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)
#define GNUNET_memcpy(dst, src, n)
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:1273
struct DelegationSetQueueEntry * prev
DLL.
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:285
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:75
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:263
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:79
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: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: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:90
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:125
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:309
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:80
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:85
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:337
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:2533
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:130
#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:135
#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:558
uint32_t issuer_attribute_len
Length of the attribute.
char * lookup_attribute
The current attribute to look up.