From 1931869c3c64411ee4348c244e8b658493a2493d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 22 Nov 2020 19:02:49 +0100 Subject: [PATCH] more work on rsa crypto helper test --- src/util/crypto_helper.c | 4 +- src/util/taler-helper-crypto-rsa.c | 18 ++- src/util/test_helper_rsa.c | 236 ++++++++++++++++++++++++----- 3 files changed, 207 insertions(+), 51 deletions(-) diff --git a/src/util/crypto_helper.c b/src/util/crypto_helper.c index c42f01fc3..20ab61ff4 100644 --- a/src/util/crypto_helper.c +++ b/src/util/crypto_helper.c @@ -408,7 +408,7 @@ TALER_CRYPTO_helper_denom_sign ( ret = recv (dh->sock, buf, sizeof (buf), - MSG_DONTWAIT); + 0); if (ret < 0) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, @@ -468,6 +468,8 @@ TALER_CRYPTO_helper_denom_sign ( *ec = (enum TALER_ErrorCode) ntohl (sf->ec); break; } + // FIXME: *could* also receive change in key status! + // Handle that here, and then try again! default: GNUNET_break_op (0); do_disconnect (dh); diff --git a/src/util/taler-helper-crypto-rsa.c b/src/util/taler-helper-crypto-rsa.c index 2d57fe75a..6fda5fec1 100644 --- a/src/util/taler-helper-crypto-rsa.c +++ b/src/util/taler-helper-crypto-rsa.c @@ -430,11 +430,11 @@ sign_worker (void *cls) /* raise #done_signal */ if (sizeof(val) != - GNUNET_NETWORK_socket_send (done_signal, - &val, - sizeof (val))) + write (GNUNET_NETWORK_get_fd (done_signal), + &val, + sizeof (val))) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, - "send(eventfd)"); + "write(eventfd)"); } GNUNET_assert (0 == pthread_mutex_lock (&work_lock)); } @@ -533,11 +533,11 @@ handle_done (void *cls) /* consume #done_signal */ if (sizeof (data) != - GNUNET_NETWORK_socket_recv (done_signal, - &data, - sizeof (data))) + read (GNUNET_NETWORK_get_fd (done_signal), + &data, + sizeof (data))) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, - "recv(eventfd)"); + "read(eventfd)"); done_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, done_signal, &handle_done, @@ -618,6 +618,8 @@ handle_sign_request (const struct sockaddr_un *addr, &sf.header); return; } + // FIXME: check denomination key is valid for signing + // at this time! wi = GNUNET_new (struct WorkItem); wi->addr = *addr; diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c index 4cb4a5f18..14b3c4a56 100644 --- a/src/util/test_helper_rsa.c +++ b/src/util/test_helper_rsa.c @@ -75,9 +75,28 @@ struct KeyData bool revoked; }; +/** + * Array of all the keys we got from the helper. + */ static struct KeyData keys[MAX_KEYS]; +/** + * Function called with information about available keys for signing. Usually + * only called once per key upon connect. Also called again in case a key is + * being revoked, in that case with an @a end_time of zero. Stores the keys + * status in #keys. + * + * @param cls closure, NULL + * @param section_name name of the denomination type in the configuration; + * NULL if the key has been revoked or purged + * @param start_time when does the key become available for signing; + * zero if the key has been revoked or purged + * @param validity_duration how long does the key remain available for signing; + * zero if the key has been revoked or purged + * @param h_denom_pub hash of the @a denom_pub that is available (or was purged) + * @param denom_pub the public key itself, NULL if the key was revoked or purged + */ static void key_cb (void *cls, const char *section_name, @@ -136,54 +155,18 @@ key_cb (void *cls, /** - * Main entry point into the test logic with the helper already running. + * Test key revocation logic. + * + * @param dh handle to the helper + * @return 0 on success */ static int -run_test (void) +test_revocation (struct TALER_CRYPTO_DenominationHelper *dh) { - struct GNUNET_CONFIGURATION_Handle *cfg; - struct TALER_CRYPTO_DenominationHelper *dh; struct timespec req = { .tv_nsec = 250000000 }; - cfg = GNUNET_CONFIGURATION_create (); - if (GNUNET_OK != - GNUNET_CONFIGURATION_load (cfg, - "test_helper_rsa.conf")) - { - GNUNET_break (0); - return 77; - } - dh = TALER_CRYPTO_helper_denom_connect (cfg, - &key_cb, - NULL); - GNUNET_CONFIGURATION_destroy (cfg); - if (NULL == dh) - { - GNUNET_break (0); - return 1; - } - /* wait for helper to start and give us keys */ - fprintf (stderr, "Waiting for helper to start "); - for (unsigned int i = 0; i<80; i++) - { - TALER_CRYPTO_helper_poll (dh); - if (0 != num_keys) - break; - nanosleep (&req, NULL); - fprintf (stderr, "."); - } - if (0 == num_keys) - { - fprintf (stderr, - "\nFAILED: timeout trying to connect to helper\n"); - TALER_CRYPTO_helper_denom_disconnect (dh); - return 1; - } - fprintf (stderr, - "\nOK: Helper ready (%u keys)\n", - num_keys); for (unsigned int i = 0; i + GNUNET_TIME_UNIT_SECONDS.rel_value_us) + { + /* key worked too early */ + GNUNET_break (0); + return 4; + } + if (GNUNET_TIME_absolute_get_duration (keys[i].start_time).rel_value_us > + keys[i].validity_duration.rel_value_us) + { + /* key worked too later */ + GNUNET_break (0); + return 5; + } + if (GNUNET_OK != + GNUNET_CRYPTO_rsa_verify (&m_hash, + ds.rsa_signature, + keys[i].denom_pub.rsa_public_key)) + { + /* signature invalid */ + GNUNET_break (0); + GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature); + return 6; + } + GNUNET_CRYPTO_rsa_signature_free (ds.rsa_signature); + success = true; + break; +#if FIXME + case TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_INVALID: + if ( (0 == + GNUNET_TIME_absolute_get_remaining ( + keys[i].start_time).rel_value_us) && + (GNUNET_TIME_absolute_get_duration ( + keys[i].start_time).rel_value_us < + keys[i].validity_duration.rel_value_us) ) + { + /* key should have worked! */ + GNUNET_break (0); + return 6; + } + break; +#endif + default: + /* unexpected error */ + GNUNET_break (0); + return 7; + } + } + if (! success) + { + /* no valid key for signing found, also bad */ + GNUNET_break (0); + return 16; + } + + /* check signing does not work if the key is unknown */ + { + struct GNUNET_HashCode rnd; + + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, + &rnd, + sizeof (rnd)); + (void) TALER_CRYPTO_helper_denom_sign (dh, + &rnd, + "Hello", + strlen ("Hello"), + &ec); + if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec) + { + GNUNET_break (0); + return 17; + } + } + return 0; +} + + +/** + * Main entry point into the test logic with the helper already running. + */ +static int +run_test (void) +{ + struct GNUNET_CONFIGURATION_Handle *cfg; + struct TALER_CRYPTO_DenominationHelper *dh; + struct timespec req = { + .tv_nsec = 250000000 + }; + int ret; + + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_OK != + GNUNET_CONFIGURATION_load (cfg, + "test_helper_rsa.conf")) + { + GNUNET_break (0); + return 77; + } + dh = TALER_CRYPTO_helper_denom_connect (cfg, + &key_cb, + NULL); + GNUNET_CONFIGURATION_destroy (cfg); + if (NULL == dh) + { + GNUNET_break (0); + return 1; + } + /* wait for helper to start and give us keys */ + fprintf (stderr, "Waiting for helper to start "); + for (unsigned int i = 0; i<80; i++) + { + TALER_CRYPTO_helper_poll (dh); + if (0 != num_keys) + break; + nanosleep (&req, NULL); + fprintf (stderr, "."); + } + if (0 == num_keys) + { + fprintf (stderr, + "\nFAILED: timeout trying to connect to helper\n"); + TALER_CRYPTO_helper_denom_disconnect (dh); + return 1; + } + fprintf (stderr, + "\nOK: Helper ready (%u keys)\n", + num_keys); + + ret = 0; +#if 1 + if (0 == ret) + ret = test_revocation (dh); +#endif +#if 0 + if (0 == ret) + ret = test_signing (dh); +#endif + TALER_CRYPTO_helper_denom_disconnect (dh); /* clean up our state */ for (unsigned int i = 0; i 0); num_keys--; } - return 0; + return ret; }