From 074ea7502e93b290f9300974f5a349a8de4f4753 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 29 Mar 2022 15:21:49 +0200 Subject: [PATCH] centralize exchange online signature logic --- ...taler-auditor-httpd_deposit-confirmation.c | 23 +- src/exchange/taler-exchange-httpd_deposit.c | 53 +- .../taler-exchange-httpd_deposits_get.c | 40 +- src/exchange/taler-exchange-httpd_keys.c | 21 +- src/exchange/taler-exchange-httpd_keys.h | 4 +- src/exchange/taler-exchange-httpd_kyc-check.c | 16 +- src/exchange/taler-exchange-httpd_melt.c | 15 +- src/exchange/taler-exchange-httpd_refund.c | 22 +- src/exchange/taler-exchange-httpd_responses.c | 188 +-- .../taler-exchange-httpd_transfers_get.c | 47 +- src/include/taler_crypto_lib.h | 672 +++++++++- src/include/taler_signatures.h | 761 ----------- src/lib/auditor_api_deposit_confirmation.c | 23 +- src/lib/exchange_api_common.c | 169 +-- src/lib/exchange_api_deposit.c | 23 +- src/lib/exchange_api_deposits_get.c | 66 +- src/lib/exchange_api_handle.c | 18 +- src/lib/exchange_api_kyc_check.c | 18 +- src/lib/exchange_api_melt.c | 2 +- src/lib/exchange_api_refund.c | 107 +- src/lib/exchange_api_transfers_get.c | 61 +- src/util/auditor_signatures.c | 83 ++ src/util/exchange_signatures.c | 1125 ++++++++++++++++- src/util/secmod_signatures.c | 66 + 24 files changed, 2322 insertions(+), 1301 deletions(-) diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c index 7f4d4286c..6042b7409 100644 --- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c +++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c @@ -182,17 +182,18 @@ verify_and_execute_deposit_confirmation ( /* check deposit confirmation signature */ if (GNUNET_OK != - TALER_exchange_deposit_confirm_verify (&dc->h_contract_terms, - &dc->h_wire, - NULL /* h_extensions! */, - dc->exchange_timestamp, - dc->wire_deadline, - dc->refund_deadline, - &dc->amount_without_fee, - &dc->coin_pub, - &dc->merchant, - &dc->exchange_pub, - &dc->exchange_sig)) + TALER_exchange_online_deposit_confirmation_verify ( + &dc->h_contract_terms, + &dc->h_wire, + NULL /* h_extensions! */, + dc->exchange_timestamp, + dc->wire_deadline, + dc->refund_deadline, + &dc->amount_without_fee, + &dc->coin_pub, + &dc->merchant, + &dc->exchange_pub, + &dc->exchange_sig)) { TALER_LOG_WARNING ( "Invalid signature on /deposit-confirmation request\n"); diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 00353a401..59d25904f 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -57,41 +57,36 @@ * @return MHD result code */ static MHD_RESULT -reply_deposit_success (struct MHD_Connection *connection, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_MerchantWireHashP *h_wire, - const struct TALER_ExtensionContractHashP *h_extensions, - const struct - TALER_PrivateContractHashP *h_contract_terms, - struct GNUNET_TIME_Timestamp exchange_timestamp, - struct GNUNET_TIME_Timestamp refund_deadline, - struct GNUNET_TIME_Timestamp wire_deadline, - const struct TALER_MerchantPublicKeyP *merchant, - const struct TALER_Amount *amount_without_fee) +reply_deposit_success ( + struct MHD_Connection *connection, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_ExtensionContractHashP *h_extensions, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp exchange_timestamp, + struct GNUNET_TIME_Timestamp refund_deadline, + struct GNUNET_TIME_Timestamp wire_deadline, + const struct TALER_MerchantPublicKeyP *merchant, + const struct TALER_Amount *amount_without_fee) { struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; - struct TALER_DepositConfirmationPS dc = { - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT), - .purpose.size = htonl (sizeof (dc)), - .h_contract_terms = *h_contract_terms, - .h_wire = *h_wire, - .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp), - .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline), - .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline), - .coin_pub = *coin_pub, - .merchant_pub = *merchant - }; enum TALER_ErrorCode ec; - if (NULL != h_extensions) - dc.h_extensions = *h_extensions; - TALER_amount_hton (&dc.amount_without_fee, - amount_without_fee); if (TALER_EC_NONE != - (ec = TEH_keys_exchange_sign (&dc, - &pub, - &sig))) + (ec = TALER_exchange_online_deposit_confirmation_sign ( + &TEH_keys_exchange_sign_, + h_contract_terms, + h_wire, + h_extensions, + exchange_timestamp, + wire_deadline, + refund_deadline, + amount_without_fee, + coin_pub, + merchant, + &pub, + &sig))) { return TALER_MHD_reply_with_ec (connection, ec, diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c b/src/exchange/taler-exchange-httpd_deposits_get.c index c88026fc4..72657d16e 100644 --- a/src/exchange/taler-exchange-httpd_deposits_get.c +++ b/src/exchange/taler-exchange-httpd_deposits_get.c @@ -46,34 +46,30 @@ * @return MHD result code */ static MHD_RESULT -reply_deposit_details (struct MHD_Connection *connection, - const struct - TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_MerchantWireHashP *h_wire, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *coin_contribution, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct GNUNET_TIME_Timestamp exec_time) +reply_deposit_details ( + struct MHD_Connection *connection, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *coin_contribution, + const struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Timestamp exec_time) { struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; - struct TALER_ConfirmWirePS cw = { - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE), - .purpose.size = htonl (sizeof (cw)), - .h_wire = *h_wire, - .h_contract_terms = *h_contract_terms, - .wtid = *wtid, - .coin_pub = *coin_pub, - .execution_time = GNUNET_TIME_timestamp_hton (exec_time) - }; enum TALER_ErrorCode ec; - TALER_amount_hton (&cw.coin_contribution, - coin_contribution); if (TALER_EC_NONE != - (ec = TEH_keys_exchange_sign (&cw, - &pub, - &sig))) + (ec = TALER_exchange_online_confirm_wire_sign ( + &TEH_keys_exchange_sign_, + h_wire, + h_contract_terms, + wtid, + coin_pub, + exec_time, + coin_contribution, + &pub, + &sig))) { return TALER_MHD_reply_with_ec (connection, ec, diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 658e5a347..e0ca24a65 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -1797,19 +1797,17 @@ create_krd (struct TEH_KeyStateHandle *ksh, GNUNET_TIME_timestamp2s (last_cpd)); /* Sign hash over denomination keys */ { - struct TALER_ExchangeKeySetPS ks = { - .purpose.size = htonl (sizeof (ks)), - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET), - .list_issue_date = GNUNET_TIME_timestamp_hton (last_cpd), - .hc = *denom_keys_hash - }; enum TALER_ErrorCode ec; if (TALER_EC_NONE != - (ec = TEH_keys_exchange_sign2 (ksh, - &ks, - &exchange_pub, - &exchange_sig))) + (ec = + TALER_exchange_online_key_set_sign ( + &TEH_keys_exchange_sign2_, + ksh, + last_cpd, + denom_keys_hash, + &exchange_pub, + &exchange_sig))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Could not create key response data: cannot sign (%s)\n", @@ -2770,11 +2768,12 @@ TEH_keys_exchange_sign_ ( enum TALER_ErrorCode TEH_keys_exchange_sign2_ ( - struct TEH_KeyStateHandle *ksh, + void *cls, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct TALER_ExchangePublicKeyP *pub, struct TALER_ExchangeSignatureP *sig) { + struct TEH_KeyStateHandle *ksh = cls; enum TALER_ErrorCode ec; TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_EDDSA]++; diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index 732ee032d..544906ad8 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -367,7 +367,7 @@ TEH_keys_exchange_sign_ ( * number of bytes of the data structure, including its header. Use * #TEH_keys_exchange_sign() instead of calling this function directly! * - * @param ksh key state state to look in + * @param cls key state state to look in * @param purpose the message to sign * @param[out] pub set to the current public signing key of the exchange * @param[out] sig signature over purpose using current signing key @@ -375,7 +375,7 @@ TEH_keys_exchange_sign_ ( */ enum TALER_ErrorCode TEH_keys_exchange_sign2_ ( - struct TEH_KeyStateHandle *ksh, + void *cls, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct TALER_ExchangePublicKeyP *pub, struct TALER_ExchangeSignatureP *sig); diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c b/src/exchange/taler-exchange-httpd_kyc-check.c index d6b16d219..62ecbaab9 100644 --- a/src/exchange/taler-exchange-httpd_kyc-check.c +++ b/src/exchange/taler-exchange-httpd_kyc-check.c @@ -414,19 +414,15 @@ TEH_handler_kyc_check ( { struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; - struct TALER_ExchangeAccountSetupSuccessPS as = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS), - .purpose.size = htonl (sizeof (as)), - .h_payto = kyp->h_payto, - .timestamp = GNUNET_TIME_timestamp_hton (now) - }; enum TALER_ErrorCode ec; if (TALER_EC_NONE != - (ec = TEH_keys_exchange_sign (&as, - &pub, - &sig))) + (ec = TALER_exchange_online_account_setup_success_sign ( + &TEH_keys_exchange_sign_, + &kyp->h_payto, + now, + &pub, + &sig))) { return TALER_MHD_reply_with_ec (rc->connection, ec, diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c index 531209c10..6fe97c8f2 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -48,18 +48,15 @@ reply_melt_success (struct MHD_Connection *connection, { struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; - struct TALER_RefreshMeltConfirmationPS body = { - .purpose.size = htonl (sizeof (body)), - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT), - .rc = *rc, - .noreveal_index = htonl (noreveal_index) - }; enum TALER_ErrorCode ec; if (TALER_EC_NONE != - (ec = TEH_keys_exchange_sign (&body, - &pub, - &sig))) + (ec = TALER_exchange_online_melt_confirmation_sign ( + &TEH_keys_exchange_sign_, + rc, + noreveal_index, + &pub, + &sig))) { return TALER_MHD_reply_with_ec (connection, ec, diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c index 84b60bcdb..3718fdedf 100644 --- a/src/exchange/taler-exchange-httpd_refund.c +++ b/src/exchange/taler-exchange-httpd_refund.c @@ -50,22 +50,18 @@ reply_refund_success (struct MHD_Connection *connection, { struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; - struct TALER_RefundConfirmationPS rc = { - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND), - .purpose.size = htonl (sizeof (rc)), - .h_contract_terms = refund->h_contract_terms, - .coin_pub = *coin_pub, - .merchant = refund->merchant_pub, - .rtransaction_id = GNUNET_htonll (refund->rtransaction_id) - }; enum TALER_ErrorCode ec; - TALER_amount_hton (&rc.refund_amount, - &refund->refund_amount); if (TALER_EC_NONE != - (ec = TEH_keys_exchange_sign (&rc, - &pub, - &sig))) + (ec = TALER_exchange_online_refund_confirmation_sign ( + &TEH_keys_exchange_sign_, + &refund->h_contract_terms, + coin_pub, + &refund->merchant_pub, + refund->rtransaction_id, + &refund->refund_amount, + &pub, + &sig))) { return TALER_MHD_reply_with_ec (connection, ec, diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index ee8c902dd..725e08d96 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -241,21 +241,16 @@ TEH_RESPONSE_compile_transaction_history ( pos->details.old_coin_recoup; struct TALER_ExchangePublicKeyP epub; struct TALER_ExchangeSignatureP esig; - struct TALER_RecoupRefreshConfirmationPS pc = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), - .purpose.size = htonl (sizeof (pc)), - .timestamp = GNUNET_TIME_timestamp_hton (pr->timestamp), - .coin_pub = pr->coin.coin_pub, - .old_coin_pub = pr->old_coin_pub - }; - TALER_amount_hton (&pc.recoup_amount, - &pr->value); if (TALER_EC_NONE != - TEH_keys_exchange_sign (&pc, - &epub, - &esig)) + TALER_exchange_online_confirm_recoup_refresh_sign ( + &TEH_keys_exchange_sign_, + pr->timestamp, + &pr->value, + &pr->coin.coin_pub, + &pr->old_coin_pub, + &epub, + &esig)) { GNUNET_break (0); json_decref (history); @@ -295,20 +290,16 @@ TEH_RESPONSE_compile_transaction_history ( pos->details.recoup; struct TALER_ExchangePublicKeyP epub; struct TALER_ExchangeSignatureP esig; - struct TALER_RecoupConfirmationPS pc = { - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP), - .purpose.size = htonl (sizeof (pc)), - .timestamp = GNUNET_TIME_timestamp_hton (recoup->timestamp), - .coin_pub = *coin_pub, - .reserve_pub = recoup->reserve_pub - }; - TALER_amount_hton (&pc.recoup_amount, - &recoup->value); if (TALER_EC_NONE != - TEH_keys_exchange_sign (&pc, - &epub, - &esig)) + TALER_exchange_online_confirm_recoup_sign ( + &TEH_keys_exchange_sign_, + recoup->timestamp, + &recoup->value, + coin_pub, + &recoup->reserve_pub, + &epub, + &esig)) { GNUNET_break (0); json_decref (history); @@ -351,21 +342,16 @@ TEH_RESPONSE_compile_transaction_history ( pos->details.recoup_refresh; struct TALER_ExchangePublicKeyP epub; struct TALER_ExchangeSignatureP esig; - struct TALER_RecoupRefreshConfirmationPS pc = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), - .purpose.size = htonl (sizeof (pc)), - .timestamp = GNUNET_TIME_timestamp_hton (pr->timestamp), - .coin_pub = *coin_pub, - .old_coin_pub = pr->old_coin_pub - }; - TALER_amount_hton (&pc.recoup_amount, - &pr->value); if (TALER_EC_NONE != - TEH_keys_exchange_sign (&pc, - &epub, - &esig)) + TALER_exchange_online_confirm_recoup_refresh_sign ( + &TEH_keys_exchange_sign_, + pr->timestamp, + &pr->value, + coin_pub, + &pr->old_coin_pub, + &epub, + &esig)) { GNUNET_break (0); json_decref (history); @@ -424,18 +410,12 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash ( enum TALER_ErrorCode ec; now = GNUNET_TIME_timestamp_get (); - { - struct TALER_DenominationUnknownAffirmationPS dua = { - .purpose.size = htonl (sizeof (dua)), - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN), - .timestamp = GNUNET_TIME_timestamp_hton (now), - .h_denom_pub = *dph, - }; - - ec = TEH_keys_exchange_sign (&dua, - &epub, - &esig); - } + ec = TALER_exchange_online_denomination_unknown_sign ( + &TEH_keys_exchange_sign_, + now, + dph, + &epub, + &esig); if (TALER_EC_NONE != ec) { GNUNET_break (0); @@ -471,22 +451,14 @@ TEH_RESPONSE_reply_expired_denom_pub_hash ( enum TALER_ErrorCode ecr; struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get (); - struct TALER_DenominationExpiredAffirmationPS dua = { - .purpose.size = htonl (sizeof (dua)), - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED), - .timestamp = GNUNET_TIME_timestamp_hton (now), - .h_denom_pub = *dph, - }; - /* strncpy would create a compiler warning */ - memcpy (dua.operation, - oper, - GNUNET_MIN (sizeof (dua.operation), - strlen (oper))); - ecr = TEH_keys_exchange_sign (&dua, - &epub, - &esig); + ecr = TALER_exchange_online_denomination_expired_sign ( + &TEH_keys_exchange_sign_, + now, + dph, + oper, + &epub, + &esig); if (TALER_EC_NONE != ecr) { GNUNET_break (0); @@ -523,18 +495,12 @@ TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( enum TALER_ErrorCode ec; now = GNUNET_TIME_timestamp_get (); - { - struct TALER_DenominationUnknownAffirmationPS dua = { - .purpose.size = htonl (sizeof (dua)), - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN), - .timestamp = GNUNET_TIME_timestamp_hton (now), - .h_denom_pub = *dph, - }; - - ec = TEH_keys_exchange_sign (&dua, - &epub, - &esig); - } + ec = TALER_exchange_online_denomination_unknown_sign ( + &TEH_keys_exchange_sign_, + now, + dph, + &epub, + &esig); if (TALER_EC_NONE != ec) { GNUNET_break (0); @@ -679,26 +645,19 @@ TEH_RESPONSE_compile_reserve_history ( struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; + if (TALER_EC_NONE != + TALER_exchange_online_confirm_recoup_sign ( + &TEH_keys_exchange_sign_, + recoup->timestamp, + &recoup->value, + &recoup->coin.coin_pub, + &recoup->reserve_pub, + &pub, + &sig)) { - struct TALER_RecoupConfirmationPS pc = { - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP), - .purpose.size = htonl (sizeof (pc)), - .timestamp = GNUNET_TIME_timestamp_hton (recoup->timestamp), - .coin_pub = recoup->coin.coin_pub, - .reserve_pub = recoup->reserve_pub - }; - - TALER_amount_hton (&pc.recoup_amount, - &recoup->value); - if (TALER_EC_NONE != - TEH_keys_exchange_sign (&pc, - &pub, - &sig)) - { - GNUNET_break (0); - json_decref (json_history); - return NULL; - } + GNUNET_break (0); + json_decref (json_history); + return NULL; } if (0 != @@ -731,30 +690,21 @@ TEH_RESPONSE_compile_reserve_history ( struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; + if (TALER_EC_NONE != + TALER_exchange_online_reserve_closed_sign ( + &TEH_keys_exchange_sign_, + closing->execution_date, + &closing->amount, + &closing->closing_fee, + closing->receiver_account_details, + &closing->wtid, + &pos->details.closing->reserve_pub, + &pub, + &sig)) { - struct TALER_ReserveCloseConfirmationPS rcc = { - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED), - .purpose.size = htonl (sizeof (rcc)), - .timestamp = GNUNET_TIME_timestamp_hton (closing->execution_date), - .reserve_pub = pos->details.closing->reserve_pub, - .wtid = closing->wtid - }; - - TALER_amount_hton (&rcc.closing_amount, - &closing->amount); - TALER_amount_hton (&rcc.closing_fee, - &closing->closing_fee); - TALER_payto_hash (closing->receiver_account_details, - &rcc.h_payto); - if (TALER_EC_NONE != - TEH_keys_exchange_sign (&rcc, - &pub, - &sig)) - { - GNUNET_break (0); - json_decref (json_history); - return NULL; - } + GNUNET_break (0); + json_decref (json_history); + return NULL; } if (0 != json_array_append_new ( diff --git a/src/exchange/taler-exchange-httpd_transfers_get.c b/src/exchange/taler-exchange-httpd_transfers_get.c index 3f87f370a..0a994d8ec 100644 --- a/src/exchange/taler-exchange-httpd_transfers_get.c +++ b/src/exchange/taler-exchange-httpd_transfers_get.c @@ -93,11 +93,11 @@ reply_transfer_details (struct MHD_Connection *connection, const struct AggregatedDepositDetail *wdd_head) { json_t *deposits; - struct TALER_WireDepositDetailP dd; struct GNUNET_HashContext *hash_context; - struct TALER_WireDepositDataPS wdp; + struct GNUNET_HashCode h_details; struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangeSignatureP sig; + struct TALER_PaytoHashP h_payto; deposits = json_array (); GNUNET_assert (NULL != deposits); @@ -106,16 +106,12 @@ reply_transfer_details (struct MHD_Connection *connection, NULL != wdd_pos; wdd_pos = wdd_pos->next) { - dd.h_contract_terms = wdd_pos->h_contract_terms; - dd.execution_time = GNUNET_TIME_timestamp_hton (exec_time); - dd.coin_pub = wdd_pos->coin_pub; - TALER_amount_hton (&dd.deposit_value, - &wdd_pos->deposit_value); - TALER_amount_hton (&dd.deposit_fee, - &wdd_pos->deposit_fee); - GNUNET_CRYPTO_hash_context_read (hash_context, - &dd, - sizeof (struct TALER_WireDepositDetailP)); + TALER_exchange_online_wire_deposit_append (hash_context, + &wdd_pos->h_contract_terms, + exec_time, + &wdd_pos->coin_pub, + &wdd_pos->deposit_value, + &wdd_pos->deposit_fee); if (0 != json_array_append_new ( deposits, @@ -137,24 +133,21 @@ reply_transfer_details (struct MHD_Connection *connection, "json_array_append_new() failed"); } } - wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT); - wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS)); - TALER_amount_hton (&wdp.total, - total); - TALER_amount_hton (&wdp.wire_fee, - wire_fee); - wdp.merchant_pub = *merchant_pub; - TALER_payto_hash (payto_uri, - &wdp.h_payto); GNUNET_CRYPTO_hash_context_finish (hash_context, - &wdp.h_details); + &h_details); { enum TALER_ErrorCode ec; if (TALER_EC_NONE != - (ec = TEH_keys_exchange_sign (&wdp, - &pub, - &sig))) + (ec = TALER_exchange_online_wire_deposit_sign ( + &TEH_keys_exchange_sign_, + total, + wire_fee, + merchant_pub, + payto_uri, + &h_details, + &pub, + &sig))) { json_decref (deposits); return TALER_MHD_reply_with_ec (connection, @@ -163,6 +156,8 @@ reply_transfer_details (struct MHD_Connection *connection, } } + TALER_payto_hash (payto_uri, + &h_payto); return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, @@ -173,7 +168,7 @@ reply_transfer_details (struct MHD_Connection *connection, GNUNET_JSON_pack_data_auto ("merchant_pub", merchant_pub), GNUNET_JSON_pack_data_auto ("h_payto", - &wdp.h_payto), + &h_payto), GNUNET_JSON_pack_timestamp ("execution_time", exec_time), GNUNET_JSON_pack_array_steal ("deposits", diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index cc489e2c2..9276ab147 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1455,6 +1455,132 @@ struct TALER_ExchangeWithdrawValues }; +/** + * @brief Information about a signing key of the exchange. Signing keys are used + * to sign exchange messages other than coins, i.e. to confirm that a + * deposit was successful or that a refresh was accepted. + * + * FIXME: remove this from the public API... + */ +struct TALER_ExchangeSigningKeyValidityPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When does this signing key begin to be valid? + */ + struct GNUNET_TIME_TimestampNBO start; + + /** + * When does this signing key expire? Note: This is currently when + * the Exchange will definitively stop using it. Signatures made with + * the key remain valid until @e end. When checking validity periods, + * clients should allow for some overlap between keys and tolerate + * the use of either key during the overlap time (due to the + * possibility of clock skew). + */ + struct GNUNET_TIME_TimestampNBO expire; + + /** + * When do signatures with this signing key become invalid? After + * this point, these signatures cannot be used in (legal) disputes + * anymore, as the Exchange is then allowed to destroy its side of the + * evidence. @e end is expected to be significantly larger than @e + * expire (by a year or more). + */ + struct GNUNET_TIME_TimestampNBO end; + + /** + * The public online signing key that the exchange will use + * between @e start and @e expire. + */ + struct TALER_ExchangePublicKeyP signkey_pub; +}; + + +/** + * @brief Information about a denomination key. Denomination keys + * are used to sign coins of a certain value into existence. + * + * FIXME: remove this from the public API... + */ +struct TALER_DenominationKeyValidityPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * The long-term offline master key of the exchange that was + * used to create @e signature. + */ + struct TALER_MasterPublicKeyP master; + + /** + * Start time of the validity period for this key. + */ + struct GNUNET_TIME_TimestampNBO start; + + /** + * The exchange will sign fresh coins between @e start and this time. + * @e expire_withdraw will be somewhat larger than @e start to + * ensure a sufficiently large anonymity set, while also allowing + * the Exchange to limit the financial damage in case of a key being + * compromised. Thus, exchanges with low volume are expected to have a + * longer withdraw period (@e expire_withdraw - @e start) than exchanges + * with high transaction volume. The period may also differ between + * types of coins. A exchange may also have a few denomination keys + * with the same value with overlapping validity periods, to address + * issues such as clock skew. + */ + struct GNUNET_TIME_TimestampNBO expire_withdraw; + + /** + * Coins signed with the denomination key must be spent or refreshed + * between @e start and this expiration time. After this time, the + * exchange will refuse transactions involving this key as it will + * "drop" the table with double-spending information (shortly after) + * this time. Note that wallets should refresh coins significantly + * before this time to be on the safe side. @e expire_deposit must be + * significantly larger than @e expire_withdraw (by months or even + * years). + */ + struct GNUNET_TIME_TimestampNBO expire_deposit; + + /** + * When do signatures with this denomination key become invalid? + * After this point, these signatures cannot be used in (legal) + * disputes anymore, as the Exchange is then allowed to destroy its side + * of the evidence. @e expire_legal is expected to be significantly + * larger than @e expire_deposit (by a year or more). + */ + struct GNUNET_TIME_TimestampNBO expire_legal; + + /** + * The value of the coins signed with this denomination key. + */ + struct TALER_AmountNBO value; + + /** + * Fees for the coin. + */ + struct TALER_DenomFeeSetNBOP fees; + + /** + * Hash code of the denomination public key. (Used to avoid having + * the variable-size RSA key in this struct.) + */ + struct TALER_DenominationHashP denom_hash GNUNET_PACKED; + +}; + + /** * Free internals of @a denom_pub, but not @a denom_pub itself. * @@ -2678,40 +2804,6 @@ TALER_CRYPTO_helper_esign_disconnect ( struct TALER_CRYPTO_ExchangeSignHelper *esh); -/* ********************* exchange signing ************************** */ - - -/** - * Verify a deposit confirmation. - * - * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) - * @param h_wire hash of the merchant’s account details - * @param h_extensions hash over the extensions, can be NULL - * @param exchange_timestamp timestamp when the contract was finalized, must not be too far off - * @param wire_deadline date until which the exchange should wire the funds - * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline - * @param amount_without_fee the amount to be deposited after fees - * @param coin_pub public key of the deposited coin - * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) - * @param exchange_pub exchange's online signing public key - * @param exchange_sig the signature made with purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT - * @return #GNUNET_OK if the signature is valid - */ -enum GNUNET_GenericReturnValue -TALER_exchange_deposit_confirm_verify ( - const struct TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_MerchantWireHashP *h_wire, - const struct TALER_ExtensionContractHashP *h_extensions, - struct GNUNET_TIME_Timestamp exchange_timestamp, - struct GNUNET_TIME_Timestamp wire_deadline, - struct GNUNET_TIME_Timestamp refund_deadline, - const struct TALER_Amount *amount_without_fee, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_ExchangePublicKeyP *exchange_pub, - const struct TALER_ExchangeSignatureP *exchange_sig); - - /* ********************* wallet signing ************************** */ @@ -3333,6 +3425,518 @@ TALER_merchant_refund_verify ( const struct TALER_MerchantSignatureP *merchant_sig); +/* ********************* exchange online signing ************************** */ + + +/** + * Signature of a function that signs the message in @a purpose with the + * exchange's signing key. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. * + * @param purpose the message to sign + * @param[out] pub set to the current public signing key of the exchange + * @param[out] sig signature over purpose using current signing key + * @return #TALER_EC_NONE on success + */ +typedef enum TALER_ErrorCode +(*TALER_ExchangeSignCallback)( + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Signature of a function that signs the message in @a purpose with the + * exchange's signing key. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. * + * @param cls closure + * @param purpose the message to sign + * @param[out] pub set to the current public signing key of the exchange + * @param[out] sig signature over purpose using current signing key + * @return #TALER_EC_NONE on success + */ +typedef enum TALER_ErrorCode +(*TALER_ExchangeSignCallback2)( + void *cls, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Create deposit confirmation signature. + * + * @param scb function to call to create the signature + * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param h_wire hash of the merchant’s account details + * @param h_extensions hash over the extensions, can be NULL + * @param exchange_timestamp timestamp when the contract was finalized, must not be too far off + * @param wire_deadline date until which the exchange should wire the funds + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param amount_without_fee the amount to be deposited after fees + * @param coin_pub public key of the deposited coin + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_deposit_confirmation_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_ExtensionContractHashP *h_extensions, + struct GNUNET_TIME_Timestamp exchange_timestamp, + struct GNUNET_TIME_Timestamp wire_deadline, + struct GNUNET_TIME_Timestamp refund_deadline, + const struct TALER_Amount *amount_without_fee, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify deposit confirmation signature. + * + * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param h_wire hash of the merchant’s account details + * @param h_extensions hash over the extensions, can be NULL + * @param exchange_timestamp timestamp when the contract was finalized, must not be too far off + * @param wire_deadline date until which the exchange should wire the funds + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param amount_without_fee the amount to be deposited after fees + * @param coin_pub public key of the deposited coin + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_deposit_confirmation_verify ( + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_ExtensionContractHashP *h_extensions, + struct GNUNET_TIME_Timestamp exchange_timestamp, + struct GNUNET_TIME_Timestamp wire_deadline, + struct GNUNET_TIME_Timestamp refund_deadline, + const struct TALER_Amount *amount_without_fee, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create refund confirmation signature. + * + * @param scb function to call to create the signature + * @param XXX wire transfer subject used + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_refund_confirmation_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant, + uint64_t rtransaction_id, + const struct TALER_Amount *refund_amount, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify refund confirmation signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_refund_confirmation_verify ( + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant, + uint64_t rtransaction_id, + const struct TALER_Amount *refund_amount, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create refresh melt confirmation signature. + * + * @param scb function to call to create the signature + * @param XXX + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_melt_confirmation_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_RefreshCommitmentP *rc, + uint32_t noreveal_index, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify refresh melt confirmation signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_melt_confirmation_verify ( + const struct TALER_RefreshCommitmentP *rc, + uint32_t noreveal_index, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create exchange key set signature. + * + * @param scb function to call to create the signature + * @param timestamp time when the key set was issued + * @param hc hash over all the keys + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_key_set_sign ( + TALER_ExchangeSignCallback2 scb, + void *cls, + struct GNUNET_TIME_Timestamp timestamp, + const struct GNUNET_HashCode *hc, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify key set signature. + * + * @param timestamp time when the key set was issued + * @param hc hash over all the keys + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_key_set_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct GNUNET_HashCode *hc, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create account setup success signature. + * + * @param scb function to call to create the signature + * @param h_payto target of the KYC account + * @param timestamp time when the KYC was confirmed + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_account_setup_success_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp timestamp, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify account setup success signature. + * + * @param h_payto target of the KYC account + * @param timestamp time when the KYC was confirmed + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_account_setup_success_verify ( + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +void +TALER_exchange_online_wire_deposit_append ( + struct GNUNET_HashContext *hash_context, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp execution_time, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *deposit_value, + const struct TALER_Amount *deposit_fee); + + +/** + * Create wire deposit signature. + * + * @param scb function to call to create the signature + * @param XXX + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_wire_deposit_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_Amount *total, + const struct TALER_Amount *wire_fee, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *payto, + const struct GNUNET_HashCode *h_details, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify wire deposit signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_wire_deposit_verify ( + const struct TALER_Amount *total, + const struct TALER_Amount *wire_fee, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_PaytoHashP *h_payto, + const struct GNUNET_HashCode *h_details, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create wire confirmation signature. + * + * @param scb function to call to create the signature + * @param XXX + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_confirm_wire_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct GNUNET_TIME_Timestamp execution_time, + const struct TALER_Amount *coin_contribution, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify confirm wire signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_confirm_wire_verify ( + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct GNUNET_TIME_Timestamp execution_time, + const struct TALER_Amount *coin_contribution, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create confirm recoup signature. + * + * @param scb function to call to create the signature + * @param XXX + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_confirm_recoup_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify confirm recoup signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_confirm_recoup_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create confirm recoup refresh signature. + * + * @param scb function to call to create the signature + * @param XXX + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_confirm_recoup_refresh_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify confirm recoup refresh signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_confirm_recoup_refresh_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create denomination unknown signature. + * + * @param scb function to call to create the signature + * @param XXX + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_denomination_unknown_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify denomination unknown signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_denomination_unknown_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create denomination expired signature. + * + * @param scb function to call to create the signature + * @param XXX + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_denomination_expired_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + const char *op, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify denomination expired signature. + * + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_denomination_expired_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + const char *op, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + +/** + * Create reserve closure signature. + * + * @param scb function to call to create the signature + * @param timestamp time when the reserve was closed + * @param closing_amount amount left in the reserve + * @param closing_fee closing fee charged + * @param payto target of the wire transfer + * @param wtid wire transfer subject used + * @param reserve_pub public key of the closed reserve + * @param[out] pub where to write the public key + * @param[out] sig where to write the signature + */ +enum TALER_ErrorCode +TALER_exchange_online_reserve_closed_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *closing_amount, + const struct TALER_Amount *closing_fee, + const char *payto, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig); + + +/** + * Verify reserve closure signature. + * + * @param timestamp time when the reserve was closed + * @param closing_amount amount left in the reserve + * @param closing_fee closing fee charged + * @param payto target of the wire transfer + * @param wtid wire transfer subject used + * @param reserve_pub public key of the closed reserve + * @param pub where to write the public key + * @param sig where to write the signature + */ +enum GNUNET_GenericReturnValue +TALER_exchange_online_reserve_closed_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *closing_amount, + const struct TALER_Amount *closing_fee, + const char *payto, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig); + + /* ********************* offline signing ************************** */ diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 775947ac0..52c294cef 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -369,467 +369,6 @@ GNUNET_NETWORK_STRUCT_BEGIN -/** - * @brief format used by the denomination crypto helper when affirming - * that it created a denomination key. - */ -struct TALER_DenominationKeyAnnouncementPS -{ - - /** - * Purpose must be #TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY. - * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash of the denomination public key. - */ - struct TALER_DenominationHashP h_denom; - - /** - * Hash of the section name in the configuration of this denomination. - */ - struct GNUNET_HashCode h_section_name; - - /** - * When does the key become available? - */ - struct GNUNET_TIME_TimestampNBO anchor_time; - - /** - * How long is the key available after @e anchor_time? - */ - struct GNUNET_TIME_RelativeNBO duration_withdraw; - -}; - - -/** - * @brief format used by the signing crypto helper when affirming - * that it created an exchange signing key. - */ -struct TALER_SigningKeyAnnouncementPS -{ - - /** - * Purpose must be #TALER_SIGNATURE_SM_SIGNING_KEY. - * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Public signing key of the exchange this is about. - */ - struct TALER_ExchangePublicKeyP exchange_pub; - - /** - * When does the key become available? - */ - struct GNUNET_TIME_TimestampNBO anchor_time; - - /** - * How long is the key available after @e anchor_time? - */ - struct GNUNET_TIME_RelativeNBO duration; - -}; - - -/** - * @brief Format used to generate the signature on a confirmation - * from the exchange that a deposit request succeeded. - */ -struct TALER_DepositConfirmationPS -{ - /** - * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. Signed - * by a `struct TALER_ExchangePublicKeyP` using EdDSA. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the contract for which this deposit is made. - */ - struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; - - /** - * Hash over the wiring information of the merchant. - */ - struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; - - /** - * Hash over the extension options of the deposit, 0 if there - * were not extension options. - */ - struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED; - - /** - * Time when this confirmation was generated / when the exchange received - * the deposit request. - */ - struct GNUNET_TIME_TimestampNBO exchange_timestamp; - - /** - * By when does the exchange expect to pay the merchant - * (as per the merchant's request). - */ - struct GNUNET_TIME_TimestampNBO wire_deadline; - - /** - * How much time does the @e merchant have to issue a refund - * request? Zero if refunds are not allowed. After this time, the - * coin cannot be refunded. Note that the wire transfer will not be - * performed by the exchange until the refund deadline. This value - * is taken from the original deposit request. - */ - struct GNUNET_TIME_TimestampNBO refund_deadline; - - /** - * Amount to be deposited, excluding fee. Calculated from the - * amount with fee and the fee from the deposit request. - */ - struct TALER_AmountNBO amount_without_fee; - - /** - * The public key of the coin that was deposited. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * The Merchant's public key. Allows the merchant to later refund - * the transaction or to inquire about the wire transfer identifier. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - -}; - - -/** - * @brief Format used to generate the signature on a request to refund - * a coin into the account of the customer. - */ -struct TALER_RefundConfirmationPS -{ - /** - * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the proposal data to identify the contract - * which is being refunded. - */ - struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; - - /** - * The coin's public key. This is the value that must have been - * signed (blindly) by the Exchange. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * The Merchant's public key. Allows the merchant to later refund - * the transaction or to inquire about the wire transfer identifier. - */ - struct TALER_MerchantPublicKeyP merchant; - - /** - * Merchant-generated transaction ID for the refund. - */ - uint64_t rtransaction_id GNUNET_PACKED; - - /** - * Amount to be refunded, including refund fee charged by the - * exchange to the customer. - */ - struct TALER_AmountNBO refund_amount; -}; - - -/** - * @brief Format of the block signed by the Exchange in response to a successful - * "/refresh/melt" request. Hereby the exchange affirms that all of the - * coins were successfully melted. This also commits the exchange to a - * particular index to not be revealed during the refresh. - */ -struct TALER_RefreshMeltConfirmationPS -{ - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT. Signed - * by a `struct TALER_ExchangePublicKeyP` using EdDSA. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Commitment made in the /refresh/melt. - */ - struct TALER_RefreshCommitmentP rc GNUNET_PACKED; - - /** - * Index that the client will not have to reveal, in NBO. - * Must be smaller than #TALER_CNC_KAPPA. - */ - uint32_t noreveal_index GNUNET_PACKED; - -}; - - -/** - * @brief Signature made by the exchange over the full set of keys, used - * to detect cheating exchanges that give out different sets to - * different users. - */ -struct TALER_ExchangeKeySetPS -{ - - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET. Signed - * by a `struct TALER_ExchangePublicKeyP` using EdDSA. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Time of the key set issue. - */ - struct GNUNET_TIME_TimestampNBO list_issue_date; - - /** - * Hash over the various denomination signing keys returned. - */ - struct GNUNET_HashCode hc GNUNET_PACKED; -}; - - -/** - * @brief Signature by which an exchange affirms that an account - * successfully passed the KYC checks. - */ -struct TALER_ExchangeAccountSetupSuccessPS -{ - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS. Signed by a - * `struct TALER_ExchangePublicKeyP` using EdDSA. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the payto for which the signature was - * made. - */ - struct TALER_PaytoHashP h_payto; - - /** - * When was the signature made. - */ - struct GNUNET_TIME_TimestampNBO timestamp; -}; - - -/** - * @brief Information about a signing key of the exchange. Signing keys are used - * to sign exchange messages other than coins, i.e. to confirm that a - * deposit was successful or that a refresh was accepted. - */ -struct TALER_ExchangeSigningKeyValidityPS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When does this signing key begin to be valid? - */ - struct GNUNET_TIME_TimestampNBO start; - - /** - * When does this signing key expire? Note: This is currently when - * the Exchange will definitively stop using it. Signatures made with - * the key remain valid until @e end. When checking validity periods, - * clients should allow for some overlap between keys and tolerate - * the use of either key during the overlap time (due to the - * possibility of clock skew). - */ - struct GNUNET_TIME_TimestampNBO expire; - - /** - * When do signatures with this signing key become invalid? After - * this point, these signatures cannot be used in (legal) disputes - * anymore, as the Exchange is then allowed to destroy its side of the - * evidence. @e end is expected to be significantly larger than @e - * expire (by a year or more). - */ - struct GNUNET_TIME_TimestampNBO end; - - /** - * The public online signing key that the exchange will use - * between @e start and @e expire. - */ - struct TALER_ExchangePublicKeyP signkey_pub; -}; - - -/** - * @brief Information about a denomination key. Denomination keys - * are used to sign coins of a certain value into existence. - */ -struct TALER_DenominationKeyValidityPS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * The long-term offline master key of the exchange that was - * used to create @e signature. - */ - struct TALER_MasterPublicKeyP master; - - /** - * Start time of the validity period for this key. - */ - struct GNUNET_TIME_TimestampNBO start; - - /** - * The exchange will sign fresh coins between @e start and this time. - * @e expire_withdraw will be somewhat larger than @e start to - * ensure a sufficiently large anonymity set, while also allowing - * the Exchange to limit the financial damage in case of a key being - * compromised. Thus, exchanges with low volume are expected to have a - * longer withdraw period (@e expire_withdraw - @e start) than exchanges - * with high transaction volume. The period may also differ between - * types of coins. A exchange may also have a few denomination keys - * with the same value with overlapping validity periods, to address - * issues such as clock skew. - */ - struct GNUNET_TIME_TimestampNBO expire_withdraw; - - /** - * Coins signed with the denomination key must be spent or refreshed - * between @e start and this expiration time. After this time, the - * exchange will refuse transactions involving this key as it will - * "drop" the table with double-spending information (shortly after) - * this time. Note that wallets should refresh coins significantly - * before this time to be on the safe side. @e expire_deposit must be - * significantly larger than @e expire_withdraw (by months or even - * years). - */ - struct GNUNET_TIME_TimestampNBO expire_deposit; - - /** - * When do signatures with this denomination key become invalid? - * After this point, these signatures cannot be used in (legal) - * disputes anymore, as the Exchange is then allowed to destroy its side - * of the evidence. @e expire_legal is expected to be significantly - * larger than @e expire_deposit (by a year or more). - */ - struct GNUNET_TIME_TimestampNBO expire_legal; - - /** - * The value of the coins signed with this denomination key. - */ - struct TALER_AmountNBO value; - - /** - * Fees for the coin. - */ - struct TALER_DenomFeeSetNBOP fees; - - /** - * Hash code of the denomination public key. (Used to avoid having - * the variable-size RSA key in this struct.) - */ - struct TALER_DenominationHashP denom_hash GNUNET_PACKED; - -}; - - -/** - * @brief Information signed by an auditor affirming - * the master public key and the denomination keys - * of a exchange. - */ -struct TALER_ExchangeKeyValidityPS -{ - - /** - * Purpose is #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash of the auditor's URL (including 0-terminator). - */ - struct GNUNET_HashCode auditor_url_hash; - - /** - * The long-term offline master key of the exchange, affirmed by the - * auditor. - */ - struct TALER_MasterPublicKeyP master; - - /** - * Start time of the validity period for this key. - */ - struct GNUNET_TIME_TimestampNBO start; - - /** - * The exchange will sign fresh coins between @e start and this time. - * @e expire_withdraw will be somewhat larger than @e start to - * ensure a sufficiently large anonymity set, while also allowing - * the Exchange to limit the financial damage in case of a key being - * compromised. Thus, exchanges with low volume are expected to have a - * longer withdraw period (@e expire_withdraw - @e start) than exchanges - * with high transaction volume. The period may also differ between - * types of coins. A exchange may also have a few denomination keys - * with the same value with overlapping validity periods, to address - * issues such as clock skew. - */ - struct GNUNET_TIME_TimestampNBO expire_withdraw; - - /** - * Coins signed with the denomination key must be spent or refreshed - * between @e start and this expiration time. After this time, the - * exchange will refuse transactions involving this key as it will - * "drop" the table with double-spending information (shortly after) - * this time. Note that wallets should refresh coins significantly - * before this time to be on the safe side. @e expire_deposit must be - * significantly larger than @e expire_withdraw (by months or even - * years). - */ - struct GNUNET_TIME_TimestampNBO expire_deposit; - - /** - * When do signatures with this denomination key become invalid? - * After this point, these signatures cannot be used in (legal) - * disputes anymore, as the Exchange is then allowed to destroy its side - * of the evidence. @e expire_legal is expected to be significantly - * larger than @e expire_deposit (by a year or more). - */ - struct GNUNET_TIME_TimestampNBO expire_legal; - - /** - * The value of the coins signed with this denomination key. - */ - struct TALER_AmountNBO value; - - /** - * Fees for the coin. - */ - struct TALER_DenomFeeSetNBOP fees; - - /** - * Hash code of the denomination public key. (Used to avoid having - * the variable-size RSA key in this struct.) - */ - struct TALER_DenominationHashP denom_hash GNUNET_PACKED; - -}; - /** * @brief Format used to generate the signature on a request to obtain @@ -867,81 +406,6 @@ struct TALER_DepositTrackPS }; -/** - * @brief Format internally used for packing the detailed information - * to generate the signature for /track/transfer signatures. - */ -struct TALER_WireDepositDetailP -{ - - /** - * Hash of the contract - */ - struct TALER_PrivateContractHashP h_contract_terms; - - /** - * Time when the wire transfer was performed by the exchange. - */ - struct GNUNET_TIME_TimestampNBO execution_time; - - /** - * Coin's public key. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Total value of the coin. - */ - struct TALER_AmountNBO deposit_value; - - /** - * Fees charged by the exchange for the deposit. - */ - struct TALER_AmountNBO deposit_fee; - -}; - - -/** - * @brief Format used to generate the signature for /wire/deposit - * replies. - */ -struct TALER_WireDepositDataPS -{ - /** - * Purpose header for the signature over the contract with - * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Total amount that was transferred. - */ - struct TALER_AmountNBO total; - - /** - * Wire fee that was charged. - */ - struct TALER_AmountNBO wire_fee; - - /** - * Public key of the merchant (for all aggregated transactions). - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * Hash of bank account of the merchant. - */ - struct TALER_PaytoHashP h_payto; - - /** - * Hash of the individual deposits that were aggregated, - * each in the format of a `struct TALER_WireDepositDetailP`. - */ - struct GNUNET_HashCode h_details; - -}; - /** * The contract sent by the merchant to the wallet. */ @@ -979,231 +443,6 @@ struct TALER_PaymentResponsePS }; -/** - * Details affirmed by the exchange about a wire transfer the exchange - * claims to have done with respect to a deposit operation. - */ -struct TALER_ConfirmWirePS -{ - /** - * Purpose header for the signature over the contract with - * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the wiring information of the merchant. - */ - struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; - - /** - * Hash over the contract for which this deposit is made. - */ - struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; - - /** - * Raw value (binary encoding) of the wire transfer subject. - */ - struct TALER_WireTransferIdentifierRawP wtid; - - /** - * The coin's public key. This is the value that must have been - * signed (blindly) by the Exchange. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * When did the exchange execute this transfer? Note that the - * timestamp may not be exactly the same on the wire, i.e. - * because the wire has a different timezone or resolution. - */ - struct GNUNET_TIME_TimestampNBO execution_time; - - /** - * The contribution of @e coin_pub to the total transfer volume. - * This is the value of the deposit minus the fee. - */ - struct TALER_AmountNBO coin_contribution; - -}; - - -/** - * Response by which the exchange affirms that it will - * refund a coin as part of the emergency /recoup - * protocol. The recoup will go back to the bank - * account that created the reserve. - */ -struct TALER_RecoupConfirmationPS -{ - - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When did the exchange receive the recoup request? - * Indirectly determines when the wire transfer is (likely) - * to happen. - */ - struct GNUNET_TIME_TimestampNBO timestamp; - - /** - * How much of the coin's value will the exchange transfer? - * (Needed in case the coin was partially spent.) - */ - struct TALER_AmountNBO recoup_amount; - - /** - * Public key of the coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Public key of the reserve that will receive the recoup. - */ - struct TALER_ReservePublicKeyP reserve_pub; -}; - - -/** - * Response by which the exchange affirms that it will refund a refreshed coin - * as part of the emergency /recoup protocol. The recoup will go back to the - * old coin's balance. - */ -struct TALER_RecoupRefreshConfirmationPS -{ - - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When did the exchange receive the recoup request? - * Indirectly determines when the wire transfer is (likely) - * to happen. - */ - struct GNUNET_TIME_TimestampNBO timestamp; - - /** - * How much of the coin's value will the exchange transfer? - * (Needed in case the coin was partially spent.) - */ - struct TALER_AmountNBO recoup_amount; - - /** - * Public key of the refreshed coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Public key of the old coin that will receive the recoup. - */ - struct TALER_CoinSpendPublicKeyP old_coin_pub; -}; - - -/** - * Response by which the exchange affirms that it does not - * currently know a denomination by the given hash. - */ -struct TALER_DenominationUnknownAffirmationPS -{ - - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When did the exchange sign this message. - */ - struct GNUNET_TIME_TimestampNBO timestamp; - - /** - * Hash of the public denomination key we do not know. - */ - struct TALER_DenominationHashP h_denom_pub; -}; - - -/** - * Response by which the exchange affirms that it does not - * currently consider the given denomination to be valid - * for the requested operation. - */ -struct TALER_DenominationExpiredAffirmationPS -{ - - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When did the exchange sign this message. - */ - struct GNUNET_TIME_TimestampNBO timestamp; - - /** - * Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s. - */ - char operation[8]; - - /** - * Hash of the public denomination key we do not know. - */ - struct TALER_DenominationHashP h_denom_pub; - -}; - - -/** - * Response by which the exchange affirms that it has - * closed a reserve and send back the funds. - */ -struct TALER_ReserveCloseConfirmationPS -{ - - /** - * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When did the exchange initiate the wire transfer. - */ - struct GNUNET_TIME_TimestampNBO timestamp; - - /** - * How much did the exchange send? - */ - struct TALER_AmountNBO closing_amount; - - /** - * How much did the exchange charge for closing the reserve? - */ - struct TALER_AmountNBO closing_fee; - - /** - * Public key of the reserve that received the recoup. - */ - struct TALER_ReservePublicKeyP reserve_pub; - - /** - * Hash of the receiver's bank account. - */ - struct TALER_PaytoHashP h_payto; - - /** - * Wire transfer subject. - */ - struct TALER_WireTransferIdentifierRawP wtid; -}; - - GNUNET_NETWORK_STRUCT_END #endif diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index 2c5bd2b41..be981eb90 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -188,17 +188,18 @@ verify_signatures (const struct TALER_MerchantWireHashP *h_wire, const struct TALER_MasterSignatureP *master_sig) { if (GNUNET_OK != - TALER_exchange_deposit_confirm_verify (h_contract_terms, - h_wire, - h_extensions, - exchange_timestamp, - wire_deadline, - refund_deadline, - amount_without_fee, - coin_pub, - merchant_pub, - exchange_pub, - exchange_sig)) + TALER_exchange_online_deposit_confirmation_verify ( + h_contract_terms, + h_wire, + h_extensions, + exchange_timestamp, + wire_deadline, + refund_deadline, + amount_without_fee, + coin_pub, + merchant_pub, + exchange_pub, + exchange_sig)) { GNUNET_break_op (0); TALER_LOG_WARNING ( diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 1da36fe8b..df1c43e4f 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -219,18 +219,16 @@ TALER_EXCHANGE_parse_reserve_history ( else if (0 == strcasecmp (type, "RECOUP")) { - struct TALER_RecoupConfirmationPS pc; - struct GNUNET_TIME_Timestamp timestamp; const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification recoup_spec[] = { GNUNET_JSON_spec_fixed_auto ("coin_pub", - &pc.coin_pub), + &rh->details.recoup_details.coin_pub), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &rh->details.recoup_details.exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &rh->details.recoup_details.exchange_pub), - GNUNET_JSON_spec_timestamp_nbo ("timestamp", - &pc.timestamp), + GNUNET_JSON_spec_timestamp ("timestamp", + &rh->details.recoup_details.timestamp), GNUNET_JSON_spec_end () }; @@ -244,15 +242,6 @@ TALER_EXCHANGE_parse_reserve_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - rh->details.recoup_details.coin_pub = pc.coin_pub; - TALER_amount_hton (&pc.recoup_amount, - &amount); - pc.purpose.size = htonl (sizeof (pc)); - pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP); - pc.reserve_pub = *reserve_pub; - timestamp = GNUNET_TIME_timestamp_ntoh (pc.timestamp); - rh->details.recoup_details.timestamp = timestamp; - key_state = TALER_EXCHANGE_get_keys (exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, @@ -263,11 +252,13 @@ TALER_EXCHANGE_parse_reserve_history ( return GNUNET_SYSERR; } if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP, - &pc, - &rh->details.recoup_details.exchange_sig.eddsa_signature, - &rh->details.recoup_details.exchange_pub.eddsa_pub)) + TALER_exchange_online_confirm_recoup_verify ( + rh->details.recoup_details.timestamp, + &amount, + &rh->details.recoup_details.coin_pub, + reserve_pub, + &rh->details.recoup_details.exchange_pub, + &rh->details.recoup_details.exchange_sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -287,8 +278,6 @@ TALER_EXCHANGE_parse_reserve_history ( "CLOSING")) { const struct TALER_EXCHANGE_Keys *key_state; - struct TALER_ReserveCloseConfirmationPS rcc; - struct GNUNET_TIME_Timestamp timestamp; struct GNUNET_JSON_Specification closing_spec[] = { GNUNET_JSON_spec_string ( "receiver_account_details", @@ -299,10 +288,10 @@ TALER_EXCHANGE_parse_reserve_history ( &rh->details.close_details.exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &rh->details.close_details.exchange_pub), - TALER_JSON_spec_amount_any_nbo ("closing_fee", - &rcc.closing_fee), - GNUNET_JSON_spec_timestamp_nbo ("timestamp", - &rcc.timestamp), + TALER_JSON_spec_amount_any ("closing_fee", + &rh->details.close_details.fee), + GNUNET_JSON_spec_timestamp ("timestamp", + &rh->details.close_details.timestamp), GNUNET_JSON_spec_end () }; @@ -316,33 +305,26 @@ TALER_EXCHANGE_parse_reserve_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_hton (&rcc.closing_amount, - &amount); - TALER_payto_hash (rh->details.close_details.receiver_account_details, - &rcc.h_payto); - rcc.wtid = rh->details.close_details.wtid; - rcc.purpose.size = htonl (sizeof (rcc)); - rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED); - rcc.reserve_pub = *reserve_pub; - timestamp = GNUNET_TIME_timestamp_ntoh (rcc.timestamp); - rh->details.close_details.timestamp = timestamp; - TALER_amount_ntoh (&rh->details.close_details.fee, - &rcc.closing_fee); + key_state = TALER_EXCHANGE_get_keys (exchange); if (GNUNET_OK != - TALER_EXCHANGE_test_signing_key (key_state, - &rh->details.close_details. - exchange_pub)) + TALER_EXCHANGE_test_signing_key ( + key_state, + &rh->details.close_details.exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; } if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED, - &rcc, - &rh->details.close_details.exchange_sig.eddsa_signature, - &rh->details.close_details.exchange_pub.eddsa_pub)) + TALER_exchange_online_reserve_closed_verify ( + rh->details.close_details.timestamp, + &amount, + &rh->details.close_details.fee, + rh->details.close_details.receiver_account_details, + &rh->details.close_details.wtid, + reserve_pub, + &rh->details.close_details.exchange_pub, + &rh->details.close_details.exchange_sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -671,35 +653,29 @@ TALER_EXCHANGE_verify_coin_history ( else if (0 == strcasecmp (type, "RECOUP")) { - struct TALER_RecoupConfirmationPS pc = { - .purpose.size = htonl (sizeof (pc)), - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP), - .coin_pub = *coin_pub - }; + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_TIME_Timestamp timestamp; union TALER_DenominationBlindingKeyP coin_bks; - struct TALER_Amount recoup_amount; struct TALER_ExchangePublicKeyP exchange_pub; struct TALER_ExchangeSignatureP exchange_sig; struct TALER_CoinSpendSignatureP coin_sig; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any_nbo ("amount", - &pc.recoup_amount), TALER_JSON_spec_amount_any ("amount", - &recoup_amount), + &amount), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_spec_fixed_auto ("reserve_pub", - &pc.reserve_pub), + &reserve_pub), GNUNET_JSON_spec_fixed_auto ("coin_sig", &coin_sig), GNUNET_JSON_spec_fixed_auto ("coin_blind", &coin_bks), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", h_denom_pub), - GNUNET_JSON_spec_timestamp_nbo ("timestamp", - &pc.timestamp), + GNUNET_JSON_spec_timestamp ("timestamp", + ×tamp), GNUNET_JSON_spec_end () }; @@ -711,13 +687,14 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_hton (&pc.recoup_amount, - &amount); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP, - &pc, - &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + TALER_exchange_online_confirm_recoup_verify ( + timestamp, + &amount, + coin_pub, + &reserve_pub, + &exchange_pub, + &exchange_sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -738,22 +715,16 @@ TALER_EXCHANGE_verify_coin_history ( { /* This is the coin that was subjected to a recoup, the value being credited to the old coin. */ - struct TALER_RecoupRefreshConfirmationPS pc = { - .purpose.size = htonl (sizeof (pc)), - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), - .coin_pub = *coin_pub - }; + struct TALER_CoinSpendPublicKeyP old_coin_pub; union TALER_DenominationBlindingKeyP coin_bks; - struct TALER_Amount recoup_amount; + struct TALER_Amount amount; + struct GNUNET_TIME_Timestamp timestamp; struct TALER_ExchangePublicKeyP exchange_pub; struct TALER_ExchangeSignatureP exchange_sig; struct TALER_CoinSpendSignatureP coin_sig; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any_nbo ("amount", - &pc.recoup_amount), TALER_JSON_spec_amount_any ("amount", - &recoup_amount), + &amount), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", @@ -761,13 +732,13 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_JSON_spec_fixed_auto ("coin_sig", &coin_sig), GNUNET_JSON_spec_fixed_auto ("old_coin_pub", - &pc.old_coin_pub), + &old_coin_pub), GNUNET_JSON_spec_fixed_auto ("coin_blind", &coin_bks), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", h_denom_pub), - GNUNET_JSON_spec_timestamp_nbo ("timestamp", - &pc.timestamp), + GNUNET_JSON_spec_timestamp ("timestamp", + ×tamp), GNUNET_JSON_spec_end () }; @@ -779,14 +750,14 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_hton (&pc.recoup_amount, - &amount); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH, - &pc, - &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + TALER_exchange_online_confirm_recoup_refresh_verify ( + timestamp, + &amount, + coin_pub, + &old_coin_pub, + &exchange_pub, + &exchange_sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -807,25 +778,21 @@ TALER_EXCHANGE_verify_coin_history ( { /* This is the coin that was credited in a recoup, the value being credited to the this coin. */ - struct TALER_RecoupRefreshConfirmationPS pc = { - .purpose.size = htonl (sizeof (pc)), - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), - .old_coin_pub = *coin_pub - }; struct TALER_ExchangePublicKeyP exchange_pub; struct TALER_ExchangeSignatureP exchange_sig; + struct TALER_CoinSpendPublicKeyP new_coin_pub; + struct GNUNET_TIME_Timestamp timestamp; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any_nbo ("amount", - &pc.recoup_amount), + TALER_JSON_spec_amount_any ("amount", + &amount), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), GNUNET_JSON_spec_fixed_auto ("coin_pub", - &pc.coin_pub), - GNUNET_JSON_spec_timestamp_nbo ("timestamp", - &pc.timestamp), + &new_coin_pub), + GNUNET_JSON_spec_timestamp ("timestamp", + ×tamp), GNUNET_JSON_spec_end () }; @@ -837,14 +804,14 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_hton (&pc.recoup_amount, - &amount); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH, - &pc, - &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + TALER_exchange_online_confirm_recoup_refresh_verify ( + timestamp, + &amount, + &new_coin_pub, + coin_pub, + &exchange_pub, + &exchange_sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index a08a6f422..947a42561 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -361,17 +361,18 @@ handle_deposit_finished (void *cls, } if (GNUNET_OK != - TALER_exchange_deposit_confirm_verify (&dh->h_contract_terms, - &dh->h_wire, - &dh->h_extensions, - dh->exchange_timestamp, - dh->wire_deadline, - dh->refund_deadline, - &dh->amount_without_fee, - &dh->coin_pub, - &dh->merchant_pub, - &dh->exchange_pub, - &dh->exchange_sig)) + TALER_exchange_online_deposit_confirmation_verify ( + &dh->h_contract_terms, + &dh->h_wire, + &dh->h_extensions, + dh->exchange_timestamp, + dh->wire_deadline, + dh->refund_deadline, + &dh->amount_without_fee, + &dh->coin_pub, + &dh->merchant_pub, + &dh->exchange_pub, + &dh->exchange_sig)) { GNUNET_break_op (0); dr.hr.http_status = 0; diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index 5d069d5c8..32c60f1fc 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -70,10 +70,38 @@ struct TALER_EXCHANGE_DepositGetHandle void *cb_cls; /** - * Information the exchange should sign in response. - * (with pre-filled fields from the request). + * Hash over the wiring information of the merchant. */ - struct TALER_ConfirmWirePS depconf; + struct TALER_MerchantWireHashP h_wire; + + /** + * Hash over the contract for which this deposit is made. + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Raw value (binary encoding) of the wire transfer subject. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * The coin's public key. This is the value that must have been + * signed (blindly) by the Exchange. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * When did the exchange execute this transfer? Note that the + * timestamp may not be exactly the same on the wire, i.e. + * because the wire has a different timezone or resolution. + */ + struct GNUNET_TIME_Timestamp execution_time; + + /** + * The contribution of @e coin_pub to the total transfer volume. + * This is the value of the deposit minus the fee. + */ + struct TALER_Amount coin_contribution; }; @@ -87,6 +115,7 @@ struct TALER_EXCHANGE_DepositGetHandle * @param exchange_sig the exchange's signature * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ +// FIXME: inline... static enum GNUNET_GenericReturnValue verify_deposit_wtid_signature_ok ( const struct TALER_EXCHANGE_DepositGetHandle *dwh, @@ -104,10 +133,15 @@ verify_deposit_wtid_signature_ok ( return GNUNET_SYSERR; } if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE, - &dwh->depconf, - &exchange_sig->eddsa_signature, - &exchange_pub->eddsa_pub)) + TALER_exchange_online_confirm_wire_verify ( + &dwh->h_wire, + &dwh->h_contract_terms, + &dwh->wtid, + &dwh->coin_pub, + dwh->execution_time, + &dwh->coin_contribution, + exchange_pub, + exchange_sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -168,11 +202,10 @@ handle_deposit_wtid_finished (void *cls, dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - dwh->depconf.execution_time = GNUNET_TIME_timestamp_hton ( - dr.details.success.execution_time); - dwh->depconf.wtid = dr.details.success.wtid; - TALER_amount_hton (&dwh->depconf.coin_contribution, - &dr.details.success.coin_contribution); + // FIXME: remove once we inline function below... + dwh->execution_time = dr.details.success.execution_time; + dwh->wtid = dr.details.success.wtid; + dwh->coin_contribution = dr.details.success.coin_contribution; if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, &dr.details.success.exchange_pub, @@ -285,6 +318,7 @@ TALER_EXCHANGE_deposits_get ( GNUNET_break (0); return NULL; } + // FIXME: move to helper! dtp.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION); dtp.purpose.size = htonl (sizeof (dtp)); dtp.h_contract_terms = *h_contract_terms; @@ -351,11 +385,9 @@ TALER_EXCHANGE_deposits_get ( GNUNET_free (dwh); return NULL; } - dwh->depconf.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS)); - dwh->depconf.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE); - dwh->depconf.h_wire = *h_wire; - dwh->depconf.h_contract_terms = *h_contract_terms; - dwh->depconf.coin_pub = *coin_pub; + dwh->h_wire = *h_wire; + dwh->h_contract_terms = *h_contract_terms; + dwh->coin_pub = *coin_pub; eh = TALER_EXCHANGE_curl_easy_get_ (dwh->url); if (NULL == eh) diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index e0fcd2b93..feab4ac44 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -1136,11 +1136,7 @@ decode_keys_json (const json_t *resp_obj, if (check_sig) { - struct TALER_ExchangeKeySetPS ks = { - .purpose.size = htonl (sizeof (ks)), - .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET), - .list_issue_date = GNUNET_TIME_timestamp_hton (key_data->list_issue_date) - }; + struct GNUNET_HashCode hc; /* If we had any age restricted denominations, add their hash to the end of * the normal denominations. */ @@ -1160,16 +1156,18 @@ decode_keys_json (const json_t *resp_obj, } GNUNET_CRYPTO_hash_context_finish (hash_context, - &ks.hc); + &hc); hash_context = NULL; EXITIF (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_data, &pub)); + EXITIF (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET, - &ks, - &sig.eddsa_signature, - &pub.eddsa_pub)); + TALER_exchange_online_key_set_verify ( + key_data->list_issue_date, + &hc, + &pub, + &sig)); } return GNUNET_OK; EXITIF_exit: diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c index 303368ea0..1f9f3b160 100644 --- a/src/lib/exchange_api_kyc_check.c +++ b/src/lib/exchange_api_kyc_check.c @@ -105,12 +105,6 @@ handle_kyc_check_finished (void *cls, GNUNET_JSON_spec_end () }; const struct TALER_EXCHANGE_Keys *key_state; - struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = { - .purpose.size = htonl (sizeof (kyc_purpose)), - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS), - .h_payto = kch->h_payto - }; if (GNUNET_OK != GNUNET_JSON_parse (j, @@ -122,8 +116,6 @@ handle_kyc_check_finished (void *cls, ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - kyc_purpose.timestamp = GNUNET_TIME_timestamp_hton ( - ks.details.kyc_ok.timestamp); key_state = TALER_EXCHANGE_get_keys (kch->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, @@ -137,11 +129,11 @@ handle_kyc_check_finished (void *cls, } if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS, - &kyc_purpose, - &ks.details.kyc_ok.exchange_sig.eddsa_signature, - &ks.details.kyc_ok.exchange_pub.eddsa_pub)) + TALER_exchange_online_account_setup_success_verify ( + &kch->h_payto, + ks.details.kyc_ok.timestamp, + &ks.details.kyc_ok.exchange_pub, + &ks.details.kyc_ok.exchange_sig)) { GNUNET_break_op (0); ks.http_status = 0; diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index 96e8c8e20..80c759704 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -170,7 +170,7 @@ verify_melt_signature_ok (struct TALER_EXCHANGE_MeltHandle *mh, } if (GNUNET_OK != - TALER_exchange_melt_confirmation_verify ( + TALER_exchange_online_melt_confirmation_verify ( &mh->md.rc, mh->noreveal_index, exchange_pub, diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 9ae907dc1..6369a5bd6 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -70,9 +70,33 @@ struct TALER_EXCHANGE_RefundHandle void *cb_cls; /** - * Information the exchange should sign in response. + * Hash over the proposal data to identify the contract + * which is being refunded. */ - struct TALER_RefundConfirmationPS depconf; + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * The coin's public key. This is the value that must have been + * signed (blindly) by the Exchange. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * The Merchant's public key. Allows the merchant to later refund + * the transaction or to inquire about the wire transfer identifier. + */ + struct TALER_MerchantPublicKeyP merchant; + + /** + * Merchant-generated transaction ID for the refund. + */ + uint64_t rtransaction_id; + + /** + * Amount to be refunded, including refund fee charged by the + * exchange to the customer. + */ + struct TALER_Amount refund_amount; }; @@ -119,10 +143,14 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, return GNUNET_SYSERR; } if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND, - &rh->depconf, - &exchange_sig->eddsa_signature, - &exchange_pub->eddsa_pub)) + TALER_exchange_online_refund_confirmation_verify ( + &rh->h_contract_terms, + &rh->coin_pub, + &rh->merchant, + rh->rtransaction_id, + &rh->refund_amount, + exchange_pub, + exchange_sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -253,16 +281,16 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, wallet_timestamp, &merchant_pub, refund_deadline, - &rh->depconf.coin_pub, + &rh->coin_pub, &sig)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms, + if ( (0 != GNUNET_memcmp (&rh->h_contract_terms, &h_contract_terms)) || - (0 != GNUNET_memcmp (&rh->depconf.merchant, + (0 != GNUNET_memcmp (&rh->merchant, &merchant_pub)) ) { /* deposit information is about a different merchant/contract */ @@ -334,7 +362,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, return GNUNET_SYSERR; } if (GNUNET_OK != - TALER_merchant_refund_verify (&rh->depconf.coin_pub, + TALER_merchant_refund_verify (&rh->coin_pub, &h_contract_terms, rtransaction_id, &sig_amount, @@ -345,9 +373,9 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms, + if ( (0 != GNUNET_memcmp (&rh->h_contract_terms, &h_contract_terms)) || - (0 != GNUNET_memcmp (&rh->depconf.merchant, + (0 != GNUNET_memcmp (&rh->merchant, &merchant_pub)) ) { /* refund is about a different merchant/contract */ @@ -355,7 +383,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - if (rtransaction_id == rh->depconf.rtransaction_id) + if (rtransaction_id == rh->rtransaction_id) { /* Eh, this shows either a dependency failure or idempotency, but must not happen in a conflict reply. Fail! */ @@ -398,16 +426,12 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, } { - struct TALER_Amount amount; - - TALER_amount_ntoh (&amount, - &rh->depconf.refund_amount); if (have_refund) { if (0 > TALER_amount_add (&rtotal, &rtotal, - &amount)) + &rh->refund_amount)) { GNUNET_break (0); GNUNET_JSON_parse_free (spec); @@ -416,7 +440,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, } else { - rtotal = amount; + rtotal = rh->refund_amount; } } if (-1 == TALER_amount_cmp (&dtotal, @@ -472,7 +496,6 @@ verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh, e = json_array_get (h, 0); { struct TALER_Amount amount; - struct TALER_Amount depconf_amount; const char *type; struct TALER_MerchantSignatureP sig; struct TALER_Amount refund_fee; @@ -507,7 +530,7 @@ verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh, return GNUNET_SYSERR; } if (GNUNET_OK != - TALER_merchant_refund_verify (&rh->depconf.coin_pub, + TALER_merchant_refund_verify (&rh->coin_pub, &h_contract_terms, rtransaction_id, &amount, @@ -518,14 +541,12 @@ verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh, GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - TALER_amount_ntoh (&depconf_amount, - &rh->depconf.refund_amount); - if ( (rtransaction_id != rh->depconf.rtransaction_id) || - (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms, + if ( (rtransaction_id != rh->rtransaction_id) || + (0 != GNUNET_memcmp (&rh->h_contract_terms, &h_contract_terms)) || - (0 != GNUNET_memcmp (&rh->depconf.merchant, + (0 != GNUNET_memcmp (&rh->merchant, &merchant_pub)) || - (0 == TALER_amount_cmp (&depconf_amount, + (0 == TALER_amount_cmp (&rh->refund_amount, &amount)) ) { GNUNET_break_op (0); @@ -669,15 +690,15 @@ handle_refund_finished (void *cls, struct TALER_EXCHANGE_RefundHandle * -TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_Amount *amount, - const struct - TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - uint64_t rtransaction_id, - const struct TALER_MerchantPrivateKeyP *merchant_priv, - TALER_EXCHANGE_RefundCallback cb, - void *cb_cls) +TALER_EXCHANGE_refund ( + struct TALER_EXCHANGE_Handle *exchange, + const struct TALER_Amount *amount, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + uint64_t rtransaction_id, + const struct TALER_MerchantPrivateKeyP *merchant_priv, + TALER_EXCHANGE_RefundCallback cb, + void *cb_cls) { struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_MerchantSignatureP merchant_sig; @@ -735,15 +756,11 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, GNUNET_free (rh); return NULL; } - rh->depconf.purpose.size = htonl (sizeof (struct TALER_RefundConfirmationPS)); - rh->depconf.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND); - rh->depconf.h_contract_terms = *h_contract_terms; - rh->depconf.coin_pub = *coin_pub; - rh->depconf.merchant = merchant_pub; - rh->depconf.rtransaction_id = GNUNET_htonll (rtransaction_id); - TALER_amount_hton (&rh->depconf.refund_amount, - amount); - + rh->h_contract_terms = *h_contract_terms; + rh->coin_pub = *coin_pub; + rh->merchant = merchant_pub; + rh->rtransaction_id = rtransaction_id; + rh->refund_amount = *amount; eh = TALER_EXCHANGE_curl_easy_get_ (rh->url); if ( (NULL == eh) || (GNUNET_OK != diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c index b9a9db941..23a0ee76b 100644 --- a/src/lib/exchange_api_transfers_get.c +++ b/src/lib/exchange_api_transfers_get.c @@ -177,43 +177,29 @@ check_transfers_get_response_ok ( return GNUNET_SYSERR; } /* build up big hash for signature checking later */ - { - struct TALER_WireDepositDetailP dd; - - dd.h_contract_terms = detail->h_contract_terms; - dd.execution_time = GNUNET_TIME_timestamp_hton (td.execution_time); - dd.coin_pub = detail->coin_pub; - TALER_amount_hton (&dd.deposit_value, - &detail->coin_value); - TALER_amount_hton (&dd.deposit_fee, - &detail->coin_fee); - GNUNET_CRYPTO_hash_context_read (hash_context, - &dd, - sizeof (dd)); - } + TALER_exchange_online_wire_deposit_append ( + hash_context, + &detail->h_contract_terms, + td.execution_time, + &detail->coin_pub, + &detail->coin_value, + &detail->coin_fee); } /* Check signature */ { - struct TALER_WireDepositDataPS wdp = { - .purpose.purpose = htonl ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), - .purpose.size = htonl (sizeof (wdp)), - .merchant_pub = merchant_pub, - .h_payto = td.h_payto - }; + struct GNUNET_HashCode h_details; - TALER_amount_hton (&wdp.total, - &td.total_amount); - TALER_amount_hton (&wdp.wire_fee, - &td.wire_fee); GNUNET_CRYPTO_hash_context_finish (hash_context, - &wdp.h_details); + &h_details); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify ( - TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, - &wdp, - &td.exchange_sig.eddsa_signature, - &td.exchange_pub.eddsa_pub)) + TALER_exchange_online_wire_deposit_verify ( + &td.total_amount, + &td.wire_fee, + &merchant_pub, + &td.h_payto, + &h_details, + &td.exchange_pub, + &td.exchange_sig)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); @@ -330,16 +316,6 @@ handle_transfers_get_finished (void *cls, } -/** - * Query the exchange about which transactions were combined - * to create a wire transfer. - * - * @param exchange exchange to query - * @param wtid raw wire transfer identifier to get information about - * @param cb callback to call - * @param cb_cls closure for @a cb - * @return handle to cancel operation - */ struct TALER_EXCHANGE_TransfersGetHandle * TALER_EXCHANGE_transfers_get ( struct TALER_EXCHANGE_Handle *exchange, @@ -369,8 +345,7 @@ TALER_EXCHANGE_transfers_get ( char *end; end = GNUNET_STRINGS_data_to_string (wtid, - sizeof (struct - TALER_WireTransferIdentifierRawP), + sizeof (wtid), wtid_str, sizeof (wtid_str)); *end = '\0'; diff --git a/src/util/auditor_signatures.c b/src/util/auditor_signatures.c index 77db296c7..c35b6f192 100644 --- a/src/util/auditor_signatures.c +++ b/src/util/auditor_signatures.c @@ -23,6 +23,89 @@ #include "taler_signatures.h" +/** + * @brief Information signed by an auditor affirming + * the master public key and the denomination keys + * of a exchange. + */ +struct TALER_ExchangeKeyValidityPS +{ + + /** + * Purpose is #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the auditor's URL (including 0-terminator). + */ + struct GNUNET_HashCode auditor_url_hash; + + /** + * The long-term offline master key of the exchange, affirmed by the + * auditor. + */ + struct TALER_MasterPublicKeyP master; + + /** + * Start time of the validity period for this key. + */ + struct GNUNET_TIME_TimestampNBO start; + + /** + * The exchange will sign fresh coins between @e start and this time. + * @e expire_withdraw will be somewhat larger than @e start to + * ensure a sufficiently large anonymity set, while also allowing + * the Exchange to limit the financial damage in case of a key being + * compromised. Thus, exchanges with low volume are expected to have a + * longer withdraw period (@e expire_withdraw - @e start) than exchanges + * with high transaction volume. The period may also differ between + * types of coins. A exchange may also have a few denomination keys + * with the same value with overlapping validity periods, to address + * issues such as clock skew. + */ + struct GNUNET_TIME_TimestampNBO expire_withdraw; + + /** + * Coins signed with the denomination key must be spent or refreshed + * between @e start and this expiration time. After this time, the + * exchange will refuse transactions involving this key as it will + * "drop" the table with double-spending information (shortly after) + * this time. Note that wallets should refresh coins significantly + * before this time to be on the safe side. @e expire_deposit must be + * significantly larger than @e expire_withdraw (by months or even + * years). + */ + struct GNUNET_TIME_TimestampNBO expire_deposit; + + /** + * When do signatures with this denomination key become invalid? + * After this point, these signatures cannot be used in (legal) + * disputes anymore, as the Exchange is then allowed to destroy its side + * of the evidence. @e expire_legal is expected to be significantly + * larger than @e expire_deposit (by a year or more). + */ + struct GNUNET_TIME_TimestampNBO expire_legal; + + /** + * The value of the coins signed with this denomination key. + */ + struct TALER_AmountNBO value; + + /** + * Fees for the coin. + */ + struct TALER_DenomFeeSetNBOP fees; + + /** + * Hash code of the denomination public key. (Used to avoid having + * the variable-size RSA key in this struct.) + */ + struct TALER_DenominationHashP denom_hash GNUNET_PACKED; + +}; + + void TALER_auditor_denom_validity_sign ( const char *auditor_url, diff --git a/src/util/exchange_signatures.c b/src/util/exchange_signatures.c index b4a1f9d70..4890ca206 100644 --- a/src/util/exchange_signatures.c +++ b/src/util/exchange_signatures.c @@ -23,8 +23,114 @@ #include "taler_signatures.h" +/** + * @brief Format used to generate the signature on a confirmation + * from the exchange that a deposit request succeeded. + */ +struct TALER_DepositConfirmationPS +{ + /** + * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. Signed + * by a `struct TALER_ExchangePublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the contract for which this deposit is made. + */ + struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; + + /** + * Hash over the wiring information of the merchant. + */ + struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; + + /** + * Hash over the extension options of the deposit, 0 if there + * were not extension options. + */ + struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED; + + /** + * Time when this confirmation was generated / when the exchange received + * the deposit request. + */ + struct GNUNET_TIME_TimestampNBO exchange_timestamp; + + /** + * By when does the exchange expect to pay the merchant + * (as per the merchant's request). + */ + struct GNUNET_TIME_TimestampNBO wire_deadline; + + /** + * How much time does the @e merchant have to issue a refund + * request? Zero if refunds are not allowed. After this time, the + * coin cannot be refunded. Note that the wire transfer will not be + * performed by the exchange until the refund deadline. This value + * is taken from the original deposit request. + */ + struct GNUNET_TIME_TimestampNBO refund_deadline; + + /** + * Amount to be deposited, excluding fee. Calculated from the + * amount with fee and the fee from the deposit request. + */ + struct TALER_AmountNBO amount_without_fee; + + /** + * The public key of the coin that was deposited. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * The Merchant's public key. Allows the merchant to later refund + * the transaction or to inquire about the wire transfer identifier. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + +}; + + +enum TALER_ErrorCode +TALER_exchange_online_deposit_confirmation_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_ExtensionContractHashP *h_extensions, + struct GNUNET_TIME_Timestamp exchange_timestamp, + struct GNUNET_TIME_Timestamp wire_deadline, + struct GNUNET_TIME_Timestamp refund_deadline, + const struct TALER_Amount *amount_without_fee, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_DepositConfirmationPS dcs = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT), + .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)), + .h_contract_terms = *h_contract_terms, + .h_wire = *h_wire, + .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp), + .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline), + .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline), + .coin_pub = *coin_pub, + .merchant_pub = *merchant_pub + }; + + if (NULL != h_extensions) + dcs.h_extensions = *h_extensions; + TALER_amount_hton (&dcs.amount_without_fee, + amount_without_fee); + return scb (&dcs.purpose, + pub, + sig); +} + + enum GNUNET_GenericReturnValue -TALER_exchange_deposit_confirm_verify ( +TALER_exchange_online_deposit_confirmation_verify ( const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_MerchantWireHashP *h_wire, const struct TALER_ExtensionContractHashP *h_extensions, @@ -66,8 +172,161 @@ TALER_exchange_deposit_confirm_verify ( } +/** + * @brief Format used to generate the signature on a request to refund + * a coin into the account of the customer. + */ +struct TALER_RefundConfirmationPS +{ + /** + * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the proposal data to identify the contract + * which is being refunded. + */ + struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; + + /** + * The coin's public key. This is the value that must have been + * signed (blindly) by the Exchange. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * The Merchant's public key. Allows the merchant to later refund + * the transaction or to inquire about the wire transfer identifier. + */ + struct TALER_MerchantPublicKeyP merchant; + + /** + * Merchant-generated transaction ID for the refund. + */ + uint64_t rtransaction_id GNUNET_PACKED; + + /** + * Amount to be refunded, including refund fee charged by the + * exchange to the customer. + */ + struct TALER_AmountNBO refund_amount; +}; + + +enum TALER_ErrorCode +TALER_exchange_online_refund_confirmation_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant, + uint64_t rtransaction_id, + const struct TALER_Amount *refund_amount, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_RefundConfirmationPS rc = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND), + .purpose.size = htonl (sizeof (rc)), + .h_contract_terms = *h_contract_terms, + .coin_pub = *coin_pub, + .merchant = *merchant, + .rtransaction_id = GNUNET_htonll (rtransaction_id) + }; + + TALER_amount_hton (&rc.refund_amount, + refund_amount); + return scb (&rc.purpose, + pub, + sig); +} + + enum GNUNET_GenericReturnValue -TALER_exchange_melt_confirmation_verify ( +TALER_exchange_online_refund_confirmation_verify ( + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_MerchantPublicKeyP *merchant, + uint64_t rtransaction_id, + const struct TALER_Amount *refund_amount, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_RefundConfirmationPS rc = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND), + .purpose.size = htonl (sizeof (rc)), + .h_contract_terms = *h_contract_terms, + .coin_pub = *coin_pub, + .merchant = *merchant, + .rtransaction_id = GNUNET_htonll (rtransaction_id) + }; + + TALER_amount_hton (&rc.refund_amount, + refund_amount); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND, + &rc, + &sig->eddsa_signature, + &pub->eddsa_pub)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * @brief Format of the block signed by the Exchange in response to a successful + * "/refresh/melt" request. Hereby the exchange affirms that all of the + * coins were successfully melted. This also commits the exchange to a + * particular index to not be revealed during the refresh. + */ +struct TALER_RefreshMeltConfirmationPS +{ + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT. Signed + * by a `struct TALER_ExchangePublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Commitment made in the /refresh/melt. + */ + struct TALER_RefreshCommitmentP rc GNUNET_PACKED; + + /** + * Index that the client will not have to reveal, in NBO. + * Must be smaller than #TALER_CNC_KAPPA. + */ + uint32_t noreveal_index GNUNET_PACKED; + +}; + + +enum TALER_ErrorCode +TALER_exchange_online_melt_confirmation_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_RefreshCommitmentP *rc, + uint32_t noreveal_index, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_RefreshMeltConfirmationPS confirm = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT), + .purpose.size = htonl (sizeof (confirm)), + .rc = *rc, + .noreveal_index = htonl (noreveal_index) + }; + + return scb (&confirm.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_melt_confirmation_verify ( const struct TALER_RefreshCommitmentP *rc, uint32_t noreveal_index, const struct TALER_ExchangePublicKeyP *exchange_pub, @@ -88,4 +347,866 @@ TALER_exchange_melt_confirmation_verify ( } +/** + * @brief Signature made by the exchange over the full set of keys, used + * to detect cheating exchanges that give out different sets to + * different users. + */ +struct TALER_ExchangeKeySetPS +{ + + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET. Signed + * by a `struct TALER_ExchangePublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time of the key set issue. + */ + struct GNUNET_TIME_TimestampNBO list_issue_date; + + /** + * Hash over the various denomination signing keys returned. + */ + struct GNUNET_HashCode hc GNUNET_PACKED; +}; + + +enum TALER_ErrorCode +TALER_exchange_online_key_set_sign ( + TALER_ExchangeSignCallback2 scb, + void *cls, + struct GNUNET_TIME_Timestamp timestamp, + const struct GNUNET_HashCode *hc, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_ExchangeKeySetPS ks = { + .purpose.size = htonl (sizeof (ks)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET), + .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp), + .hc = *hc + }; + + return scb (cls, + &ks.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_key_set_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct GNUNET_HashCode *hc, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_ExchangeKeySetPS ks = { + .purpose.size = htonl (sizeof (ks)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET), + .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp), + .hc = *hc + }; + + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET, + &ks, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * @brief Signature by which an exchange affirms that an account + * successfully passed the KYC checks. + */ +struct TALER_ExchangeAccountSetupSuccessPS +{ + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS. Signed by a + * `struct TALER_ExchangePublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the payto for which the signature was + * made. + */ + struct TALER_PaytoHashP h_payto; + + /** + * When was the signature made. + */ + struct GNUNET_TIME_TimestampNBO timestamp; +}; + + +enum TALER_ErrorCode +TALER_exchange_online_account_setup_success_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp timestamp, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = { + .purpose.size = htonl (sizeof (kyc_purpose)), + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS), + .h_payto = *h_payto, + .timestamp = GNUNET_TIME_timestamp_hton ( + timestamp) + }; + + return scb (&kyc_purpose.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_account_setup_success_verify ( + const struct TALER_PaytoHashP *h_payto, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = { + .purpose.size = htonl (sizeof (kyc_purpose)), + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS), + .h_payto = *h_payto, + .timestamp = GNUNET_TIME_timestamp_hton ( + timestamp) + }; + + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS, + &kyc_purpose, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * @brief Format internally used for packing the detailed information + * to generate the signature for /track/transfer signatures. + */ +struct TALER_WireDepositDetailP +{ + + /** + * Hash of the contract + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Time when the wire transfer was performed by the exchange. + */ + struct GNUNET_TIME_TimestampNBO execution_time; + + /** + * Coin's public key. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Total value of the coin. + */ + struct TALER_AmountNBO deposit_value; + + /** + * Fees charged by the exchange for the deposit. + */ + struct TALER_AmountNBO deposit_fee; + +}; + + +void +TALER_exchange_online_wire_deposit_append ( + struct GNUNET_HashContext *hash_context, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp execution_time, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *deposit_value, + const struct TALER_Amount *deposit_fee) +{ + struct TALER_WireDepositDetailP dd = { + .h_contract_terms = *h_contract_terms, + .execution_time = GNUNET_TIME_timestamp_hton (execution_time), + .coin_pub = *coin_pub + }; + TALER_amount_hton (&dd.deposit_value, + deposit_value); + TALER_amount_hton (&dd.deposit_fee, + deposit_fee); + GNUNET_CRYPTO_hash_context_read (hash_context, + &dd, + sizeof (dd)); +} + + +/** + * @brief Format used to generate the signature for /wire/deposit + * replies. + */ +struct TALER_WireDepositDataPS +{ + /** + * Purpose header for the signature over the contract with + * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Total amount that was transferred. + */ + struct TALER_AmountNBO total; + + /** + * Wire fee that was charged. + */ + struct TALER_AmountNBO wire_fee; + + /** + * Public key of the merchant (for all aggregated transactions). + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Hash of bank account of the merchant. + */ + struct TALER_PaytoHashP h_payto; + + /** + * Hash of the individual deposits that were aggregated, + * each in the format of a `struct TALER_WireDepositDetailP`. + */ + struct GNUNET_HashCode h_details; + +}; + + +enum TALER_ErrorCode +TALER_exchange_online_wire_deposit_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_Amount *total, + const struct TALER_Amount *wire_fee, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *payto, + const struct GNUNET_HashCode *h_details, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_WireDepositDataPS wdp = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), + .purpose.size = htonl (sizeof (wdp)), + .merchant_pub = *merchant_pub, + .h_details = *h_details + }; + + TALER_amount_hton (&wdp.total, + total); + TALER_amount_hton (&wdp.wire_fee, + wire_fee); + TALER_payto_hash (payto, + &wdp.h_payto); + return scb (&wdp.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_wire_deposit_verify ( + const struct TALER_Amount *total, + const struct TALER_Amount *wire_fee, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_PaytoHashP *h_payto, + const struct GNUNET_HashCode *h_details, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_WireDepositDataPS wdp = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), + .purpose.size = htonl (sizeof (wdp)), + .merchant_pub = *merchant_pub, + .h_details = *h_details, + .h_payto = *h_payto + }; + + TALER_amount_hton (&wdp.total, + total); + TALER_amount_hton (&wdp.wire_fee, + wire_fee); + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, + &wdp, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * Details affirmed by the exchange about a wire transfer the exchange + * claims to have done with respect to a deposit operation. + */ +struct TALER_ConfirmWirePS +{ + /** + * Purpose header for the signature over the contract with + * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the wiring information of the merchant. + */ + struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; + + /** + * Hash over the contract for which this deposit is made. + */ + struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; + + /** + * Raw value (binary encoding) of the wire transfer subject. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * The coin's public key. This is the value that must have been + * signed (blindly) by the Exchange. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * When did the exchange execute this transfer? Note that the + * timestamp may not be exactly the same on the wire, i.e. + * because the wire has a different timezone or resolution. + */ + struct GNUNET_TIME_TimestampNBO execution_time; + + /** + * The contribution of @e coin_pub to the total transfer volume. + * This is the value of the deposit minus the fee. + */ + struct TALER_AmountNBO coin_contribution; + +}; + + +enum TALER_ErrorCode +TALER_exchange_online_confirm_wire_sign ( + TALER_ExchangeSignCallback scb, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct GNUNET_TIME_Timestamp execution_time, + const struct TALER_Amount *coin_contribution, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) + +{ + struct TALER_ConfirmWirePS cw = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE), + .purpose.size = htonl (sizeof (cw)), + .h_wire = *h_wire, + .h_contract_terms = *h_contract_terms, + .wtid = *wtid, + .coin_pub = *coin_pub, + .execution_time = GNUNET_TIME_timestamp_hton (execution_time) + }; + + TALER_amount_hton (&cw.coin_contribution, + coin_contribution); + return scb (&cw.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_confirm_wire_verify ( + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct GNUNET_TIME_Timestamp execution_time, + const struct TALER_Amount *coin_contribution, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_ConfirmWirePS cw = { + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE), + .purpose.size = htonl (sizeof (cw)), + .h_wire = *h_wire, + .h_contract_terms = *h_contract_terms, + .wtid = *wtid, + .coin_pub = *coin_pub, + .execution_time = GNUNET_TIME_timestamp_hton (execution_time) + }; + + TALER_amount_hton (&cw.coin_contribution, + coin_contribution); + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE, + &cw, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * Response by which the exchange affirms that it will + * refund a coin as part of the emergency /recoup + * protocol. The recoup will go back to the bank + * account that created the reserve. + */ +struct TALER_RecoupConfirmationPS +{ + + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When did the exchange receive the recoup request? + * Indirectly determines when the wire transfer is (likely) + * to happen. + */ + struct GNUNET_TIME_TimestampNBO timestamp; + + /** + * How much of the coin's value will the exchange transfer? + * (Needed in case the coin was partially spent.) + */ + struct TALER_AmountNBO recoup_amount; + + /** + * Public key of the coin. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Public key of the reserve that will receive the recoup. + */ + struct TALER_ReservePublicKeyP reserve_pub; +}; + + +enum TALER_ErrorCode +TALER_exchange_online_confirm_recoup_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_RecoupConfirmationPS pc = { + .purpose.size = htonl (sizeof (pc)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP), + .reserve_pub = *reserve_pub, + .coin_pub = *coin_pub + }; + + TALER_amount_hton (&pc.recoup_amount, + recoup_amount); + return scb (&pc.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_confirm_recoup_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_RecoupConfirmationPS pc = { + .purpose.size = htonl (sizeof (pc)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP), + .reserve_pub = *reserve_pub, + .coin_pub = *coin_pub + }; + + TALER_amount_hton (&pc.recoup_amount, + recoup_amount); + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP, + &pc, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * Response by which the exchange affirms that it will refund a refreshed coin + * as part of the emergency /recoup protocol. The recoup will go back to the + * old coin's balance. + */ +struct TALER_RecoupRefreshConfirmationPS +{ + + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When did the exchange receive the recoup request? + * Indirectly determines when the wire transfer is (likely) + * to happen. + */ + struct GNUNET_TIME_TimestampNBO timestamp; + + /** + * How much of the coin's value will the exchange transfer? + * (Needed in case the coin was partially spent.) + */ + struct TALER_AmountNBO recoup_amount; + + /** + * Public key of the refreshed coin. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Public key of the old coin that will receive the recoup. + */ + struct TALER_CoinSpendPublicKeyP old_coin_pub; +}; + + +enum TALER_ErrorCode +TALER_exchange_online_confirm_recoup_refresh_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_RecoupRefreshConfirmationPS pc = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), + .purpose.size = htonl (sizeof (pc)), + .timestamp = GNUNET_TIME_timestamp_hton (timestamp), + .coin_pub = *coin_pub, + .old_coin_pub = *old_coin_pub + }; + + TALER_amount_hton (&pc.recoup_amount, + recoup_amount); + return scb (&pc.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_confirm_recoup_refresh_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *recoup_amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_RecoupRefreshConfirmationPS pc = { + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), + .purpose.size = htonl (sizeof (pc)), + .timestamp = GNUNET_TIME_timestamp_hton (timestamp), + .coin_pub = *coin_pub, + .old_coin_pub = *old_coin_pub + }; + + TALER_amount_hton (&pc.recoup_amount, + recoup_amount); + + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH, + &pc, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * Response by which the exchange affirms that it does not + * currently know a denomination by the given hash. + */ +struct TALER_DenominationUnknownAffirmationPS +{ + + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When did the exchange sign this message. + */ + struct GNUNET_TIME_TimestampNBO timestamp; + + /** + * Hash of the public denomination key we do not know. + */ + struct TALER_DenominationHashP h_denom_pub; +}; + + +enum TALER_ErrorCode +TALER_exchange_online_denomination_unknown_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_DenominationUnknownAffirmationPS dua = { + .purpose.size = htonl (sizeof (dua)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN), + .timestamp = GNUNET_TIME_timestamp_hton (timestamp), + .h_denom_pub = *h_denom_pub, + }; + + return scb (&dua.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_denomination_unknown_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_DenominationUnknownAffirmationPS dua = { + .purpose.size = htonl (sizeof (dua)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN), + .timestamp = GNUNET_TIME_timestamp_hton (timestamp), + .h_denom_pub = *h_denom_pub, + }; + + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN, + &dua, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * Response by which the exchange affirms that it does not + * currently consider the given denomination to be valid + * for the requested operation. + */ +struct TALER_DenominationExpiredAffirmationPS +{ + + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When did the exchange sign this message. + */ + struct GNUNET_TIME_TimestampNBO timestamp; + + /** + * Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s. + */ + char operation[8]; + + /** + * Hash of the public denomination key we do not know. + */ + struct TALER_DenominationHashP h_denom_pub; + +}; + + +enum TALER_ErrorCode +TALER_exchange_online_denomination_expired_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + const char *op, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_DenominationExpiredAffirmationPS dua = { + .purpose.size = htonl (sizeof (dua)), + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED), + .timestamp = GNUNET_TIME_timestamp_hton (timestamp), + .h_denom_pub = *h_denom_pub, + }; + + /* strncpy would create a compiler warning */ + memcpy (dua.operation, + op, + GNUNET_MIN (sizeof (dua.operation), + strlen (op))); + return scb (&dua.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_denomination_expired_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_DenominationHashP *h_denom_pub, + const char *op, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_DenominationExpiredAffirmationPS dua = { + .purpose.size = htonl (sizeof (dua)), + .purpose.purpose = htonl ( + TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED), + .timestamp = GNUNET_TIME_timestamp_hton (timestamp), + .h_denom_pub = *h_denom_pub, + }; + + /* strncpy would create a compiler warning */ + memcpy (dua.operation, + op, + GNUNET_MIN (sizeof (dua.operation), + strlen (op))); + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED, + &dua, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + +/** + * Response by which the exchange affirms that it has + * closed a reserve and send back the funds. + */ +struct TALER_ReserveCloseConfirmationPS +{ + + /** + * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When did the exchange initiate the wire transfer. + */ + struct GNUNET_TIME_TimestampNBO timestamp; + + /** + * How much did the exchange send? + */ + struct TALER_AmountNBO closing_amount; + + /** + * How much did the exchange charge for closing the reserve? + */ + struct TALER_AmountNBO closing_fee; + + /** + * Public key of the reserve that was closed. + */ + struct TALER_ReservePublicKeyP reserve_pub; + + /** + * Hash of the receiver's bank account. + */ + struct TALER_PaytoHashP h_payto; + + /** + * Wire transfer subject. + */ + struct TALER_WireTransferIdentifierRawP wtid; +}; + + +enum TALER_ErrorCode +TALER_exchange_online_reserve_closed_sign ( + TALER_ExchangeSignCallback scb, + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *closing_amount, + const struct TALER_Amount *closing_fee, + const char *payto, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_ExchangePublicKeyP *pub, + struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_ReserveCloseConfirmationPS rcc = { + .purpose.size = htonl (sizeof (rcc)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED), + .wtid = *wtid, + .reserve_pub = *reserve_pub, + .timestamp = GNUNET_TIME_timestamp_hton (timestamp) + }; + + TALER_amount_hton (&rcc.closing_amount, + closing_amount); + TALER_amount_hton (&rcc.closing_fee, + closing_fee); + TALER_payto_hash (payto, + &rcc.h_payto); + return scb (&rcc.purpose, + pub, + sig); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_online_reserve_closed_verify ( + struct GNUNET_TIME_Timestamp timestamp, + const struct TALER_Amount *closing_amount, + const struct TALER_Amount *closing_fee, + const char *payto, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ExchangePublicKeyP *pub, + const struct TALER_ExchangeSignatureP *sig) +{ + struct TALER_ReserveCloseConfirmationPS rcc = { + .purpose.size = htonl (sizeof (rcc)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED), + .wtid = *wtid, + .reserve_pub = *reserve_pub, + .timestamp = GNUNET_TIME_timestamp_hton (timestamp) + }; + + TALER_amount_hton (&rcc.closing_amount, + closing_amount); + TALER_amount_hton (&rcc.closing_fee, + closing_fee); + TALER_payto_hash (payto, + &rcc.h_payto); + return + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED, + &rcc, + &sig->eddsa_signature, + &pub->eddsa_pub); +} + + /* end of exchange_signatures.c */ diff --git a/src/util/secmod_signatures.c b/src/util/secmod_signatures.c index 8e629ebbc..3b539d5fe 100644 --- a/src/util/secmod_signatures.c +++ b/src/util/secmod_signatures.c @@ -23,6 +23,37 @@ #include "taler_signatures.h" +/** + * @brief format used by the signing crypto helper when affirming + * that it created an exchange signing key. + */ +struct TALER_SigningKeyAnnouncementPS +{ + + /** + * Purpose must be #TALER_SIGNATURE_SM_SIGNING_KEY. + * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Public signing key of the exchange this is about. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * When does the key become available? + */ + struct GNUNET_TIME_TimestampNBO anchor_time; + + /** + * How long is the key available after @e anchor_time? + */ + struct GNUNET_TIME_RelativeNBO duration; + +}; + + void TALER_exchange_secmod_eddsa_sign ( const struct TALER_ExchangePublicKeyP *exchange_pub, @@ -69,6 +100,41 @@ TALER_exchange_secmod_eddsa_verify ( } +/** + * @brief format used by the denomination crypto helper when affirming + * that it created a denomination key. + */ +struct TALER_DenominationKeyAnnouncementPS +{ + + /** + * Purpose must be #TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY. + * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the denomination public key. + */ + struct TALER_DenominationHashP h_denom; + + /** + * Hash of the section name in the configuration of this denomination. + */ + struct GNUNET_HashCode h_section_name; + + /** + * When does the key become available? + */ + struct GNUNET_TIME_TimestampNBO anchor_time; + + /** + * How long is the key available after @e anchor_time? + */ + struct GNUNET_TIME_RelativeNBO duration_withdraw; + +}; + void TALER_exchange_secmod_rsa_sign ( const struct TALER_RsaPubHashP *h_rsa,