aboutsummaryrefslogtreecommitdiff
path: root/src/credential/gnunet-credential.c
diff options
context:
space:
mode:
authorAndreas Ebner <pansy007@googlemail.com>2019-07-09 17:53:33 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-10-07 12:15:06 +0200
commit5091edcec16455febee99afec20e0ffe6cc59c21 (patch)
treec7d517e26ca7d3d4f863b4154361293bc79d733e /src/credential/gnunet-credential.c
parentfc58d9d4241ed2dcd4b492b4f922ba959449a697 (diff)
downloadgnunet-5091edcec16455febee99afec20e0ffe6cc59c21.tar.gz
gnunet-5091edcec16455febee99afec20e0ffe6cc59c21.zip
Cleanup, additional input checks, renaming, simplification:
- introducing own GNUNET_SIGNATURE_PURPOSE_DELEGATE - renaming of cred/crd in delegation_misc.c - renamed extension cmd para to import - changed subject key/attr parsing from memcpy/malloc to strtok - only allow to create delegates to expire absolute not relative (prevent reusing created delegation signatures) - check subject key and reuse expiration of import/signed delegation - replaced strdup() part of delegation_misc.c and credential_serialization.c with pointers - uncommented return after detection of unverifyable signatures
Diffstat (limited to 'src/credential/gnunet-credential.c')
-rw-r--r--src/credential/gnunet-credential.c233
1 files changed, 113 insertions, 120 deletions
diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c
index 22fca7b00..3d20e7082 100644
--- a/src/credential/gnunet-credential.c
+++ b/src/credential/gnunet-credential.c
@@ -150,7 +150,7 @@ static int sign_ss;
150/** 150/**
151 * Signed issue credentials 151 * Signed issue credentials
152 */ 152 */
153static char *extension; 153static char *import;
154 154
155/** 155/**
156 * Queue entry for the 'add' operation. 156 * Queue entry for the 'add' operation.
@@ -187,6 +187,16 @@ static uint64_t etime;
187static int etime_is_rel = GNUNET_SYSERR; 187static int etime_is_rel = GNUNET_SYSERR;
188 188
189/** 189/**
190 * Fixed size of the public/private keys
191 */
192static const int key_length = 52;
193
194/**
195 * Record label for storing delegations
196 */
197static char *record_label;
198
199/**
190 * Task run on shutdown. Cleans up everything. 200 * Task run on shutdown. Cleans up everything.
191 * 201 *
192 * @param cls unused 202 * @param cls unused
@@ -332,7 +342,7 @@ identity_cb (void *cls,
332 const struct GNUNET_IDENTITY_Ego *ego) 342 const struct GNUNET_IDENTITY_Ego *ego)
333{ 343{
334 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; 344 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
335 struct GNUNET_CREDENTIAL_Credential *crd; 345 struct GNUNET_CREDENTIAL_Credential *cred;
336 struct GNUNET_TIME_Absolute etime_abs; 346 struct GNUNET_TIME_Absolute etime_abs;
337 struct GNUNET_TIME_Relative etime_rel; 347 struct GNUNET_TIME_Relative etime_rel;
338 char *res; 348 char *res;
@@ -400,47 +410,17 @@ identity_cb (void *cls,
400 privkey = GNUNET_IDENTITY_ego_get_private_key (ego); 410 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
401 GNUNET_free_non_null (ego_name); 411 GNUNET_free_non_null (ego_name);
402 ego_name = NULL; 412 ego_name = NULL;
403 crd = GNUNET_CREDENTIAL_credential_issue (privkey, 413 cred = GNUNET_CREDENTIAL_credential_issue (privkey,
404 &subject_pkey, 414 &subject_pkey,
405 issuer_attr, 415 issuer_attr,
406 &etime_abs); 416 &etime_abs);
407 417
408 res = GNUNET_CREDENTIAL_credential_to_string (crd); 418 res = GNUNET_CREDENTIAL_credential_to_string (cred);
409 GNUNET_free (crd); 419 GNUNET_free (cred);
410 printf ("%s\n", res); 420 printf ("%s\n", res);
411 GNUNET_SCHEDULER_shutdown (); 421 GNUNET_SCHEDULER_shutdown ();
412} 422}
413 423
414static int
415parse_cmdl_param(const char *extensionstring)
416{
417 char *token;
418 char *tmp_str;
419 int counter = 0;
420
421 tmp_str = GNUNET_strdup (extensionstring);
422 // split string via strtok, assume parameters are in the right order
423 token = strtok (tmp_str, ";");
424 while (NULL != token) {
425
426 // fill variables depending on counter
427 if(0 == counter) {
428 expiration = GNUNET_strdup(token);
429 } else if(1 == counter) {
430 extension = GNUNET_strdup(token);
431 } else {
432 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not parse extension string\n");
433 }
434
435 counter++;
436 token = strtok (NULL, ";");
437 }
438 GNUNET_free (tmp_str);
439
440 //return GNUNET_SYSERR;
441 return GNUNET_OK;
442}
443
444/** 424/**
445 * Parse expiration time. 425 * Parse expiration time.
446 * 426 *
@@ -573,55 +553,71 @@ store_cb (void *cls,
573 // Key handling 553 // Key handling
574 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); 554 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
575 555
576 // Check relevant cmdline parameters 556 // TODO maybe dont have to set subject, if only used in if/else can use import here instead!!
577 if (NULL == issuer_attr) 557 if( GNUNET_GNSRECORD_TYPE_DELEGATE == type){
578 { 558 // Parse import
579 fprintf (stderr, "Missing option -attribute for operation 'create'.\n"); 559 struct GNUNET_CREDENTIAL_Delegate *cred;
580 GNUNET_SCHEDULER_shutdown (); 560 cred = GNUNET_CREDENTIAL_delegate_from_string (import);
581 return;
582 }
583 561
584 if (NULL == subject) 562 // Get import subject public key string
585 { 563 char *subject_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&cred->subject_key);
586 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
587 GNUNET_SCHEDULER_shutdown ();
588 return;
589 }
590 564
591 // String to value conversion for storage 565 // Get zone public key string
592 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, 566 struct GNUNET_CRYPTO_EcdsaPublicKey zone_pubkey;
567 GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey);
568 char *zone_pubkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string(&zone_pubkey);
569
570 // Check if the subject key in the signed import matches the zone's key it is issued to
571 if(strcmp(zone_pubkey_str, subject_pubkey_str) != 0)
572 {
573 fprintf (stderr, "Import signed delegate does not match this ego's public key.\n");
574 GNUNET_SCHEDULER_shutdown ();
575 return;
576 }
577
578 // Expiration
579 etime = cred->expiration.abs_value_us;
580 etime_is_rel = GNUNET_NO;
581
582 // Prepare the data to be store in the record
583 data_size = GNUNET_CREDENTIAL_delegate_serialize (cred, (char **)&data);
584 GNUNET_free(cred);
585 } else {
586 // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE
587 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type,
593 subject, 588 subject,
594 &data, 589 &data,
595 &data_size)) 590 &data_size))
596 { 591 {
597 fprintf (stderr, "Value `%s' invalid for record type `%s'\n", 592 fprintf (stderr, "Value `%s' invalid for record type `%s'\n",
598 subject, 593 subject,
599 typestring); 594 typestring);
600 GNUNET_SCHEDULER_shutdown (); 595 GNUNET_SCHEDULER_shutdown ();
601 return; 596 return;
602 } 597 }
603 598
604 // Take care of expiration 599 // Take care of expiration
605 if (NULL == expiration) 600 if (NULL == expiration)
606 { 601 {
607 fprintf (stderr, "Missing option -e for operation 'create'\n"); 602 fprintf (stderr, "Missing option -e for operation 'create'\n");
608 GNUNET_SCHEDULER_shutdown (); 603 GNUNET_SCHEDULER_shutdown ();
609 return; 604 return;
610 } 605 }
611 if (GNUNET_OK != parse_expiration (expiration, 606 if (GNUNET_OK != parse_expiration (expiration,
612 &etime_is_rel, 607 &etime_is_rel,
613 &etime)) 608 &etime))
614 { 609 {
615 fprintf (stderr, "Invalid time format `%s'\n", 610 fprintf (stderr, "Invalid time format `%s'\n",
616 expiration); 611 expiration);
617 GNUNET_SCHEDULER_shutdown (); 612 GNUNET_SCHEDULER_shutdown ();
618 return; 613 return;
614 }
619 } 615 }
620 616
621 // Start lookup 617 // Start lookup
622 add_qe = GNUNET_NAMESTORE_records_lookup (ns, 618 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
623 &zone_pkey, 619 &zone_pkey,
624 issuer_attr, 620 record_label,
625 &error_cb, 621 &error_cb,
626 NULL, 622 NULL,
627 &get_existing_record, 623 &get_existing_record,
@@ -634,9 +630,8 @@ sign_cb (void *cls,
634 const struct GNUNET_IDENTITY_Ego *ego) 630 const struct GNUNET_IDENTITY_Ego *ego)
635{ 631{
636 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; 632 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
637 struct GNUNET_CREDENTIAL_Delegate *crd; 633 struct GNUNET_CREDENTIAL_Delegate *dele;
638 struct GNUNET_TIME_Absolute etime_abs; 634 struct GNUNET_TIME_Absolute etime_abs;
639 struct GNUNET_TIME_Relative etime_rel;
640 char *res; 635 char *res;
641 636
642 el = NULL; 637 el = NULL;
@@ -647,43 +642,33 @@ sign_cb (void *cls,
647 fprintf (stderr, "Please specify a TTL\n"); 642 fprintf (stderr, "Please specify a TTL\n");
648 GNUNET_SCHEDULER_shutdown (); 643 GNUNET_SCHEDULER_shutdown ();
649 return; 644 return;
650 } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration, &etime_rel))
651 {
652 etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
653 } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs)) 645 } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs))
654 { 646 {
655 fprintf (stderr, "%s is not a valid ttl!\n", expiration); 647 fprintf (stderr, "%s is not a valid ttl! Only absolute times are accepted!\n", expiration);
656 GNUNET_SCHEDULER_shutdown (); 648 GNUNET_SCHEDULER_shutdown ();
657 return; 649 return;
658 } 650 }
659 651
660 // if contains a space - split it by the first space only - assume first entry is subject followed by attribute(s) 652 // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
661 char *space;
662 int idx;
663 char *subject_pubkey_str; 653 char *subject_pubkey_str;
664 char *subject_attr; 654 char *subject_attr = NULL;
655 char *token;
665 656
666 space = strchr(subject, ' '); 657 // Subject Public Key
667 if(NULL == space) 658 token = strtok (subject, " ");
659 if (key_length == strlen(token))
668 { 660 {
669 // only contains subject key e.g. A.a <- B 661 subject_pubkey_str = token;
670 subject_pubkey_str = subject;
671 subject_attr = '\0';
672 } else { 662 } else {
673 // subject contains: key attr1.attr2.attr3... 663 fprintf (stderr, "Key error, wrong length: %ld!\n", strlen(token));
674 // split subject into subject_pubkey_str and subject_attr 664 GNUNET_SCHEDULER_shutdown ();
675 idx = (int)(space - subject); 665 return;
676 666 }
677 subject_pubkey_str = GNUNET_malloc(idx+1); 667 // Subject Attribute(s)
678 GNUNET_memcpy(subject_pubkey_str, subject, idx); 668 token = strtok (NULL, " ");
679 subject_pubkey_str[idx] = '\0'; 669 if(NULL != token)
680 670 {
681 int sub_attr_len = strlen(subject) - idx - 1; 671 subject_attr = token;
682 // +1 for the \0
683 subject_attr = GNUNET_malloc(sub_attr_len + 1);
684 // +1 to remove the space "key attr" (or whatever separator)
685 GNUNET_memcpy(subject_attr, subject + idx + 1, sub_attr_len);
686 subject_attr[sub_attr_len] = '\0';
687 } 672 }
688 673
689 // work on keys 674 // work on keys
@@ -699,14 +684,14 @@ sign_cb (void *cls,
699 } 684 }
700 685
701 // Sign delegate 686 // Sign delegate
702 crd = GNUNET_CREDENTIAL_delegate_issue (privkey, 687 dele = GNUNET_CREDENTIAL_delegate_issue (privkey,
703 &subject_pkey, 688 &subject_pkey,
704 issuer_attr, 689 issuer_attr,
705 subject_attr, 690 subject_attr,
706 &etime_abs); 691 &etime_abs);
707 res = GNUNET_CREDENTIAL_delegate_to_string (crd); 692 res = GNUNET_CREDENTIAL_delegate_to_string (dele);
708 GNUNET_free (crd); 693 GNUNET_free (dele);
709 printf ("%s;%s\n", expiration, res); 694 printf ("%s\n", res);
710 695
711 GNUNET_free_non_null (ego_name); 696 GNUNET_free_non_null (ego_name);
712 ego_name = NULL; 697 ego_name = NULL;
@@ -728,22 +713,34 @@ run (void *cls,
728 const char *cfgfile, 713 const char *cfgfile,
729 const struct GNUNET_CONFIGURATION_Handle *c) 714 const struct GNUNET_CONFIGURATION_Handle *c)
730{ 715{
731
732 cfg = c; 716 cfg = c;
733 717
734 tt = GNUNET_SCHEDULER_add_delayed (timeout, 718 tt = GNUNET_SCHEDULER_add_delayed (timeout,
735 &do_timeout, NULL); 719 &do_timeout, NULL);
736 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 720 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
737 721
722 // Check relevant cmdline parameters
738 if (GNUNET_YES == create_is) { 723 if (GNUNET_YES == create_is) {
739 if (NULL == ego_name) { 724 if (NULL == ego_name) {
740 fprintf (stderr, "ego required\n"); 725 fprintf (stderr, "Missing option '-ego'\n");
726 GNUNET_SCHEDULER_shutdown ();
727 return;
728 }
729 if (NULL == issuer_attr) {
730 fprintf (stderr, "Missing option '-attribute' for issuer attribute\n");
731 GNUNET_SCHEDULER_shutdown ();
732 return;
733 }
734 if (NULL == subject)
735 {
736 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
741 GNUNET_SCHEDULER_shutdown (); 737 GNUNET_SCHEDULER_shutdown ();
742 return; 738 return;
743 } 739 }
744 740
745 // Lookup ego, on success call store_cb and store as ATTRIBUTE type 741 // Lookup ego, on success call store_cb and store as ATTRIBUTE type
746 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE; 742 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE;
743 record_label = issuer_attr;
747 el = GNUNET_IDENTITY_ego_lookup (cfg, 744 el = GNUNET_IDENTITY_ego_lookup (cfg,
748 ego_name, 745 ego_name,
749 &store_cb, 746 &store_cb,
@@ -753,18 +750,14 @@ run (void *cls,
753 750
754 if (GNUNET_YES == create_ss) { 751 if (GNUNET_YES == create_ss) {
755 // check if signed parameter has been passed in cmd line call 752 // check if signed parameter has been passed in cmd line call
756 if (NULL == extension) { 753 if (NULL == import) {
757 fprintf (stderr, "'extension' required\n"); 754 fprintf (stderr, "'import' required\n");
758 GNUNET_SCHEDULER_shutdown (); 755 GNUNET_SCHEDULER_shutdown ();
759 return; 756 return;
760 } 757 }
761 758
762 // parses all the passed parameters
763 parse_cmdl_param(extension);
764
765 type = GNUNET_GNSRECORD_TYPE_DELEGATE; 759 type = GNUNET_GNSRECORD_TYPE_DELEGATE;
766 subject = extension; 760 record_label = GNUNET_GNS_EMPTY_LABEL_AT;
767 issuer_attr = GNUNET_GNS_EMPTY_LABEL_AT;
768 // Store subject side 761 // Store subject side
769 el = GNUNET_IDENTITY_ego_lookup (cfg, 762 el = GNUNET_IDENTITY_ego_lookup (cfg,
770 ego_name, 763 ego_name,
@@ -1008,7 +1001,7 @@ main (int argc, char *const *argv)
1008 GNUNET_GETOPT_option_string ('T', 1001 GNUNET_GETOPT_option_string ('T',
1009 "ttl", 1002 "ttl",
1010 "EXP", 1003 "EXP",
1011 gettext_noop ("The time to live for the credential"), 1004 gettext_noop ("The time to live for the credential. e.g. 5m, 6h, \"1990-12-30 12:00:00\""),
1012 &expiration), 1005 &expiration),
1013 GNUNET_GETOPT_option_flag ('g', 1006 GNUNET_GETOPT_option_flag ('g',
1014 "collect", 1007 "collect",
@@ -1027,10 +1020,10 @@ main (int argc, char *const *argv)
1027 gettext_noop ("Create, sign and return a credential subject side."), 1020 gettext_noop ("Create, sign and return a credential subject side."),
1028 &sign_ss), 1021 &sign_ss),
1029 GNUNET_GETOPT_option_string ('x', 1022 GNUNET_GETOPT_option_string ('x',
1030 "extension", 1023 "import",
1031 "EXT", 1024 "IMP",
1032 gettext_noop ("Signed credentials that should be issued to a zone/ego"), 1025 gettext_noop ("Import signed credentials that should be issued to a zone/ego"),
1033 &extension), 1026 &import),
1034 GNUNET_GETOPT_OPTION_END 1027 GNUNET_GETOPT_OPTION_END
1035 }; 1028 };
1036 int ret; 1029 int ret;