diff options
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r-- | src/util/crypto_ecc.c | 401 |
1 files changed, 0 insertions, 401 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index e6d6bc133..87c787185 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c | |||
@@ -658,407 +658,6 @@ GNUNET_CRYPTO_ecdsa_key_get_anonymous () | |||
658 | 658 | ||
659 | 659 | ||
660 | /** | 660 | /** |
661 | * Wait for a short time (we're trying to lock a file or want | ||
662 | * to give another process a shot at finishing a disk write, etc.). | ||
663 | * Sleeps for 100ms (as that should be long enough for virtually all | ||
664 | * modern systems to context switch and allow another process to do | ||
665 | * some 'real' work). | ||
666 | */ | ||
667 | static void | ||
668 | short_wait () | ||
669 | { | ||
670 | struct GNUNET_TIME_Relative timeout; | ||
671 | |||
672 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100); | ||
673 | (void) GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout); | ||
674 | } | ||
675 | |||
676 | |||
677 | /** | ||
678 | * Create a new private key by reading it from a file. If the | ||
679 | * files does not exist, create a new key and write it to the | ||
680 | * file. Caller must free return value. Note that this function | ||
681 | * can not guarantee that another process might not be trying | ||
682 | * the same operation on the same file at the same time. | ||
683 | * If the contents of the file | ||
684 | * are invalid the old file is deleted and a fresh key is | ||
685 | * created. | ||
686 | * | ||
687 | * @param filename name of file to use to store the key | ||
688 | * @return new private key, NULL on error (for example, | ||
689 | * permission denied) | ||
690 | */ | ||
691 | struct GNUNET_CRYPTO_EddsaPrivateKey * | ||
692 | GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename) | ||
693 | { | ||
694 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv; | ||
695 | struct GNUNET_DISK_FileHandle *fd; | ||
696 | unsigned int cnt; | ||
697 | int ec; | ||
698 | uint64_t fs; | ||
699 | |||
700 | if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) | ||
701 | return NULL; | ||
702 | while (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
703 | { | ||
704 | fd = GNUNET_DISK_file_open (filename, | ||
705 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | ||
706 | | GNUNET_DISK_OPEN_FAILIFEXISTS, | ||
707 | GNUNET_DISK_PERM_USER_READ | | ||
708 | GNUNET_DISK_PERM_USER_WRITE); | ||
709 | if (NULL == fd) | ||
710 | { | ||
711 | if (EEXIST == errno) | ||
712 | { | ||
713 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
714 | { | ||
715 | /* must exist but not be accessible, fail for good! */ | ||
716 | if (0 != ACCESS (filename, R_OK)) | ||
717 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename); | ||
718 | else | ||
719 | GNUNET_break (0); /* what is going on!? */ | ||
720 | return NULL; | ||
721 | } | ||
722 | continue; | ||
723 | } | ||
724 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); | ||
725 | return NULL; | ||
726 | } | ||
727 | cnt = 0; | ||
728 | while (GNUNET_YES != | ||
729 | GNUNET_DISK_file_lock (fd, 0, | ||
730 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), | ||
731 | GNUNET_YES)) | ||
732 | { | ||
733 | short_wait (); | ||
734 | if (0 == ++cnt % 10) | ||
735 | { | ||
736 | ec = errno; | ||
737 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
738 | _("Could not acquire lock on file `%s': %s...\n"), filename, | ||
739 | STRERROR (ec)); | ||
740 | } | ||
741 | } | ||
742 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
743 | _("Creating a new private key. This may take a while.\n")); | ||
744 | priv = GNUNET_CRYPTO_eddsa_key_create (); | ||
745 | GNUNET_assert (NULL != priv); | ||
746 | GNUNET_assert (sizeof (*priv) == | ||
747 | GNUNET_DISK_file_write (fd, priv, sizeof (*priv))); | ||
748 | GNUNET_DISK_file_sync (fd); | ||
749 | if (GNUNET_YES != | ||
750 | GNUNET_DISK_file_unlock (fd, 0, | ||
751 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) | ||
752 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
753 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); | ||
754 | return priv; | ||
755 | } | ||
756 | /* key file exists already, read it! */ | ||
757 | fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, | ||
758 | GNUNET_DISK_PERM_NONE); | ||
759 | if (NULL == fd) | ||
760 | { | ||
761 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); | ||
762 | return NULL; | ||
763 | } | ||
764 | cnt = 0; | ||
765 | while (1) | ||
766 | { | ||
767 | if (GNUNET_YES != | ||
768 | GNUNET_DISK_file_lock (fd, 0, | ||
769 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), | ||
770 | GNUNET_NO)) | ||
771 | { | ||
772 | if (0 == ++cnt % 60) | ||
773 | { | ||
774 | ec = errno; | ||
775 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
776 | _("Could not acquire lock on file `%s': %s...\n"), filename, | ||
777 | STRERROR (ec)); | ||
778 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
779 | _ | ||
780 | ("This may be ok if someone is currently generating a private key.\n")); | ||
781 | } | ||
782 | short_wait (); | ||
783 | continue; | ||
784 | } | ||
785 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
786 | { | ||
787 | /* eh, what!? File we opened is now gone!? */ | ||
788 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); | ||
789 | if (GNUNET_YES != | ||
790 | GNUNET_DISK_file_unlock (fd, 0, | ||
791 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) | ||
792 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
793 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); | ||
794 | |||
795 | return NULL; | ||
796 | } | ||
797 | if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) | ||
798 | fs = 0; | ||
799 | if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) | ||
800 | { | ||
801 | /* maybe we got the read lock before the key generating | ||
802 | * process had a chance to get the write lock; give it up! */ | ||
803 | if (GNUNET_YES != | ||
804 | GNUNET_DISK_file_unlock (fd, 0, | ||
805 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) | ||
806 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
807 | if (0 == ++cnt % 10) | ||
808 | { | ||
809 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
810 | _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"), | ||
811 | filename, (unsigned int) fs, | ||
812 | (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); | ||
813 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
814 | _("This may be ok if someone is currently generating a key.\n")); | ||
815 | } | ||
816 | short_wait (); /* wait a bit longer! */ | ||
817 | continue; | ||
818 | } | ||
819 | break; | ||
820 | } | ||
821 | fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey); | ||
822 | priv = GNUNET_malloc (fs); | ||
823 | GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs)); | ||
824 | if (GNUNET_YES != | ||
825 | GNUNET_DISK_file_unlock (fd, 0, | ||
826 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) | ||
827 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
828 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); | ||
829 | return priv; | ||
830 | } | ||
831 | |||
832 | |||
833 | /** | ||
834 | * Create a new private key by reading it from a file. If the | ||
835 | * files does not exist, create a new key and write it to the | ||
836 | * file. Caller must free return value. Note that this function | ||
837 | * can not guarantee that another process might not be trying | ||
838 | * the same operation on the same file at the same time. | ||
839 | * If the contents of the file | ||
840 | * are invalid the old file is deleted and a fresh key is | ||
841 | * created. | ||
842 | * | ||
843 | * @param filename name of file to use to store the key | ||
844 | * @return new private key, NULL on error (for example, | ||
845 | * permission denied) | ||
846 | */ | ||
847 | struct GNUNET_CRYPTO_EcdsaPrivateKey * | ||
848 | GNUNET_CRYPTO_ecdsa_key_create_from_file (const char *filename) | ||
849 | { | ||
850 | struct GNUNET_CRYPTO_EcdsaPrivateKey *priv; | ||
851 | struct GNUNET_DISK_FileHandle *fd; | ||
852 | unsigned int cnt; | ||
853 | int ec; | ||
854 | uint64_t fs; | ||
855 | |||
856 | if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) | ||
857 | return NULL; | ||
858 | while (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
859 | { | ||
860 | fd = GNUNET_DISK_file_open (filename, | ||
861 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | ||
862 | | GNUNET_DISK_OPEN_FAILIFEXISTS, | ||
863 | GNUNET_DISK_PERM_USER_READ | | ||
864 | GNUNET_DISK_PERM_USER_WRITE); | ||
865 | if (NULL == fd) | ||
866 | { | ||
867 | if (EEXIST == errno) | ||
868 | { | ||
869 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
870 | { | ||
871 | /* must exist but not be accessible, fail for good! */ | ||
872 | if (0 != ACCESS (filename, R_OK)) | ||
873 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename); | ||
874 | else | ||
875 | GNUNET_break (0); /* what is going on!? */ | ||
876 | return NULL; | ||
877 | } | ||
878 | continue; | ||
879 | } | ||
880 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); | ||
881 | return NULL; | ||
882 | } | ||
883 | cnt = 0; | ||
884 | while (GNUNET_YES != | ||
885 | GNUNET_DISK_file_lock (fd, 0, | ||
886 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), | ||
887 | GNUNET_YES)) | ||
888 | { | ||
889 | short_wait (); | ||
890 | if (0 == ++cnt % 10) | ||
891 | { | ||
892 | ec = errno; | ||
893 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
894 | _("Could not acquire lock on file `%s': %s...\n"), filename, | ||
895 | STRERROR (ec)); | ||
896 | } | ||
897 | } | ||
898 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
899 | _("Creating a new private key. This may take a while.\n")); | ||
900 | priv = GNUNET_CRYPTO_ecdsa_key_create (); | ||
901 | GNUNET_assert (NULL != priv); | ||
902 | GNUNET_assert (sizeof (*priv) == | ||
903 | GNUNET_DISK_file_write (fd, priv, sizeof (*priv))); | ||
904 | GNUNET_DISK_file_sync (fd); | ||
905 | if (GNUNET_YES != | ||
906 | GNUNET_DISK_file_unlock (fd, 0, | ||
907 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) | ||
908 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
909 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); | ||
910 | return priv; | ||
911 | } | ||
912 | /* key file exists already, read it! */ | ||
913 | fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, | ||
914 | GNUNET_DISK_PERM_NONE); | ||
915 | if (NULL == fd) | ||
916 | { | ||
917 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); | ||
918 | return NULL; | ||
919 | } | ||
920 | cnt = 0; | ||
921 | while (1) | ||
922 | { | ||
923 | if (GNUNET_YES != | ||
924 | GNUNET_DISK_file_lock (fd, 0, | ||
925 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), | ||
926 | GNUNET_NO)) | ||
927 | { | ||
928 | if (0 == ++cnt % 60) | ||
929 | { | ||
930 | ec = errno; | ||
931 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
932 | _("Could not acquire lock on file `%s': %s...\n"), filename, | ||
933 | STRERROR (ec)); | ||
934 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
935 | _ | ||
936 | ("This may be ok if someone is currently generating a private key.\n")); | ||
937 | } | ||
938 | short_wait (); | ||
939 | continue; | ||
940 | } | ||
941 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
942 | { | ||
943 | /* eh, what!? File we opened is now gone!? */ | ||
944 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); | ||
945 | if (GNUNET_YES != | ||
946 | GNUNET_DISK_file_unlock (fd, 0, | ||
947 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) | ||
948 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
949 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); | ||
950 | |||
951 | return NULL; | ||
952 | } | ||
953 | if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) | ||
954 | fs = 0; | ||
955 | if (fs < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)) | ||
956 | { | ||
957 | /* maybe we got the read lock before the key generating | ||
958 | * process had a chance to get the write lock; give it up! */ | ||
959 | if (GNUNET_YES != | ||
960 | GNUNET_DISK_file_unlock (fd, 0, | ||
961 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) | ||
962 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
963 | if (0 == ++cnt % 10) | ||
964 | { | ||
965 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
966 | _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"), | ||
967 | filename, (unsigned int) fs, | ||
968 | (unsigned int) sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); | ||
969 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
970 | _("This may be ok if someone is currently generating a key.\n")); | ||
971 | } | ||
972 | short_wait (); /* wait a bit longer! */ | ||
973 | continue; | ||
974 | } | ||
975 | break; | ||
976 | } | ||
977 | fs = sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); | ||
978 | priv = GNUNET_malloc (fs); | ||
979 | GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs)); | ||
980 | if (GNUNET_YES != | ||
981 | GNUNET_DISK_file_unlock (fd, 0, | ||
982 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) | ||
983 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
984 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); | ||
985 | return priv; | ||
986 | } | ||
987 | |||
988 | |||
989 | /** | ||
990 | * Create a new private key by reading our peer's key from | ||
991 | * the file specified in the configuration. | ||
992 | * | ||
993 | * @param cfg the configuration to use | ||
994 | * @return new private key, NULL on error (for example, | ||
995 | * permission denied) | ||
996 | */ | ||
997 | struct GNUNET_CRYPTO_EddsaPrivateKey * | ||
998 | GNUNET_CRYPTO_eddsa_key_create_from_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
999 | { | ||
1000 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv; | ||
1001 | char *fn; | ||
1002 | |||
1003 | if (GNUNET_OK != | ||
1004 | GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &fn)) | ||
1005 | return NULL; | ||
1006 | priv = GNUNET_CRYPTO_eddsa_key_create_from_file (fn); | ||
1007 | GNUNET_free (fn); | ||
1008 | return priv; | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | /** | ||
1013 | * Setup a key file for a peer given the name of the | ||
1014 | * configuration file (!). This function is used so that | ||
1015 | * at a later point code can be certain that reading a | ||
1016 | * key is fast (for example in time-dependent testcases). | ||
1017 | * | ||
1018 | * @param cfg_name name of the configuration file to use | ||
1019 | */ | ||
1020 | void | ||
1021 | GNUNET_CRYPTO_eddsa_setup_key (const char *cfg_name) | ||
1022 | { | ||
1023 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
1024 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv; | ||
1025 | |||
1026 | cfg = GNUNET_CONFIGURATION_create (); | ||
1027 | (void) GNUNET_CONFIGURATION_load (cfg, cfg_name); | ||
1028 | priv = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); | ||
1029 | if (NULL != priv) | ||
1030 | GNUNET_free (priv); | ||
1031 | GNUNET_CONFIGURATION_destroy (cfg); | ||
1032 | } | ||
1033 | |||
1034 | |||
1035 | /** | ||
1036 | * Retrieve the identity of the host's peer. | ||
1037 | * | ||
1038 | * @param cfg configuration to use | ||
1039 | * @param dst pointer to where to write the peer identity | ||
1040 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity | ||
1041 | * could not be retrieved | ||
1042 | */ | ||
1043 | int | ||
1044 | GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
1045 | struct GNUNET_PeerIdentity *dst) | ||
1046 | { | ||
1047 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv; | ||
1048 | |||
1049 | if (NULL == (priv = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg))) | ||
1050 | { | ||
1051 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1052 | _("Could not load peer's private key\n")); | ||
1053 | return GNUNET_SYSERR; | ||
1054 | } | ||
1055 | GNUNET_CRYPTO_eddsa_key_get_public (priv, &dst->public_key); | ||
1056 | GNUNET_free (priv); | ||
1057 | return GNUNET_OK; | ||
1058 | } | ||
1059 | |||
1060 | |||
1061 | /** | ||
1062 | * Compare two Peer Identities. | 661 | * Compare two Peer Identities. |
1063 | * | 662 | * |
1064 | * @param first first peer identity | 663 | * @param first first peer identity |