aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-11-09 20:35:01 +0100
committerChristian Grothoff <christian@grothoff.org>2024-11-09 20:35:01 +0100
commit2d01575f5810be410e49564288268671945eb625 (patch)
tree0512ed31d7e71e889c0ec86f8343010cb7523fb5
parente48768c3c65437c11bed0b56541d60acb3b0ea14 (diff)
implement protocol v22, fixes #9185
-rw-r--r--src/exchange/taler-exchange-httpd_batch-deposit.c21
-rw-r--r--src/exchange/taler-exchange-httpd_config.h2
-rw-r--r--src/exchangedb/0005-legitimization_processes.sql2
-rw-r--r--src/exchangedb/0007-batch_deposits.sql21
-rw-r--r--src/exchangedb/exchange-0007.sql.in1
-rw-r--r--src/exchangedb/exchange_do_deposit.sql3
-rw-r--r--src/exchangedb/pg_do_deposit.c6
-rw-r--r--src/include/taler_crypto_lib.h23
-rw-r--r--src/include/taler_exchange_service.h6
-rw-r--r--src/include/taler_exchangedb_plugin.h6
-rw-r--r--src/lib/Makefile.am2
-rw-r--r--src/lib/exchange_api_batch_deposit.c6
-rw-r--r--src/lib/exchange_api_handle.c4
-rw-r--r--src/util/merchant_signatures.c59
14 files changed, 124 insertions, 38 deletions
diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c
index e46d2124a..07651a470 100644
--- a/src/exchange/taler-exchange-httpd_batch-deposit.c
+++ b/src/exchange/taler-exchange-httpd_batch-deposit.c
@@ -904,6 +904,10 @@ bdc_phase_parse (struct BatchDepositContext *bdc,
&bd->wire_salt),
GNUNET_JSON_spec_fixed_auto ("merchant_pub",
&bd->merchant_pub),
+ GNUNET_JSON_spec_mark_optional ( /* since v22, we are compatible */
+ GNUNET_JSON_spec_fixed_auto ("merchant_sig",
+ &bd->merchant_sig),
+ NULL),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
&bd->h_contract_terms),
GNUNET_JSON_spec_mark_optional (
@@ -950,6 +954,23 @@ bdc_phase_parse (struct BatchDepositContext *bdc,
return;
}
}
+ if ( (! GNUNET_is_zero (&bd->merchant_sig)) &&
+ (GNUNET_OK !=
+ TALER_merchant_contract_verify (
+ &bd->h_contract_terms,
+ &bd->merchant_pub,
+ &bd->merchant_sig)) )
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ finish_loop (bdc,
+ TALER_MHD_reply_with_error (
+ bdc->rc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "merchant_sig"));
+ return;
+ }
bdc->policy_json
= json_incref ((json_t *) policy_json);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
diff --git a/src/exchange/taler-exchange-httpd_config.h b/src/exchange/taler-exchange-httpd_config.h
index 486a8b83b..e033ac29c 100644
--- a/src/exchange/taler-exchange-httpd_config.h
+++ b/src/exchange/taler-exchange-httpd_config.h
@@ -41,7 +41,7 @@
*
* Returned via both /config and /keys endpoints.
*/
-#define EXCHANGE_PROTOCOL_VERSION "21:0:4"
+#define EXCHANGE_PROTOCOL_VERSION "22:0:5"
/**
diff --git a/src/exchangedb/0005-legitimization_processes.sql b/src/exchangedb/0005-legitimization_processes.sql
index c1bffca7d..d8222bf6c 100644
--- a/src/exchangedb/0005-legitimization_processes.sql
+++ b/src/exchangedb/0005-legitimization_processes.sql
@@ -22,7 +22,7 @@ LANGUAGE plpgsql
AS $$
BEGIN
PERFORM create_partitioned_table(
- 'ALTER TABLE legitimization_processes'
+ 'ALTER TABLE %I'
' ADD COLUMN legitimization_measure_serial_id BIGINT'
',ADD COLUMN measure_index INT4 DEFAULT(0)'
',ADD COLUMN error_code INT4 DEFAULT (0)'
diff --git a/src/exchangedb/0007-batch_deposits.sql b/src/exchangedb/0007-batch_deposits.sql
index 65055f6ad..44c832484 100644
--- a/src/exchangedb/0007-batch_deposits.sql
+++ b/src/exchangedb/0007-batch_deposits.sql
@@ -14,25 +14,28 @@
-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
--
-CREATE FUNCTION alter_table_batch_deposits7()
+CREATE FUNCTION alter_table_batch_deposits7(
+ IN partition_suffix TEXT DEFAULT NULL
+)
RETURNS VOID
LANGUAGE plpgsql
AS $$
-DECLARE
- table_name TEXT DEFAULT 'batch_deposits';
BEGIN
- EXECUTE FORMAT (
- 'ALTER TABLE ' || table_name ||
+ PERFORM create_partitioned_table(
+ 'ALTER TABLE %I'
' ADD COLUMN merchant_sig BYTEA CHECK(LENGTH(merchant_sig)=64)'
' DEFAULT NULL'
- ';'
+ ';',
+ 'batch_deposits'
+ ,''
+ ,partition_suffix
);
PERFORM comment_partitioned_column(
- 'signature by the merchant over the contract terms'
- ,'batch_deposits'
+ 'signature by the merchant over the contract terms, of purpuse TALER_SIGNATURE_MERCHANT_CONTRACT'
,'merchant_sig'
- ,NULL
+ ,'batch_deposits'
+ ,partition_suffix
);
END $$;
diff --git a/src/exchangedb/exchange-0007.sql.in b/src/exchangedb/exchange-0007.sql.in
index 6d634e22c..9a03e2fa1 100644
--- a/src/exchangedb/exchange-0007.sql.in
+++ b/src/exchangedb/exchange-0007.sql.in
@@ -21,6 +21,7 @@ SET search_path TO exchange;
#include "0007-wire_targets.sql"
#include "0007-legitimization_outcomes.sql"
+#include "0007-batch_deposits.sql"
COMMIT;
diff --git a/src/exchangedb/exchange_do_deposit.sql b/src/exchangedb/exchange_do_deposit.sql
index ef1d94919..8ada2c497 100644
--- a/src/exchangedb/exchange_do_deposit.sql
+++ b/src/exchangedb/exchange_do_deposit.sql
@@ -19,6 +19,7 @@ CREATE FUNCTION exchange_do_deposit(
-- For batch_deposits
IN in_shard INT8,
IN in_merchant_pub BYTEA,
+ IN in_merchant_sig BYTEA,
IN in_wallet_timestamp INT8,
IN in_exchange_timestamp INT8,
IN in_refund_deadline INT8,
@@ -88,6 +89,7 @@ END IF;
INSERT INTO batch_deposits
(shard
,merchant_pub
+ ,merchant_sig
,wallet_timestamp
,exchange_timestamp
,refund_deadline
@@ -102,6 +104,7 @@ INSERT INTO batch_deposits
VALUES
(in_shard
,in_merchant_pub
+ ,in_merchant_sig
,in_wallet_timestamp
,in_exchange_timestamp
,in_refund_deadline
diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c
index ed689696a..da8ddf793 100644
--- a/src/exchangedb/pg_do_deposit.c
+++ b/src/exchangedb/pg_do_deposit.c
@@ -46,6 +46,9 @@ TEH_PG_do_deposit (
/* data for batch_deposits */
GNUNET_PQ_query_param_uint64 (&deposit_shard),
GNUNET_PQ_query_param_auto_from_type (&bd->merchant_pub),
+ GNUNET_is_zero (&bd->merchant_sig)
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_auto_from_type (&bd->merchant_sig),
GNUNET_PQ_query_param_timestamp (&bd->wallet_timestamp),
GNUNET_PQ_query_param_timestamp (exchange_timestamp),
GNUNET_PQ_query_param_timestamp (&bd->refund_deadline),
@@ -113,7 +116,8 @@ TEH_PG_do_deposit (
",out_insufficient_balance_coin_index AS insufficient_balance_coin_index"
",out_conflict AS conflicted"
" FROM exchange_do_deposit"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17);");
+ " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18);")
+ ;
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"call_deposit",
params,
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 6edc15d5c..52dbb75d1 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -5995,14 +5995,29 @@ TALER_merchant_pay_verify (
* Sign contract sent by the merchant to the wallet.
*
* @param h_contract_terms hash of the contract terms
- * @param merch_priv private key to sign with
- * @param[out] merch_sig where to write the signature
+ * @param merchant_priv private key to sign with
+ * @param[out] merchant_sig where to write the signature
*/
void
TALER_merchant_contract_sign (
const struct TALER_PrivateContractHashP *h_contract_terms,
- const struct TALER_MerchantPrivateKeyP *merch_priv,
- struct GNUNET_CRYPTO_EddsaSignature *merch_sig);
+ const struct TALER_MerchantPrivateKeyP *merchant_priv,
+ struct TALER_MerchantSignatureP *merchant_sig);
+
+
+/**
+ * Verify contract signature sent by the merchant to the wallet.
+ *
+ * @param h_contract_terms hash of the contract terms
+ * @param merchant_pub public key of the merchant
+ * @param merchant_sig signature to check
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_merchant_contract_verify (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ struct TALER_MerchantSignatureP *merchant_sig);
/* **************** /management/extensions offline signing **************** */
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index f2b62c9d6..c561e0e8f 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1246,6 +1246,12 @@ struct TALER_EXCHANGE_DepositContractDetail
struct TALER_MerchantPublicKeyP merchant_pub;
/**
+ * The signature of the merchant (used to show that the merchant indeed
+ * agree to the deposit).
+ */
+ struct TALER_MerchantSignatureP merchant_sig;
+
+ /**
* Salt used to hash the @e merchant_payto_uri.
*/
struct TALER_WireSaltP wire_salt;
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index c633675d8..66e0c4587 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1780,6 +1780,12 @@ struct TALER_EXCHANGEDB_BatchDeposit
struct TALER_MerchantPublicKeyP merchant_pub;
/**
+ * Signature of the merchant over the contract, of purpose
+ * #TALER_SIGNATURE_MERCHANT_CONTRACT.
+ */
+ struct TALER_MerchantSignatureP merchant_sig;
+
+ /**
* Hash over the proposal data between merchant and customer
* (remains unknown to the Exchange).
*/
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 88d00765f..cd7e5aed5 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -18,7 +18,7 @@ lib_LTLIBRARIES = \
libtalerexchange.la
libtalerexchange_la_LDFLAGS = \
- -version-info 12:0:0 \
+ -version-info 13:0:0 \
-no-undefined
libtalerexchange_la_SOURCES = \
exchange_api_add_aml_decision.c \
diff --git a/src/lib/exchange_api_batch_deposit.c b/src/lib/exchange_api_batch_deposit.c
index 26f00c7a7..23bef742f 100644
--- a/src/lib/exchange_api_batch_deposit.c
+++ b/src/lib/exchange_api_batch_deposit.c
@@ -668,6 +668,10 @@ TALER_EXCHANGE_batch_deposit (
json_decref (deposits);
return NULL;
}
+ if (! GNUNET_is_zero (&dcd->merchant_sig))
+ {
+ /* FIXME #9185: check merchant_sig!? */
+ }
if (GNUNET_is_zero (&cdd->h_age_commitment))
h_age_commitmentp = NULL;
else
@@ -730,6 +734,8 @@ TALER_EXCHANGE_batch_deposit (
dcd->wallet_timestamp),
GNUNET_JSON_pack_data_auto ("merchant_pub",
&dcd->merchant_pub),
+ GNUNET_JSON_pack_data_auto ("merchant_sig",
+ &dcd->merchant_sig),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_timestamp ("refund_deadline",
dcd->refund_deadline)),
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 9acb7c2b0..acb40151e 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -40,12 +40,12 @@
* Which version of the Taler protocol is implemented
* by this library? Used to determine compatibility.
*/
-#define EXCHANGE_PROTOCOL_CURRENT 21
+#define EXCHANGE_PROTOCOL_CURRENT 22
/**
* How many versions are we backwards compatible with?
*/
-#define EXCHANGE_PROTOCOL_AGE 4
+#define EXCHANGE_PROTOCOL_AGE 5
/**
* Set to 1 for extra debug logging.
diff --git a/src/util/merchant_signatures.c b/src/util/merchant_signatures.c
index 56d93ab87..32948578b 100644
--- a/src/util/merchant_signatures.c
+++ b/src/util/merchant_signatures.c
@@ -95,11 +95,11 @@ TALER_merchant_deposit_verify (
.h_wire = *h_wire
};
- return
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION,
- &tps,
- &merchant_sig->eddsa_sig,
- &merchant->eddsa_pub);
+ return GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION,
+ &tps,
+ &merchant_sig->eddsa_sig,
+ &merchant->eddsa_pub);
}
@@ -183,11 +183,11 @@ TALER_merchant_refund_verify (
TALER_amount_hton (&rr.refund_amount,
amount);
- return
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
- &rr,
- &merchant_sig->eddsa_sig,
- &merchant_pub->eddsa_pub);
+ return GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_MERCHANT_REFUND,
+ &rr,
+ &merchant_sig->eddsa_sig,
+ &merchant_pub->eddsa_pub);
}
@@ -303,11 +303,11 @@ TALER_merchant_pay_verify (
.h_contract_terms = *h_contract_terms
};
- return
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_PAYMENT_OK,
- &pr,
- &merchant_sig->eddsa_sig,
- &merchant_pub->eddsa_pub);
+ return GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_MERCHANT_PAYMENT_OK,
+ &pr,
+ &merchant_sig->eddsa_sig,
+ &merchant_pub->eddsa_pub);
}
@@ -329,11 +329,12 @@ struct TALER_ProposalDataPS
struct TALER_PrivateContractHashP hash;
};
+
void
TALER_merchant_contract_sign (
const struct TALER_PrivateContractHashP *h_contract_terms,
- const struct TALER_MerchantPrivateKeyP *merch_priv,
- struct GNUNET_CRYPTO_EddsaSignature *merch_sig)
+ const struct TALER_MerchantPrivateKeyP *merchant_priv,
+ struct TALER_MerchantSignatureP *merchant_sig)
{
struct TALER_ProposalDataPS pdps = {
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT),
@@ -341,9 +342,29 @@ TALER_merchant_contract_sign (
.hash = *h_contract_terms
};
- GNUNET_CRYPTO_eddsa_sign (&merch_priv->eddsa_priv,
+ GNUNET_CRYPTO_eddsa_sign (&merchant_priv->eddsa_priv,
&pdps,
- merch_sig);
+ &merchant_sig->eddsa_sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_merchant_contract_verify (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ struct TALER_MerchantSignatureP *merchant_sig)
+{
+ struct TALER_ProposalDataPS pdps = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT),
+ .purpose.size = htonl (sizeof (pdps)),
+ .hash = *h_contract_terms
+ };
+
+ return GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_MERCHANT_CONTRACT,
+ &pdps,
+ &merchant_sig->eddsa_sig,
+ &merchant_pub->eddsa_pub);
}