diff --git a/ChangeLog b/ChangeLog index c7ee8017f..24d9badcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,2 +1,7 @@ +Tue Jun 7 15:13:46 CEST 2016 + Adding public key of the exchange that was used to sign replies + to applicable callbacks of libtalerexchange. (This will eventually + be needed by the merchant's backend.) -CG + Wed Jun 1 17:27:36 CEST 2016 Releasing taler-exchange 0.0.0. -CG diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 7e19d8318..53c49df80 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -222,12 +222,14 @@ fail (const char *msg) * @param cls closure with the interpreter state * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param exchange_pub public key used by the exchange for signing * @param obj the received JSON reply, should be kept as proof (and, in case of errors, * be forwarded to the customer) */ static void deposit_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *obj) { unsigned int coin_index = (unsigned int) (long) cls; diff --git a/src/exchange-lib/exchange_api_deposit.c b/src/exchange-lib/exchange_api_deposit.c index 4d13febf4..e65684acf 100644 --- a/src/exchange-lib/exchange_api_deposit.c +++ b/src/exchange-lib/exchange_api_deposit.c @@ -94,18 +94,20 @@ struct TALER_EXCHANGE_DepositHandle * * @param dh deposit handle * @param json json reply with the signature + * @param exchange_pub set to the exchange's public key * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_deposit_signature_ok (const struct TALER_EXCHANGE_DepositHandle *dh, - const json_t *json) + const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; + const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("pub", &exchange_pub), + GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub), GNUNET_JSON_spec_end() }; @@ -120,7 +122,7 @@ verify_deposit_signature_ok (const struct TALER_EXCHANGE_DepositHandle *dh, key_state = TALER_EXCHANGE_get_keys (dh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -129,7 +131,7 @@ verify_deposit_signature_ok (const struct TALER_EXCHANGE_DepositHandle *dh, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT, &dh->depconf.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -200,6 +202,8 @@ handle_deposit_finished (void *cls, const json_t *json) { struct TALER_EXCHANGE_DepositHandle *dh = cls; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangePublicKeyP *ep = NULL; dh->job = NULL; switch (response_code) @@ -209,11 +213,16 @@ handle_deposit_finished (void *cls, case MHD_HTTP_OK: if (GNUNET_OK != verify_deposit_signature_ok (dh, - json)) + json, + &exchange_pub)) { GNUNET_break_op (0); response_code = 0; } + else + { + ep = &exchange_pub; + } break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy @@ -253,6 +262,7 @@ handle_deposit_finished (void *cls, } dh->cb (dh->cb_cls, response_code, + ep, json); TALER_EXCHANGE_deposit_cancel (dh); } diff --git a/src/exchange-lib/exchange_api_deposit_wtid.c b/src/exchange-lib/exchange_api_deposit_wtid.c index 073ce2b35..66b91413c 100644 --- a/src/exchange-lib/exchange_api_deposit_wtid.c +++ b/src/exchange-lib/exchange_api_deposit_wtid.c @@ -84,18 +84,19 @@ struct TALER_EXCHANGE_DepositWtidHandle * * @param dwh deposit wtid handle * @param json json reply with the signature + * @param[out] exchange_pub set to the exchange's public key * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_deposit_wtid_signature_ok (const struct TALER_EXCHANGE_DepositWtidHandle *dwh, - const json_t *json) + const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), GNUNET_JSON_spec_end() }; @@ -110,7 +111,7 @@ verify_deposit_wtid_signature_ok (const struct TALER_EXCHANGE_DepositWtidHandle key_state = TALER_EXCHANGE_get_keys (dwh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -119,7 +120,7 @@ verify_deposit_wtid_signature_ok (const struct TALER_EXCHANGE_DepositWtidHandle GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE, &dwh->depconf.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -146,6 +147,8 @@ handle_deposit_wtid_finished (void *cls, struct GNUNET_TIME_Absolute execution_time = GNUNET_TIME_UNIT_FOREVER_ABS; const struct TALER_Amount *coin_contribution = NULL; struct TALER_Amount coin_contribution_s; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangePublicKeyP *ep = NULL; dwh->job = NULL; switch (response_code) @@ -177,11 +180,16 @@ handle_deposit_wtid_finished (void *cls, coin_contribution = &coin_contribution_s; if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, - json)) + json, + &exchange_pub)) { GNUNET_break_op (0); response_code = 0; } + else + { + ep = &exchange_pub; + } } break; case MHD_HTTP_ACCEPTED: @@ -231,6 +239,7 @@ handle_deposit_wtid_finished (void *cls, } dwh->cb (dwh->cb_cls, response_code, + ep, json, wtid, execution_time, diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c index 7e207d795..b86e58362 100644 --- a/src/exchange-lib/exchange_api_refresh.c +++ b/src/exchange-lib/exchange_api_refresh.c @@ -951,20 +951,21 @@ struct TALER_EXCHANGE_RefreshMeltHandle * * @param rmh melt handle * @param json json reply with the signature + * @param[out] exchange_pub public key of the exchange used for the signature * @param[out] noreveal_index set to the noreveal index selected by the exchange * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh, const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub, uint16_t *noreveal_index) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub), GNUNET_JSON_spec_uint16 ("noreveal_index", noreveal_index), GNUNET_JSON_spec_end() }; @@ -983,7 +984,7 @@ verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh, key_state = TALER_EXCHANGE_get_keys (rmh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -1006,7 +1007,7 @@ verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT, &confirm.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -1126,6 +1127,7 @@ handle_refresh_melt_finished (void *cls, { struct TALER_EXCHANGE_RefreshMeltHandle *rmh = cls; uint16_t noreveal_index = TALER_CNC_KAPPA; /* invalid value */ + struct TALER_ExchangePublicKeyP exchange_pub; rmh->job = NULL; switch (response_code) @@ -1136,6 +1138,7 @@ handle_refresh_melt_finished (void *cls, if (GNUNET_OK != verify_refresh_melt_signature_ok (rmh, json, + &exchange_pub, &noreveal_index)) { GNUNET_break_op (0); @@ -1146,6 +1149,7 @@ handle_refresh_melt_finished (void *cls, rmh->melt_cb (rmh->melt_cb_cls, response_code, noreveal_index, + (0 == response_code) ? NULL : &exchange_pub, json); rmh->melt_cb = NULL; } @@ -1190,6 +1194,7 @@ handle_refresh_melt_finished (void *cls, rmh->melt_cb (rmh->melt_cb_cls, response_code, UINT16_MAX, + NULL, json); TALER_EXCHANGE_refresh_melt_cancel (rmh); } @@ -1731,7 +1736,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *ctx; struct MeltData *md; unsigned int j; - + GNUNET_assert (GNUNET_YES == MAH_handle_is_ready (exchange)); md = deserialize_melt_data (refresh_data, diff --git a/src/exchange-lib/exchange_api_refund.c b/src/exchange-lib/exchange_api_refund.c index d622ddc75..fff03acf9 100644 --- a/src/exchange-lib/exchange_api_refund.c +++ b/src/exchange-lib/exchange_api_refund.c @@ -83,18 +83,19 @@ struct TALER_EXCHANGE_RefundHandle * * @param rh refund handle * @param json json reply with the signature + * @param[out] exchange_pub set to the exchange's public key * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ static int verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, - const json_t *json) + const json_t *json, + struct TALER_ExchangePublicKeyP *exchange_pub) { struct TALER_ExchangeSignatureP exchange_sig; - struct TALER_ExchangePublicKeyP exchange_pub; const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("sig", &exchange_sig), - GNUNET_JSON_spec_fixed_auto ("pub", &exchange_pub), + GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub), GNUNET_JSON_spec_end() }; @@ -109,7 +110,7 @@ verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, key_state = TALER_EXCHANGE_get_keys (rh->exchange); if (GNUNET_OK != TALER_EXCHANGE_test_signing_key (key_state, - &exchange_pub)) + exchange_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -118,7 +119,7 @@ verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND, &rh->depconf.purpose, &exchange_sig.eddsa_signature, - &exchange_pub.eddsa_pub)) + &exchange_pub->eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -141,6 +142,8 @@ handle_refund_finished (void *cls, const json_t *json) { struct TALER_EXCHANGE_RefundHandle *rh = cls; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangePublicKeyP *ep = NULL; rh->job = NULL; switch (response_code) @@ -150,11 +153,16 @@ handle_refund_finished (void *cls, case MHD_HTTP_OK: if (GNUNET_OK != verify_refund_signature_ok (rh, - json)) + json, + &exchange_pub)) { GNUNET_break_op (0); response_code = 0; } + else + { + ep = &exchange_pub; + } break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the exchange is buggy @@ -188,6 +196,7 @@ handle_refund_finished (void *cls, } rh->cb (rh->cb_cls, response_code, + ep, json); TALER_EXCHANGE_refund_cancel (rh); } diff --git a/src/exchange-lib/exchange_api_wire_deposits.c b/src/exchange-lib/exchange_api_wire_deposits.c index 0601f9b4a..91e2aef7b 100644 --- a/src/exchange-lib/exchange_api_wire_deposits.c +++ b/src/exchange-lib/exchange_api_wire_deposits.c @@ -186,6 +186,7 @@ handle_wire_deposits_finished (void *cls, break; wdh->cb (wdh->cb_cls, response_code, + &exchange_pub, json, &h_wire, &total_amount, @@ -224,6 +225,7 @@ handle_wire_deposits_finished (void *cls, } wdh->cb (wdh->cb_cls, response_code, + NULL, json, NULL, NULL, 0, NULL); TALER_EXCHANGE_wire_deposits_cancel (wdh); diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 75a9cfbd9..83fb0eb32 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -1028,12 +1028,14 @@ reserve_withdraw_cb (void *cls, * @param cls closure with the interpreter state * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param exchange_pub public key the exchange used for signing * @param obj the received JSON reply, should be kept as proof (and, in case of errors, * be forwarded to the customer) */ static void deposit_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *obj) { struct InterpreterState *is = cls; @@ -1062,12 +1064,14 @@ deposit_cb (void *cls, * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param noreveal_index choice by the exchange in the cut-and-choose protocol, * UINT16_MAX on error + * @param exchange_pub public key the exchange used for signing * @param full_response full response from the exchange (for logging, in case of errors) */ static void melt_cb (void *cls, unsigned int http_status, uint16_t noreveal_index, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *full_response) { struct InterpreterState *is = cls; @@ -1388,6 +1392,7 @@ wire_cb (void *cls, * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param exchange_pub public key the exchange used for signing * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid extracted wire transfer identifier, or NULL if the exchange could @@ -1400,6 +1405,7 @@ wire_cb (void *cls, static void wire_deposits_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *json, const struct GNUNET_HashCode *h_wire, const struct TALER_Amount *total_amount, @@ -1515,6 +1521,7 @@ wire_deposits_cb (void *cls, * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param exchange_pub public key the exchange used for signing * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not @@ -1527,6 +1534,7 @@ wire_deposits_cb (void *cls, static void deposit_wtid_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *json, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute execution_time, @@ -1580,12 +1588,14 @@ deposit_wtid_cb (void *cls, * @param cls closure * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param exchange_pub public key the exchange used for signing @a obj * @param obj the received JSON reply, should be kept as proof (and, in particular, * be forwarded to the customer) */ static void refund_cb (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *exchange_pub, const json_t *obj) { struct InterpreterState *is = cls; diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index e65a9faee..5f79b9bee 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -416,12 +416,14 @@ struct TALER_EXCHANGE_DepositHandle; * @param cls closure * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param sign_key exchange key used to sign @a obj, or NULL * @param obj the received JSON reply, should be kept as proof (and, in case of errors, * be forwarded to the customer) */ typedef void (*TALER_EXCHANGE_DepositResultCallback) (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *obj); @@ -502,12 +504,14 @@ struct TALER_EXCHANGE_RefundHandle; * @param cls closure * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit; * 0 if the exchange's reply is bogus (fails to follow the protocol) + * @param sign_key exchange key used to sign @a obj, or NULL * @param obj the received JSON reply, should be kept as proof (and, in particular, * be forwarded to the customer) */ typedef void (*TALER_EXCHANGE_RefundResultCallback) (void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *obj); @@ -833,12 +837,14 @@ struct TALER_EXCHANGE_RefreshMeltHandle; * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param noreveal_index choice by the exchange in the cut-and-choose protocol, * UINT16_MAX on error + * @param sign_key exchange key used to sign @a full_response, or NULL * @param full_response full response from the exchange (for logging, in case of errors) */ typedef void (*TALER_EXCHANGE_RefreshMeltCallback) (void *cls, unsigned int http_status, uint16_t noreveal_index, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *full_response); @@ -1135,6 +1141,7 @@ struct TALER_WireDepositDetails * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param sign_key exchange key used to sign @a json, or NULL * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid extracted wire transfer identifier, or NULL if the exchange could @@ -1147,6 +1154,7 @@ struct TALER_WireDepositDetails typedef void (*TALER_EXCHANGE_WireDepositsCallback)(void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *json, const struct GNUNET_HashCode *h_wire, const struct TALER_Amount *total_amount, @@ -1195,6 +1203,7 @@ struct TALER_EXCHANGE_DepositWtidHandle; * * @param cls closure * @param http_status HTTP status code we got, 0 on exchange protocol violation + * @param sign_key exchange key used to sign @a json, or NULL * @param json original json reply (may include signatures, those have then been * validated already) * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not @@ -1205,6 +1214,7 @@ struct TALER_EXCHANGE_DepositWtidHandle; typedef void (*TALER_EXCHANGE_DepositWtidCallback)(void *cls, unsigned int http_status, + const struct TALER_ExchangePublicKeyP *sign_key, const json_t *json, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute execution_time,