From cc5d09cf1d28e31ca8eca054b7da2c3873e2efe7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 7 Oct 2017 15:10:24 +0200 Subject: properly handle signing errors if httpd lacks signing keys by returning internal errors (and handling new return value from TEH_KS_sign) --- src/exchange/taler-exchange-httpd_deposit.c | 12 +++++-- src/exchange/taler-exchange-httpd_keystate.c | 15 ++++++--- src/exchange/taler-exchange-httpd_keystate.h | 3 +- src/exchange/taler-exchange-httpd_payback.c | 12 +++++-- src/exchange/taler-exchange-httpd_refresh_melt.c | 12 +++++-- src/exchange/taler-exchange-httpd_refund.c | 12 +++++-- src/exchange/taler-exchange-httpd_responses.c | 38 ++++++++++++++++------ .../taler-exchange-httpd_track_transaction.c | 12 +++++-- src/exchange/taler-exchange-httpd_track_transfer.c | 14 ++++++-- 9 files changed, 97 insertions(+), 33 deletions(-) (limited to 'src/exchange') diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index ea77216f0..b7fb3452c 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -78,9 +78,15 @@ reply_deposit_success (struct MHD_Connection *connection, amount_without_fee); dc.coin_pub = *coin_pub; dc.merchant = *merchant; - TEH_KS_sign (&dc.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&dc.purpose, + &pub, + &sig)) + { + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:s, s:o, s:o}", diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c index 033995c6a..6f3ced2b5 100644 --- a/src/exchange/taler-exchange-httpd_keystate.c +++ b/src/exchange/taler-exchange-httpd_keystate.c @@ -1845,8 +1845,9 @@ read_again: * @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 #GNUNET_OK on success, #GNUNET_SYSERR if we lack key material */ -void +int TEH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct TALER_ExchangePublicKeyP *pub, struct TALER_ExchangeSignatureP *sig) @@ -1855,15 +1856,21 @@ TEH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct TEH_KS_StateHandle *key_state; key_state = TEH_KS_acquire (); - GNUNET_assert (NULL != key_state); /* This *can* happen if the exchange's keys are - not properly maintained, but in this case we - simply have no good way forward. */ + if (NULL == key_state) + { + /* This *can* happen if the exchange's keys are + not properly maintained. */ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Cannot sign request, no valid keys available\n")); + return GNUNET_SYSERR; + } *pub = key_state->current_sign_key_issue.issue.signkey_pub; GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (&key_state->current_sign_key_issue.signkey_priv.eddsa_priv, purpose, &sig->eddsa_signature)); TEH_KS_release (key_state); + return GNUNET_OK; } diff --git a/src/exchange/taler-exchange-httpd_keystate.h b/src/exchange/taler-exchange-httpd_keystate.h index b2fb6f6d7..b956c6308 100644 --- a/src/exchange/taler-exchange-httpd_keystate.h +++ b/src/exchange/taler-exchange-httpd_keystate.h @@ -140,8 +140,9 @@ TEH_KS_loop (void); * @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 #GNUNET_OK on success, #GNUNET_SYSERR if we lack key material */ -void +int TEH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct TALER_ExchangePublicKeyP *pub, struct TALER_ExchangeSignatureP *sig); diff --git a/src/exchange/taler-exchange-httpd_payback.c b/src/exchange/taler-exchange-httpd_payback.c index 4e2e1e46a..e6fade49e 100644 --- a/src/exchange/taler-exchange-httpd_payback.c +++ b/src/exchange/taler-exchange-httpd_payback.c @@ -82,9 +82,15 @@ reply_payback_success (struct MHD_Connection *connection, amount); pc.coin_pub = *coin_pub; pc.reserve_pub = *reserve_pub; - TEH_KS_sign (&pc.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&pc.purpose, + &pub, + &sig)) + { + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o, s:o, s:o, s:o, s:o}", diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c index c9914f222..320ec9d8b 100644 --- a/src/exchange/taler-exchange-httpd_refresh_melt.c +++ b/src/exchange/taler-exchange-httpd_refresh_melt.c @@ -135,9 +135,15 @@ reply_refresh_melt_success (struct MHD_Connection *connection, body.session_hash = *session_hash; body.noreveal_index = htons (noreveal_index); body.reserved = htons (0); - TEH_KS_sign (&body.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&body.purpose, + &pub, + &sig)) + { + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } sig_json = GNUNET_JSON_from_data_auto (&sig); GNUNET_assert (NULL != sig_json); return TEH_RESPONSE_reply_json_pack (connection, diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c index 46c6dfd46..f0aaa65c0 100644 --- a/src/exchange/taler-exchange-httpd_refund.c +++ b/src/exchange/taler-exchange-httpd_refund.c @@ -61,9 +61,15 @@ reply_refund_success (struct MHD_Connection *connection, &refund->refund_amount); TALER_amount_hton (&rc.refund_fee, &refund->refund_fee); - TEH_KS_sign (&rc.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&rc.purpose, + &pub, + &sig)) + { + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:s, s:o, s:o}", diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 1b45a0cc7..ac86416f3 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -474,7 +474,7 @@ TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection) * Compile the transaction history of a coin into a JSON object. * * @param tl transaction history to JSON-ify - * @return json representation of the @a rh + * @return json representation of the @a rh, NULL on error */ json_t * TEH_RESPONSE_compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl) @@ -632,9 +632,15 @@ TEH_RESPONSE_compile_transaction_history (const struct TALER_EXCHANGEDB_Transact &payback->value); pc.coin_pub = payback->coin.coin_pub; pc.reserve_pub = payback->reserve_pub; - TEH_KS_sign (&pc.purpose, - &epub, - &esig); + if (GNUNET_OK != + TEH_KS_sign (&pc.purpose, + &epub, + &esig)) + { + GNUNET_break (0); + json_decref (history); + return NULL; + } GNUNET_assert (0 == json_array_append_new (history, json_pack ("{s:s, s:o, s:o, s:o, s:o, s:o}", @@ -796,9 +802,15 @@ TEH_RESPONSE_compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHisto &payback->value); pc.coin_pub = payback->coin.coin_pub; pc.reserve_pub = payback->reserve_pub; - TEH_KS_sign (&pc.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&pc.purpose, + &pub, + &sig)) + { + GNUNET_break (0); + json_decref (json_history); + return NULL; + } GNUNET_assert (0 == json_array_append_new (json_history, @@ -852,9 +864,15 @@ TEH_RESPONSE_compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHisto return NULL; } rcc.wtid = pos->details.closing->wtid; - TEH_KS_sign (&rcc.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&rcc.purpose, + &pub, + &sig)) + { + GNUNET_break (0); + json_decref (json_history); + return NULL; + } GNUNET_assert (0 == json_array_append_new (json_history, json_pack ("{s:s, s:O, s:o, s:o, s:o, s:o, s:o, s:o}", diff --git a/src/exchange/taler-exchange-httpd_track_transaction.c b/src/exchange/taler-exchange-httpd_track_transaction.c index 7c1bd6a37..13a106621 100644 --- a/src/exchange/taler-exchange-httpd_track_transaction.c +++ b/src/exchange/taler-exchange-httpd_track_transaction.c @@ -85,9 +85,15 @@ reply_track_transaction (struct MHD_Connection *connection, cw.execution_time = GNUNET_TIME_absolute_hton (exec_time); TALER_amount_hton (&cw.coin_contribution, coin_contribution); - TEH_KS_sign (&cw.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&cw.purpose, + &pub, + &sig)) + { + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o, s:o, s:o, s:o, s:o}", diff --git a/src/exchange/taler-exchange-httpd_track_transfer.c b/src/exchange/taler-exchange-httpd_track_transfer.c index 57b621e48..4d28096be 100644 --- a/src/exchange/taler-exchange-httpd_track_transfer.c +++ b/src/exchange/taler-exchange-httpd_track_transfer.c @@ -131,9 +131,17 @@ reply_track_transfer_details (struct MHD_Connection *connection, wdp.h_wire = *h_wire; GNUNET_CRYPTO_hash_context_finish (hash_context, &wdp.h_details); - TEH_KS_sign (&wdp.purpose, - &pub, - &sig); + if (GNUNET_OK != + TEH_KS_sign (&wdp.purpose, + &pub, + &sig)) + { + json_decref (deposits); + return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_EXCHANGE_BAD_CONFIGURATION, + "no keys"); + } + return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}", -- cgit v1.2.3