diff options
author | Andreas Ebner <pansy007@googlemail.com> | 2019-07-09 17:53:33 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-10-07 12:15:06 +0200 |
commit | 5091edcec16455febee99afec20e0ffe6cc59c21 (patch) | |
tree | c7d517e26ca7d3d4f863b4154361293bc79d733e /src/credential/gnunet-credential.c | |
parent | fc58d9d4241ed2dcd4b492b4f922ba959449a697 (diff) | |
download | gnunet-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.c | 233 |
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 | */ |
153 | static char *extension; | 153 | static 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; | |||
187 | static int etime_is_rel = GNUNET_SYSERR; | 187 | static int etime_is_rel = GNUNET_SYSERR; |
188 | 188 | ||
189 | /** | 189 | /** |
190 | * Fixed size of the public/private keys | ||
191 | */ | ||
192 | static const int key_length = 52; | ||
193 | |||
194 | /** | ||
195 | * Record label for storing delegations | ||
196 | */ | ||
197 | static 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 | ||
414 | static int | ||
415 | parse_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; |