From d153d8036ea14503f812717b8994a4a845ab643e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 23 Aug 2021 18:22:06 +0200 Subject: -more work on iban logic --- src/stasis/plugin_anastasis_postgres.c | 135 ++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) (limited to 'src/stasis/plugin_anastasis_postgres.c') diff --git a/src/stasis/plugin_anastasis_postgres.c b/src/stasis/plugin_anastasis_postgres.c index 8c06243..506c304 100644 --- a/src/stasis/plugin_anastasis_postgres.c +++ b/src/stasis/plugin_anastasis_postgres.c @@ -38,6 +38,12 @@ */ #define MAX_RETRIES 3 +/** + * Maximum value allowed for nonces. Limited to 2^52 to ensure the + * numeric value survives a conversion to float by JavaScript. + */ +#define NONCE_MAX_VALUE (1LLU << 52) + /** * Type of the "cls" argument given to each of the functions in @@ -2125,7 +2131,7 @@ postgres_create_challenge_code ( } *code = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, - INT64_MAX); + NONCE_MAX_VALUE); *retransmission_date = GNUNET_TIME_UNIT_ZERO_ABS; { struct GNUNET_PQ_QueryParam params[] = { @@ -2168,6 +2174,132 @@ retry: } +/** + * Setup challenge code for a given challenge identified by the + * challenge public key. The function will first check if there is + * already a valid code for this challenge present and won't insert + * a new one in this case. This variant is not rate-limited, will + * return the existing challenge if it has not yet expired and will + * simply create new challenges when the old ones need to be + * rotated. + * + * @param cls closure + * @param truth_uuid the identifier for the challenge + * @param rotation_period for how long is the code available + * @param validity_period for how long is the code available + * @param[out] code set to the code which will be checked for later + * @return transaction status, + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if @a code is now in the DB + */ +static enum GNUNET_DB_QueryStatus +postgres_get_unlimited_challenge_code ( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + struct GNUNET_TIME_Relative rotation_period, + struct GNUNET_TIME_Relative validity_period, + uint64_t *code) +{ + struct PostgresClosure *pg = cls; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); + struct GNUNET_TIME_Absolute expiration_date; + struct GNUNET_TIME_Absolute ex_rot; + + check_connection (pg); + GNUNET_TIME_round_abs (&now); + expiration_date = GNUNET_TIME_absolute_add (now, + validity_period); + ex_rot = GNUNET_TIME_absolute_subtract (now, + rotation_period); + for (unsigned int retries = 0; retriesconn, + "challengecode_select_meta", + params, + rs); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + rollback (pg); + return qs; + case GNUNET_DB_STATUS_SOFT_ERROR: + goto retry; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + /* no active challenge, create fresh one (below) */ + break; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + rollback (pg); + return qs; + } + } + + *code = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, + NONCE_MAX_VALUE); + { + uint32_t retry_counter = UINT32_MAX; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (truth_uuid), + GNUNET_PQ_query_param_uint64 (code), + TALER_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_absolute_time (&expiration_date), + GNUNET_PQ_query_param_uint32 (&retry_counter), + GNUNET_PQ_query_param_end + }; + + qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, + "challengecode_insert", + params); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + rollback (pg); + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_DB_STATUS_SOFT_ERROR: + goto retry; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); + rollback (pg); + return GNUNET_DB_STATUS_HARD_ERROR; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } + } + qs = commit_transaction (pg); + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + goto retry; + if (qs < 0) + return qs; + return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; +retry: + rollback (pg); + } + return GNUNET_DB_STATUS_SOFT_ERROR; +} + + /** * Remember in the database that we successfully sent a challenge. * @@ -2675,6 +2807,7 @@ libanastasis_plugin_db_postgres_init (void *cls) plugin->test_challenge_code_satisfied = &postgres_test_challenge_code_satisfied; plugin->create_challenge_code = &postgres_create_challenge_code; + plugin->get_unlimited_challenge_code = &postgres_get_unlimited_challenge_code; plugin->mark_challenge_sent = &postgres_mark_challenge_sent; plugin->challenge_gc = &postgres_challenge_gc; plugin->record_truth_upload_payment = &postgres_record_truth_upload_payment; -- cgit v1.2.3