diff options
Diffstat (limited to 'src/lib/exchange_api_management_get_keys.c')
-rw-r--r-- | src/lib/exchange_api_management_get_keys.c | 240 |
1 files changed, 134 insertions, 106 deletions
diff --git a/src/lib/exchange_api_management_get_keys.c b/src/lib/exchange_api_management_get_keys.c index e9cab5810..b88ddc205 100644 --- a/src/lib/exchange_api_management_get_keys.c +++ b/src/lib/exchange_api_management_get_keys.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015-2020 Taler Systems SA + Copyright (C) 2015-2023 Taler Systems SA 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 @@ -23,9 +23,10 @@ #include "taler_json_lib.h" #include <gnunet/gnunet_curl_lib.h> #include "taler_exchange_service.h" +#include "exchange_api_curl_defaults.h" #include "taler_signatures.h" #include "taler_curl_lib.h" -#include "taler_crypto_lib.h" +#include "taler_util.h" #include "taler_json_lib.h" /** @@ -74,25 +75,32 @@ struct TALER_EXCHANGE_ManagementGetKeysHandle * @param response the response * @return #GNUNET_OK if the response was well-formed */ -static int +static enum GNUNET_GenericReturnValue handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, const json_t *response) { - struct TALER_EXCHANGE_FutureKeys fk; - json_t *sk; - json_t *dk; + struct TALER_EXCHANGE_ManagementGetKeysResponse gkr = { + .hr.http_status = MHD_HTTP_OK, + .hr.reply = response, + }; + struct TALER_EXCHANGE_FutureKeys *fk + = &gkr.details.ok.keys; + const json_t *sk; + const json_t *dk; bool ok; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("future_denoms", - &dk), - GNUNET_JSON_spec_json ("future_signkeys", - &sk), + GNUNET_JSON_spec_array_const ("future_denoms", + &dk), + GNUNET_JSON_spec_array_const ("future_signkeys", + &sk), GNUNET_JSON_spec_fixed_auto ("master_pub", - &fk.master_pub), + &fk->master_pub), GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key", - &fk.denom_secmod_public_key), + &fk->denom_secmod_public_key), + GNUNET_JSON_spec_fixed_auto ("denom_secmod_cs_public_key", + &fk->denom_secmod_cs_public_key), GNUNET_JSON_spec_fixed_auto ("signkey_secmod_public_key", - &fk.signkey_secmod_public_key), + &fk->signkey_secmod_public_key), GNUNET_JSON_spec_end () }; @@ -104,38 +112,38 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, GNUNET_break_op (0); return GNUNET_SYSERR; } - fk.num_sign_keys = json_array_size (sk); - fk.num_denom_keys = json_array_size (dk); - fk.sign_keys = GNUNET_new_array ( - fk.num_sign_keys, + fk->num_sign_keys = json_array_size (sk); + fk->num_denom_keys = json_array_size (dk); + fk->sign_keys = GNUNET_new_array ( + fk->num_sign_keys, struct TALER_EXCHANGE_FutureSigningPublicKey); - fk.denom_keys = GNUNET_new_array ( - fk.num_denom_keys, + fk->denom_keys = GNUNET_new_array ( + fk->num_denom_keys, struct TALER_EXCHANGE_FutureDenomPublicKey); ok = true; - for (unsigned int i = 0; i<fk.num_sign_keys; i++) + for (unsigned int i = 0; i<fk->num_sign_keys; i++) { json_t *j = json_array_get (sk, i); struct TALER_EXCHANGE_FutureSigningPublicKey *sign_key - = &fk.sign_keys[i]; - struct GNUNET_JSON_Specification spec[] = { + = &fk->sign_keys[i]; + struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ("key", &sign_key->key), GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig", &sign_key->signkey_secmod_sig), - TALER_JSON_spec_absolute_time ("stamp_start", - &sign_key->valid_from), - TALER_JSON_spec_absolute_time ("stamp_expire", - &sign_key->valid_until), - TALER_JSON_spec_absolute_time ("stamp_end", - &sign_key->valid_legal), + GNUNET_JSON_spec_timestamp ("stamp_start", + &sign_key->valid_from), + GNUNET_JSON_spec_timestamp ("stamp_expire", + &sign_key->valid_until), + GNUNET_JSON_spec_timestamp ("stamp_end", + &sign_key->valid_legal), GNUNET_JSON_spec_end () }; if (GNUNET_OK != GNUNET_JSON_parse (j, - spec, + ispec, NULL, NULL)) { GNUNET_break_op (0); @@ -144,15 +152,15 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, } { struct GNUNET_TIME_Relative duration - = GNUNET_TIME_absolute_get_difference (sign_key->valid_from, - sign_key->valid_until); + = GNUNET_TIME_absolute_get_difference (sign_key->valid_from.abs_time, + sign_key->valid_until.abs_time); if (GNUNET_OK != TALER_exchange_secmod_eddsa_verify ( &sign_key->key, sign_key->valid_from, duration, - &fk.signkey_secmod_public_key, + &fk->signkey_secmod_public_key, &sign_key->signkey_secmod_sig)) { GNUNET_break_op (0); @@ -161,26 +169,26 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, } } } - for (unsigned int i = 0; i<fk.num_denom_keys; i++) + for (unsigned int i = 0; i<fk->num_denom_keys; i++) { json_t *j = json_array_get (dk, i); struct TALER_EXCHANGE_FutureDenomPublicKey *denom_key - = &fk.denom_keys[i]; + = &fk->denom_keys[i]; const char *section_name; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount_any ("value", &denom_key->value), - TALER_JSON_spec_absolute_time ("stamp_start", - &denom_key->valid_from), - TALER_JSON_spec_absolute_time ("stamp_expire_withdraw", - &denom_key->withdraw_valid_until), - TALER_JSON_spec_absolute_time ("stamp_expire_deposit", - &denom_key->expire_deposit), - TALER_JSON_spec_absolute_time ("stamp_expire_legal", - &denom_key->expire_legal), - GNUNET_JSON_spec_rsa_public_key ("denom_pub", - &denom_key->key.rsa_public_key), + GNUNET_JSON_spec_timestamp ("stamp_start", + &denom_key->valid_from), + GNUNET_JSON_spec_timestamp ("stamp_expire_withdraw", + &denom_key->withdraw_valid_until), + GNUNET_JSON_spec_timestamp ("stamp_expire_deposit", + &denom_key->expire_deposit), + GNUNET_JSON_spec_timestamp ("stamp_expire_legal", + &denom_key->expire_legal), + TALER_JSON_spec_denom_pub ("denom_pub", + &denom_key->key), TALER_JSON_spec_amount_any ("fee_withdraw", &denom_key->fee_withdraw), TALER_JSON_spec_amount_any ("fee_deposit", @@ -212,51 +220,76 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, } { + struct TALER_DenominationHashP h_denom_pub; struct GNUNET_TIME_Relative duration - = GNUNET_TIME_absolute_get_difference (denom_key->valid_from, - denom_key->withdraw_valid_until); - struct GNUNET_HashCode h_denom_pub; + = GNUNET_TIME_absolute_get_difference ( + denom_key->valid_from.abs_time, + denom_key->withdraw_valid_until.abs_time); - GNUNET_CRYPTO_rsa_public_key_hash (denom_key->key.rsa_public_key, - &h_denom_pub); - if (GNUNET_OK != - TALER_exchange_secmod_rsa_verify (&h_denom_pub, - section_name, - denom_key->valid_from, - duration, - &fk.denom_secmod_public_key, - &denom_key->denom_secmod_sig)) + TALER_denom_pub_hash (&denom_key->key, + &h_denom_pub); + switch (denom_key->key.bsign_pub_key->cipher) { + case GNUNET_CRYPTO_BSA_RSA: + { + struct TALER_RsaPubHashP h_rsa; + + TALER_rsa_pub_hash ( + denom_key->key.bsign_pub_key->details.rsa_public_key, + &h_rsa); + if (GNUNET_OK != + TALER_exchange_secmod_rsa_verify (&h_rsa, + section_name, + denom_key->valid_from, + duration, + &fk->denom_secmod_public_key, + &denom_key->denom_secmod_sig)) + { + GNUNET_break_op (0); + ok = false; + break; + } + } + break; + case GNUNET_CRYPTO_BSA_CS: + { + struct TALER_CsPubHashP h_cs; + + TALER_cs_pub_hash ( + &denom_key->key.bsign_pub_key->details.cs_public_key, + &h_cs); + if (GNUNET_OK != + TALER_exchange_secmod_cs_verify (&h_cs, + section_name, + denom_key->valid_from, + duration, + &fk->denom_secmod_cs_public_key, + &denom_key->denom_secmod_sig)) + { + GNUNET_break_op (0); + ok = false; + break; + } + } + break; + default: GNUNET_break_op (0); ok = false; break; } } - GNUNET_JSON_parse_free (spec); + if (! ok) + break; } if (ok) { - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = MHD_HTTP_OK, - .reply = response - }; - gh->cb (gh->cb_cls, - &hr, - &fk); - } - for (unsigned int i = 0; i<fk.num_denom_keys; i++) - { - if (NULL != fk.denom_keys[i].key.rsa_public_key) - { - GNUNET_CRYPTO_rsa_public_key_free ( - fk.denom_keys[i].key.rsa_public_key); - fk.denom_keys[i].key.rsa_public_key = NULL; - } + &gkr); } - GNUNET_free (fk.sign_keys); - GNUNET_free (fk.denom_keys); - GNUNET_JSON_parse_free (spec); + for (unsigned int i = 0; i<fk->num_denom_keys; i++) + TALER_denom_pub_free (&fk->denom_keys[i].key); + GNUNET_free (fk->sign_keys); + GNUNET_free (fk->denom_keys); return (ok) ? GNUNET_OK : GNUNET_SYSERR; } @@ -276,9 +309,9 @@ handle_get_keys_finished (void *cls, { struct TALER_EXCHANGE_ManagementGetKeysHandle *gh = cls; const json_t *json = response; - struct TALER_EXCHANGE_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_EXCHANGE_ManagementGetKeysResponse gkr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; gh->job = NULL; @@ -296,45 +329,49 @@ handle_get_keys_finished (void *cls, response_code = 0; } break; + case MHD_HTTP_NOT_FOUND: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n", + gh->url); + if (NULL != json) + { + gkr.hr.ec = TALER_JSON_get_error_code (json); + gkr.hr.hint = TALER_JSON_get_error_hint (json); + } + else + { + gkr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + gkr.hr.hint = TALER_ErrorCode_get_hint (gkr.hr.ec); + } + break; default: /* unexpected response code */ if (NULL != json) { - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + gkr.hr.ec = TALER_JSON_get_error_code (json); + gkr.hr.hint = TALER_JSON_get_error_hint (json); } else { - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - hr.hint = TALER_ErrorCode_get_hint (hr.ec); + gkr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + gkr.hr.hint = TALER_ErrorCode_get_hint (gkr.hr.ec); } GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d for exchange management get keys\n", (unsigned int) response_code, - (int) hr.ec); + (int) gkr.hr.ec); break; } if (NULL != gh->cb) { gh->cb (gh->cb_cls, - &hr, - NULL); + &gkr); gh->cb = NULL; } TALER_EXCHANGE_get_management_keys_cancel (gh); }; -/** - * Request future keys from the exchange. The obtained information will be - * passed to the @a cb. - * - * @param ctx the context - * @param url HTTP base URL for the exchange - * @param cb function to call with the exchange's future keys result - * @param cb_cls closure for @a cb - * @return the request handle; NULL upon error - */ struct TALER_EXCHANGE_ManagementGetKeysHandle * TALER_EXCHANGE_get_management_keys (struct GNUNET_CURL_Context *ctx, const char *url, @@ -358,14 +395,10 @@ TALER_EXCHANGE_get_management_keys (struct GNUNET_CURL_Context *ctx, GNUNET_free (gh); return NULL; } - eh = curl_easy_init (); + eh = TALER_EXCHANGE_curl_easy_get_ (gh->url); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting URL '%s'\n", gh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_URL, - gh->url)); gh->job = GNUNET_CURL_job_add (ctx, eh, &handle_get_keys_finished, @@ -379,11 +412,6 @@ TALER_EXCHANGE_get_management_keys (struct GNUNET_CURL_Context *ctx, } -/** - * Cancel #TALER_EXCHANGE_get_management_keys() operation. - * - * @param gh handle of the operation to cancel - */ void TALER_EXCHANGE_get_management_keys_cancel ( struct TALER_EXCHANGE_ManagementGetKeysHandle *gh) |