From 7aa23a39bd844e5fab4f82c66741fa584e2f6074 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 12 Sep 2017 15:34:38 +0200 Subject: add support for #4840 (/keys cherry picking) to libtalerexchange --- src/exchange-lib/exchange_api_handle.c | 116 ++++++++++++++++++++-------- src/exchangedb/plugin_exchangedb_postgres.c | 10 +++ src/include/taler_exchange_service.h | 12 ++- 3 files changed, 104 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/exchange-lib/exchange_api_handle.c b/src/exchange-lib/exchange_api_handle.c index a03f7d4ba..c028b9a9c 100644 --- a/src/exchange-lib/exchange_api_handle.c +++ b/src/exchange-lib/exchange_api_handle.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. + Copyright (C) 2014-2017 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -436,7 +436,7 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor, GNUNET_JSON_parse (key, kspec, NULL, NULL)) - { + { GNUNET_break_op (0); continue; } @@ -509,32 +509,22 @@ decode_keys_json (const json_t *resp_obj, struct TALER_ExchangeKeySetPS ks; struct GNUNET_HashContext *hash_context; struct TALER_ExchangePublicKeyP pub; + unsigned int age; + unsigned int revision; + unsigned int current; - /* FIXME: #4840: handle incremental / cherry-picked /keys! */ memset (key_data, 0, sizeof (struct TALER_EXCHANGE_Keys)); if (JSON_OBJECT != json_typeof (resp_obj)) return GNUNET_SYSERR; - hash_context = GNUNET_CRYPTO_hash_context_start (); - /* parse the master public key and issue date of the response */ + /* check the version */ { const char *ver; - unsigned int age; - unsigned int revision; - unsigned int current; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("version", &ver), - GNUNET_JSON_spec_fixed_auto ("master_public_key", - &key_data->master_pub), - GNUNET_JSON_spec_fixed_auto ("eddsa_sig", - &sig), - GNUNET_JSON_spec_fixed_auto ("eddsa_pub", - &pub), - GNUNET_JSON_spec_absolute_time ("list_issue_date", - &list_issue_date), GNUNET_JSON_spec_end() }; @@ -549,7 +539,6 @@ decode_keys_json (const json_t *resp_obj, &age)) { GNUNET_break_op (0); - GNUNET_CRYPTO_hash_context_abort (hash_context); return GNUNET_SYSERR; } *vc = TALER_EXCHANGE_VC_MATCH; @@ -568,6 +557,27 @@ decode_keys_json (const json_t *resp_obj, key_data->version = GNUNET_strdup (ver); } + /* parse the master public key and issue date of the response */ + hash_context = GNUNET_CRYPTO_hash_context_start (); + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ("master_public_key", + &key_data->master_pub), + GNUNET_JSON_spec_fixed_auto ("eddsa_sig", + &sig), + GNUNET_JSON_spec_fixed_auto ("eddsa_pub", + &pub), + GNUNET_JSON_spec_absolute_time ("list_issue_date", + &list_issue_date), + GNUNET_JSON_spec_end() + }; + + EXITIF (GNUNET_OK != + GNUNET_JSON_parse (resp_obj, + spec, + NULL, NULL)); + } + /* parse the signing keys */ { json_t *sign_keys_array; @@ -578,17 +588,37 @@ decode_keys_json (const json_t *resp_obj, json_object_get (resp_obj, "signkeys"))); EXITIF (JSON_ARRAY != json_typeof (sign_keys_array)); - EXITIF (0 == (key_data->num_sign_keys = - json_array_size (sign_keys_array))); - key_data->sign_keys - = GNUNET_new_array (key_data->num_sign_keys, - struct TALER_EXCHANGE_SigningPublicKey); + index = 0; json_array_foreach (sign_keys_array, index, sign_key_obj) { + struct TALER_EXCHANGE_SigningPublicKey sk; + bool found = false; + EXITIF (GNUNET_SYSERR == - parse_json_signkey (&key_data->sign_keys[index], + parse_json_signkey (&sk, sign_key_obj, &key_data->master_pub)); + for (unsigned int j=0;jnum_sign_keys;j++) + { + if (0 == memcmp (&sk, + &key_data->sign_keys[j], + sizeof (sk))) + { + found = true; + break; + } + } + if (found) + { + /* 0:0:0 did not support /keys cherry picking */ + GNUNET_break_op (0 == current); + continue; + } + if (key_data->sign_keys_size == key_data->num_sign_keys) + GNUNET_array_grow (key_data->sign_keys, + key_data->sign_keys_size, + key_data->sign_keys_size * 2 + 2); + key_data->sign_keys[key_data->num_sign_keys++] = sk; } } @@ -601,21 +631,41 @@ decode_keys_json (const json_t *resp_obj, EXITIF (NULL == (denom_keys_array = json_object_get (resp_obj, "denoms"))); EXITIF (JSON_ARRAY != json_typeof (denom_keys_array)); - if (0 == (key_data->num_denom_keys = json_array_size (denom_keys_array))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Found no denomination keys at this exchange\n"); - goto EXITIF_exit; - } + key_data->denom_keys = GNUNET_new_array (key_data->num_denom_keys, struct TALER_EXCHANGE_DenomPublicKey); + index = 0; json_array_foreach (denom_keys_array, index, denom_key_obj) { + struct TALER_EXCHANGE_DenomPublicKey dk; + bool found = false; + EXITIF (GNUNET_SYSERR == - parse_json_denomkey (&key_data->denom_keys[index], + parse_json_denomkey (&dk, denom_key_obj, &key_data->master_pub, hash_context)); + for (unsigned int j=0;jnum_denom_keys;j++) + { + if (0 == memcmp (&dk, + &key_data->denom_keys[j], + sizeof (dk))) + { + found = true; + break; + } + } + if (found) + { + /* 0:0:0 did not support /keys cherry picking */ + GNUNET_break_op (0 == current); + continue; + } + if (key_data->denom_keys_size == key_data->num_denom_keys) + GNUNET_array_grow (key_data->denom_keys, + key_data->denom_keys_size, + key_data->denom_keys_size * 2 + 2); + key_data->denom_keys[key_data->num_denom_keys++] = dk; } } @@ -655,7 +705,7 @@ decode_keys_json (const json_t *resp_obj, hash_context = NULL; EXITIF (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_data, - &pub)); + &pub)); EXITIF (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET, &ks.purpose, @@ -679,12 +729,12 @@ static void free_key_data (struct TALER_EXCHANGE_Keys *key_data) { GNUNET_array_grow (key_data->sign_keys, - key_data->num_sign_keys, + key_data->sign_keys_size, 0); for (unsigned int i=0;inum_denom_keys;i++) GNUNET_CRYPTO_rsa_public_key_free (key_data->denom_keys[i].key.rsa_public_key); GNUNET_array_grow (key_data->denom_keys, - key_data->num_denom_keys, + key_data->denom_keys_size, 0); for (unsigned int i=0;inum_auditors;i++) { diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 016ba26c3..b4d510384 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -2704,6 +2704,11 @@ postgres_get_ready_deposit (void *cls, }; enum GNUNET_DB_QueryStatus qs; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Finding ready deposits by deadline %s (%llu)\n", + GNUNET_STRINGS_absolute_time_to_string (now), + (unsigned long long) now.abs_value_us); + qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn, "deposits_get_ready", params, @@ -3027,6 +3032,11 @@ postgres_insert_deposit (void *cls, session, &deposit->coin))) return qs; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Inserting deposit to be executed at %s (%llu/%llu)\n", + GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline), + (unsigned long long) deposit->wire_deadline.abs_value_us, + (unsigned long long) deposit->refund_deadline.abs_value_us); return GNUNET_PQ_eval_prepared_non_select (session->conn, "insert_deposit", params); diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 487304c59..c4c41c027 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -213,7 +213,7 @@ struct TALER_EXCHANGE_Keys struct GNUNET_TIME_Absolute last_issue_date; /** - * Length of the @e sign_keys array. + * Length of the @e sign_keys array (number of valid entries). */ unsigned int num_sign_keys; @@ -227,6 +227,16 @@ struct TALER_EXCHANGE_Keys */ unsigned int num_auditors; + /** + * Actual length of the @e sign_keys array (size of allocation). + */ + unsigned int sign_keys_size; + + /** + * Actual length of the @e denom_keys array (size of allocation). + */ + unsigned int denom_keys_size; + }; -- cgit v1.2.3