From 4b5efa4e8160634fc6cefce8dcedb38d71f76cc6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 4 Apr 2017 16:27:27 +0200 Subject: towards supporting #3887 in the auditor --- src/auditor/taler-auditor.c | 23 ++++++-- src/auditordb/plugin_auditordb_postgres.c | 2 +- src/exchange/taler-exchange-httpd_db.c | 2 +- src/exchange/taler-exchange-httpd_responses.c | 4 +- src/exchangedb/plugin_exchangedb_common.c | 7 ++- src/exchangedb/plugin_exchangedb_postgres.c | 77 ++++++++++++++++++--------- src/exchangedb/test_exchangedb.c | 12 +++-- src/include/taler_exchangedb_plugin.h | 20 +++---- 8 files changed, 95 insertions(+), 52 deletions(-) diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c index b884e64bc..e89812a2a 100644 --- a/src/auditor/taler-auditor.c +++ b/src/auditor/taler-auditor.c @@ -808,9 +808,8 @@ handle_reserve_out (void *cls, * @param timestamp when did we receive the payback request * @param amount how much should be added back to the reserve * @param reserve_pub public key of the reserve - * @param coin_pub public key of the coin + * @param coin public information about the coin * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK - * @param h_denom_pub hash of the denomination key of the coin * @param coin_blind blinding factor used to blind the coin * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ @@ -820,9 +819,8 @@ handle_payback_by_reserve (void *cls, struct GNUNET_TIME_Absolute timestamp, const struct TALER_Amount *amount, const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinSpendSignatureP *coin_sig, - const struct GNUNET_HashCode *h_denom_pub, const struct TALER_DenominationBlindingKeyP *coin_blind) { struct ReserveContext *rc = cls; @@ -834,6 +832,9 @@ handle_payback_by_reserve (void *cls, GNUNET_assert (rowid >= pp.last_reserve_payback_serial_id); pp.last_reserve_payback_serial_id = rowid + 1; + /* TODO: check that coin signature on payback request is valid + and/or that the coin was eligible for payback! #3887!*/ + GNUNET_CRYPTO_hash (reserve_pub, sizeof (*reserve_pub), &key); @@ -1529,6 +1530,17 @@ check_transaction_history (const struct TALER_CoinSpendPublicKeyP *coin_pub, } } break; + case TALER_EXCHANGEDB_TT_PAYBACK: + amount_with_fee = &tl->details.payback->value; + if (GNUNET_OK != + TALER_amount_add (&expenditures, + &expenditures, + amount_with_fee)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + break; } /* Check that the fees given in the transaction list and in dki match */ @@ -1656,6 +1668,9 @@ wire_transfer_information_cb (void *cls, case TALER_EXCHANGEDB_TT_REFUND: coin = &tl->details.refund->coin; break; + case TALER_EXCHANGEDB_TT_PAYBACK: + coin = &tl->details.payback->coin; + break; } GNUNET_assert (NULL != coin); /* hard check that switch worked */ if (GNUNET_OK != diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index b68708f0c..f144746ac 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -1424,7 +1424,7 @@ postgres_get_auditor_progress (void *cls, GNUNET_PQ_result_spec_uint64 ("last_reserve_payback_serial_id", &pp->last_reserve_payback_serial_id), GNUNET_PQ_result_spec_uint64 ("last_reserve_close_serial_id", - &pp->last_reserve_out_serial_id), + &pp->last_reserve_close_serial_id), GNUNET_PQ_result_spec_uint64 ("last_withdraw_serial_id", &pp->last_withdraw_serial_id), GNUNET_PQ_result_spec_uint64 ("last_deposit_serial_id", diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 11f8d31d3..9e345e806 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -2413,7 +2413,7 @@ TEH_DB_execute_payback (struct MHD_Connection *connection, ret = TEH_plugin->insert_payback_request (TEH_plugin->cls, session, &reserve_pub, - &coin->coin_pub, + coin, coin_sig, coin_blind, &amount, diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 29ba9e02f..111337c7e 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -565,7 +565,7 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl) pc.timestamp = GNUNET_TIME_absolute_hton (payback->timestamp); TALER_amount_hton (&pc.payback_amount, &payback->value); - pc.coin_pub = payback->coin_pub; + pc.coin_pub = payback->coin.coin_pub; pc.reserve_pub = payback->reserve_pub; TEH_KS_sign (&pc.purpose, &epub, @@ -737,7 +737,7 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh, pc.timestamp = GNUNET_TIME_absolute_hton (payback->timestamp); TALER_amount_hton (&pc.payback_amount, &payback->value); - pc.coin_pub = payback->coin_pub; + pc.coin_pub = payback->coin.coin_pub; pc.reserve_pub = payback->reserve_pub; TEH_KS_sign (&pc.purpose, &pub, diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c index 2fb480415..b97aa08c2 100644 --- a/src/exchangedb/plugin_exchangedb_common.c +++ b/src/exchangedb/plugin_exchangedb_common.c @@ -56,7 +56,8 @@ common_free_reserve_history (void *cls, break; case TALER_EXCHANGEDB_RO_PAYBACK_COIN: payback = rh->details.payback; - GNUNET_CRYPTO_rsa_public_key_free (payback->denom_pub.rsa_public_key); + GNUNET_CRYPTO_rsa_signature_free (payback->coin.denom_sig.rsa_signature); + GNUNET_CRYPTO_rsa_public_key_free (payback->coin.denom_pub.rsa_public_key); GNUNET_free (payback); break; } @@ -133,6 +134,10 @@ common_free_coin_transaction_list (void *cls, GNUNET_free (list->details.refund); break; case TALER_EXCHANGEDB_TT_PAYBACK: + if (NULL != list->details.payback->coin.denom_pub.rsa_public_key) + GNUNET_CRYPTO_rsa_public_key_free (list->details.payback->coin.denom_pub.rsa_public_key); + if (NULL != list->details.payback->coin.denom_sig.rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (list->details.payback->coin.denom_sig.rsa_signature); GNUNET_free (list->details.payback); break; } diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 498b84864..d2a2bba66 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -517,7 +517,7 @@ postgres_create_tables (void *cls) SQLEXEC("CREATE TABLE IF NOT EXISTS payback " "(payback_uuid BIGSERIAL" ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE" - ",coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)" + ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE" ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)" ",amount_val INT8 NOT NULL" @@ -1429,12 +1429,13 @@ postgres_prepare (PGconn *db_conn) ",coin_sig" ",coin_blind" ",h_blind_ev" - ",denom.denom_pub" + ",coins.denom_pub" + ",coins.denom_sig" ",amount_val" ",amount_frac" ",amount_curr" " FROM payback" - " JOIN reserves_out denom USING (reserve_pub,h_blind_ev)" + " JOIN known_coins coins USING (coin_pub)" " WHERE payback_uuid>=$1" " ORDER BY payback_uuid ASC", 1, NULL); @@ -1450,10 +1451,10 @@ postgres_prepare (PGconn *db_conn) ",amount_frac" ",amount_curr" ",timestamp" - ",denom.denom_pub" - ",denom.denom_sig" + ",coins.denom_pub" + ",coins.denom_sig" " FROM payback" - " JOIN reserves_out denom USING (reserve_pub,h_blind_ev)" + " JOIN known_coins coins USING (coin_pub)" " WHERE payback.reserve_pub=$1", 1, NULL); @@ -1468,10 +1469,10 @@ postgres_prepare (PGconn *db_conn) ",amount_frac" ",amount_curr" ",timestamp" - ",denom.denom_pub" - ",denom.denom_sig" + ",coins.denom_pub" + ",coins.denom_sig" " FROM payback" - " JOIN reserves_out denom USING (reserve_pub,h_blind_ev)" + " JOIN known_coins coins USING (coin_pub)" " WHERE payback.coin_pub=$1", 1, NULL); @@ -2413,7 +2414,7 @@ postgres_get_reserve_history (void *cls, TALER_PQ_result_spec_amount ("amount", &payback->value), GNUNET_PQ_result_spec_auto_from_type ("coin_pub", - &payback->coin_pub), + &payback->coin.coin_pub), GNUNET_PQ_result_spec_auto_from_type ("coin_blind", &payback->coin_blind), GNUNET_PQ_result_spec_auto_from_type ("coin_sig", @@ -2421,7 +2422,9 @@ postgres_get_reserve_history (void *cls, GNUNET_PQ_result_spec_absolute_time ("timestamp", &payback->timestamp), GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &payback->denom_pub.rsa_public_key), + &payback->coin.denom_pub.rsa_public_key), + GNUNET_PQ_result_spec_rsa_signature ("denom_sig", + &payback->coin.denom_sig.rsa_signature), GNUNET_PQ_result_spec_end }; if (GNUNET_OK != @@ -4226,7 +4229,9 @@ postgres_get_coin_transactions (void *cls, GNUNET_PQ_result_spec_absolute_time ("timestamp", &payback->timestamp), GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &payback->denom_pub.rsa_public_key), + &payback->coin.denom_pub.rsa_public_key), + GNUNET_PQ_result_spec_rsa_signature ("denom_sig", + &payback->coin.denom_sig.rsa_signature), GNUNET_PQ_result_spec_end }; if (GNUNET_OK != @@ -4239,7 +4244,7 @@ postgres_get_coin_transactions (void *cls, PQclear (result); goto cleanup; } - payback->coin_pub = *coin_pub; + payback->coin.coin_pub = *coin_pub; } tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList); tl->next = head; @@ -4912,6 +4917,7 @@ postgres_start_deferred_wire_out (void *cls, PQclear (result); return GNUNET_SYSERR; } + PQclear (result); result = PQexec (session->conn, "SET CONSTRAINTS wire_out_ref DEFERRED"); if (PGRES_COMMAND_OK != @@ -5702,14 +5708,12 @@ postgres_select_payback_above_serial_id (void *cls, { uint64_t rowid; struct TALER_ReservePublicKeyP reserve_pub; - struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinPublicInfo coin; struct TALER_CoinSpendSignatureP coin_sig; struct TALER_DenominationBlindingKeyP coin_blind; struct TALER_Amount amount; struct GNUNET_HashCode h_blind_ev; struct GNUNET_TIME_Absolute timestamp; - struct TALER_DenominationPublicKey denom_pub; - struct GNUNET_HashCode h_denom_pub; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint64 ("payback_uuid", @@ -5719,7 +5723,7 @@ postgres_select_payback_above_serial_id (void *cls, GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", &reserve_pub), GNUNET_PQ_result_spec_auto_from_type ("coin_pub", - &coin_pub), + &coin.coin_pub), GNUNET_PQ_result_spec_auto_from_type ("coin_sig", &coin_sig), GNUNET_PQ_result_spec_auto_from_type ("coin_blind", @@ -5727,7 +5731,9 @@ postgres_select_payback_above_serial_id (void *cls, GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev", &h_blind_ev), GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", - &denom_pub.rsa_public_key), + &coin.denom_pub.rsa_public_key), + GNUNET_PQ_result_spec_rsa_signature ("denom_sig", + &coin.denom_sig.rsa_signature), TALER_PQ_result_spec_amount ("amount", &amount), GNUNET_PQ_result_spec_end @@ -5742,16 +5748,13 @@ postgres_select_payback_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key, - &h_denom_pub); ret = cb (cb_cls, rowid, timestamp, &amount, &reserve_pub, - &coin_pub, + &coin, &coin_sig, - &h_denom_pub, &coin_blind); GNUNET_PQ_cleanup_result (rs); if (GNUNET_OK != ret) @@ -5772,7 +5775,7 @@ postgres_select_payback_above_serial_id (void *cls, * @param cls closure * @param session database connection * @param reserve_pub public key of the reserve that is being refunded - * @param coin_pub public key of the coin + * @param coin information about the coin * @param coin_sig signature of the coin of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK * @param coin_blind blinding key of the coin * @param amount total amount to be paid back @@ -5786,7 +5789,7 @@ static int postgres_insert_payback_request (void *cls, struct TALER_EXCHANGEDB_Session *session, const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_DenominationBlindingKeyP *coin_blind, const struct TALER_Amount *amount, @@ -5798,7 +5801,7 @@ postgres_insert_payback_request (void *cls, struct TALER_EXCHANGEDB_Reserve reserve; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (reserve_pub), - GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub), GNUNET_PQ_query_param_auto_from_type (coin_sig), GNUNET_PQ_query_param_auto_from_type (coin_blind), TALER_PQ_query_param_amount (amount), @@ -5806,7 +5809,31 @@ postgres_insert_payback_request (void *cls, GNUNET_PQ_query_param_auto_from_type (h_blind_ev), GNUNET_PQ_query_param_end }; + int ret; + + /* check if the coin is already known */ + ret = get_known_coin (cls, + session, + &coin->coin_pub, + NULL); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_NO == ret) /* if not, insert it */ + { + if (GNUNET_SYSERR == + insert_known_coin (cls, + session, + coin)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + /* now store actual payback information */ result = GNUNET_PQ_exec_prepared (session->conn, "payback_insert", params); diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 49cc64316..5175ef4fb 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -1385,6 +1385,7 @@ run (void *cls) rh = NULL; wire = NULL; session = NULL; + deposit.coin.denom_sig.rsa_signature = NULL; ZR_BLK (&cbc); ZR_BLK (&cbc2); if (NULL == @@ -1513,12 +1514,15 @@ run (void *cls) RND_BLK (&coin_sig); RND_BLK (&coin_blind); + RND_BLK (&deposit.coin.coin_pub); + deposit.coin.denom_pub = dkp->pub; + deposit.coin.denom_sig = cbc.sig; deadline = GNUNET_TIME_absolute_get (); FAILIF (GNUNET_OK != plugin->insert_payback_request (plugin->cls, session, &reserve_pub, - &deposit.coin.coin_pub, + &deposit.coin, &coin_sig, &coin_blind, &value, @@ -1569,7 +1573,7 @@ run (void *cls) FAILIF (0 != memcmp (&payback->reserve_pub, &reserve_pub, sizeof (reserve_pub))); - FAILIF (0 != memcmp (&payback->coin_pub, + FAILIF (0 != memcmp (&payback->coin.coin_pub, &deposit.coin.coin_pub, sizeof (deposit.coin.coin_pub))); FAILIF (0 != TALER_amount_cmp (&payback->value, @@ -1717,7 +1721,7 @@ run (void *cls) plugin->insert_payback_request (plugin->cls, session, &reserve_pub, - &deposit.coin.coin_pub, + &deposit.coin, &coin_sig, &coin_blind, &value, @@ -1824,7 +1828,7 @@ run (void *cls) FAILIF (0 != memcmp (&payback->reserve_pub, &reserve_pub, sizeof (reserve_pub))); - FAILIF (0 != memcmp (&payback->coin_pub, + FAILIF (0 != memcmp (&payback->coin.coin_pub, &deposit.coin.coin_pub, sizeof (deposit.coin.coin_pub))); FAILIF (0 != TALER_amount_cmp (&payback->value, diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index f6d78aba9..c1a7f8f63 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -153,9 +153,9 @@ struct TALER_EXCHANGEDB_Payback { /** - * Public key of the coin that was paid back. + * Information about the coin that was paid back. */ - struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinPublicInfo coin; /** * Blinding factor supplied to prove to the exchange that @@ -184,12 +184,6 @@ struct TALER_EXCHANGEDB_Payback */ struct GNUNET_TIME_Absolute timestamp; - /** - * Public key representing the denomination of - * @e coin_pub. - */ - struct TALER_DenominationPublicKey denom_pub; - }; @@ -914,9 +908,8 @@ typedef int * @param timestamp when did we receive the payback request * @param amount how much should be added back to the reserve * @param reserve_pub public key of the reserve - * @param coin_pub public key of the coin + * @param coin public information about the coin * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK - * @param h_denom_pub hash of the denomination key of the coin * @param coin_blind blinding factor used to blind the coin * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ @@ -926,9 +919,8 @@ typedef int struct GNUNET_TIME_Absolute timestamp, const struct TALER_Amount *amount, const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinSpendSignatureP *coin_sig, - const struct GNUNET_HashCode *h_denom_pub, const struct TALER_DenominationBlindingKeyP *coin_blind); @@ -1979,7 +1971,7 @@ struct TALER_EXCHANGEDB_Plugin * @param cls closure * @param session database connection * @param reserve_pub public key of the reserve that is being refunded - * @param coin_pub public key of the coin + * @param coin public information about a coin * @param coin_sig signature of the coin of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK * @param coin_blind blinding key of the coin * @param h_blind_ev blinded envelope, as calculated by the exchange @@ -1994,7 +1986,7 @@ struct TALER_EXCHANGEDB_Plugin (*insert_payback_request)(void *cls, struct TALER_EXCHANGEDB_Session *session, const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_DenominationBlindingKeyP *coin_blind, const struct TALER_Amount *amount, -- cgit v1.2.3