diff options
Diffstat (limited to 'src/util/gnunet-rsa.c')
-rw-r--r-- | src/util/gnunet-rsa.c | 142 |
1 files changed, 136 insertions, 6 deletions
diff --git a/src/util/gnunet-rsa.c b/src/util/gnunet-rsa.c index f3cd83a..917ee50 100644 --- a/src/util/gnunet-rsa.c +++ b/src/util/gnunet-rsa.c @@ -25,6 +25,8 @@ */ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet_testing_lib.h" +#include <gcrypt.h> /** @@ -42,6 +44,112 @@ static int print_peer_identity; */ static int print_short_identity; +/** + * Use weak random number generator for key generation. + */ +static int weak_random; + +/** + * Option set to create a bunch of keys at once. + */ +static unsigned int make_keys; + +/** + * The private information of an RSA key pair. + * NOTE: this must match the definition in crypto_ksk.c and crypto_rsa.c! + */ +struct GNUNET_CRYPTO_RsaPrivateKey +{ + gcry_sexp_t sexp; +}; + + +/** + * Create a new private key. Caller must free return value. + * + * @return fresh private key + */ +static struct GNUNET_CRYPTO_RsaPrivateKey * +rsa_key_create () +{ + struct GNUNET_CRYPTO_RsaPrivateKey *ret; + gcry_sexp_t s_key; + gcry_sexp_t s_keyparam; + + GNUNET_assert (0 == + gcry_sexp_build (&s_keyparam, NULL, + "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))", + 2048)); + GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam)); + gcry_sexp_release (s_keyparam); +#if EXTRA_CHECKS + GNUNET_assert (0 == gcry_pk_testkey (s_key)); +#endif + ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); + ret->sexp = s_key; + return ret; +} + + +/** + * Create a flat file with a large number of key pairs for testing. + */ +static void +create_keys (const char *fn) +{ + FILE *f; + struct GNUNET_CRYPTO_RsaPrivateKey *pk; + struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc; + + if (NULL == (f = fopen (fn, "w+"))) + { + fprintf (stderr, + _("Failed to open `%s': %s\n"), + fn, + STRERROR (errno)); + return; + } + fprintf (stderr, + _("Generating %u keys, please wait"), + make_keys); + while (0 < make_keys--) + { + fprintf (stderr, + "."); + if (NULL == (pk = rsa_key_create ())) + { + GNUNET_break (0); + break; + } + enc = GNUNET_CRYPTO_rsa_encode_key (pk); + if (GNUNET_TESTING_HOSTKEYFILESIZE != htons (enc->len)) + { + /* sometimes we get a different key length because 'd' or 'u' start + with leading bits; skip those... */ + GNUNET_CRYPTO_rsa_key_free (pk); + GNUNET_free (enc); + make_keys++; + continue; + } + if (htons (enc->len) != fwrite (enc, 1, htons (enc->len), f)) + { + fprintf (stderr, + _("\nFailed to write to `%s': %s\n"), + fn, + STRERROR (errno)); + GNUNET_CRYPTO_rsa_key_free (pk); + GNUNET_free (enc); + break; + } + GNUNET_CRYPTO_rsa_key_free (pk); + GNUNET_free (enc); + } + if (0 == make_keys) + fprintf (stderr, + _("Finished!\n")); + fclose (f); +} + /** * Main function that will be run by the scheduler. @@ -64,7 +172,16 @@ run (void *cls, char *const *args, const char *cfgfile, fprintf (stderr, _("No hostkey file specified on command line\n")); return; } + if (0 != weak_random) + GNUNET_CRYPTO_random_disable_entropy_gathering (); + if (make_keys > 0) + { + create_keys (args[0]); + return; + } pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]); + if (NULL == pk) + return; if (print_public_key) { char *s; @@ -98,16 +215,19 @@ run (void *cls, char *const *args, const char *cfgfile, /** - * The main function to obtain statistics in GNUnet. + * Program to manipulate RSA key files. * * @param argc number of arguments from the command line * @param argv command line arguments * @return 0 ok, 1 on error */ int -main (int argc, char *const *argv) +main (int argc, char *const*argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { + { 'g', "generate-keys", "COUNT", + gettext_noop ("create COUNT public-private key pairs (for testing)"), + 1, &GNUNET_GETOPT_set_uint, &make_keys }, { 'p', "print-public-key", NULL, gettext_noop ("print the public key in ASCII format"), 0, &GNUNET_GETOPT_set_one, &print_public_key }, @@ -117,12 +237,22 @@ main (int argc, char *const *argv) { 's', "print-short-identity", NULL, gettext_noop ("print the short hash of the public key in ASCII format"), 0, &GNUNET_GETOPT_set_one, &print_short_identity }, + { 'w', "weak-random", NULL, + gettext_noop ("use insecure, weak random number generator for key generation (for testing only)"), + 0, &GNUNET_GETOPT_set_one, &weak_random }, GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-rsa [OPTIONS] keyfile", - gettext_noop ("Manipulate GNUnet private RSA key files"), - options, &run, NULL)) ? 0 : 1; + int ret; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-rsa [OPTIONS] keyfile", + gettext_noop ("Manipulate GNUnet private RSA key files"), + options, &run, NULL)) ? 0 : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-rsa.c */ |