v12: also do not sign over merchant_pub in REFUND signature, centralize logic
This commit is contained in:
parent
1c34489905
commit
84c9adf5a6
@ -1794,41 +1794,30 @@ refund_cb (void *cls,
|
||||
}
|
||||
|
||||
/* verify refund signature */
|
||||
if (GNUNET_OK !=
|
||||
TALER_merchant_refund_verify (coin_pub,
|
||||
h_contract_terms,
|
||||
rtransaction_id,
|
||||
amount_with_fee,
|
||||
merchant_pub,
|
||||
merchant_sig))
|
||||
{
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.h_contract_terms = *h_contract_terms,
|
||||
.coin_pub = *coin_pub,
|
||||
.merchant = *merchant_pub,
|
||||
.rtransaction_id = GNUNET_htonll (rtransaction_id),
|
||||
};
|
||||
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
amount_with_fee);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||
&rr,
|
||||
&merchant_sig->eddsa_sig,
|
||||
&merchant_pub->eddsa_pub))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"refund"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
amount_with_fee),
|
||||
GNUNET_JSON_pack_data_auto ("coin_pub",
|
||||
coin_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
amount_with_fee);
|
||||
if (TALER_ARL_do_abort ())
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"refund"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
amount_with_fee),
|
||||
GNUNET_JSON_pack_data_auto ("coin_pub",
|
||||
coin_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
amount_with_fee);
|
||||
if (TALER_ARL_do_abort ())
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
TALER_amount_ntoh (&refund_fee,
|
||||
|
@ -209,31 +209,19 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
||||
.refund = refund
|
||||
};
|
||||
|
||||
// FIXME: move to libtalerutil!
|
||||
if (GNUNET_OK !=
|
||||
TALER_merchant_refund_verify (&refund->coin.coin_pub,
|
||||
&refund->details.h_contract_terms,
|
||||
refund->details.rtransaction_id,
|
||||
&refund->details.refund_amount,
|
||||
&refund->details.merchant_pub,
|
||||
&refund->details.merchant_sig))
|
||||
{
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.h_contract_terms = refund->details.h_contract_terms,
|
||||
.coin_pub = refund->coin.coin_pub,
|
||||
.merchant = refund->details.merchant_pub,
|
||||
.rtransaction_id = GNUNET_htonll (refund->details.rtransaction_id)
|
||||
};
|
||||
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
&refund->details.refund_amount);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||
&rr,
|
||||
&refund->details.merchant_sig.eddsa_sig,
|
||||
&refund->details.merchant_pub.eddsa_pub))
|
||||
{
|
||||
TALER_LOG_WARNING ("Invalid signature on refund request\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_REFUND_MERCHANT_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
TALER_LOG_WARNING ("Invalid signature on refund request\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_REFUND_MERCHANT_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Fetch the coin's denomination (hash) */
|
||||
|
@ -165,25 +165,15 @@ TEH_RESPONSE_compile_transaction_history (
|
||||
const struct TALER_EXCHANGEDB_RefundListEntry *refund =
|
||||
pos->details.refund;
|
||||
struct TALER_Amount value;
|
||||
// FIXME: move to libtalerutil!
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.h_contract_terms = refund->h_contract_terms,
|
||||
.coin_pub = *coin_pub,
|
||||
.merchant = refund->merchant_pub,
|
||||
.rtransaction_id = GNUNET_htonll (refund->rtransaction_id)
|
||||
};
|
||||
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
&refund->refund_amount);
|
||||
#if ENABLE_SANITY_CHECKS
|
||||
/* internal sanity check before we hand out a bogus sig... */
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||
&rr,
|
||||
&refund->merchant_sig.eddsa_sig,
|
||||
&refund->merchant_pub.eddsa_pub))
|
||||
TALER_merchant_refund_verify (coin_pub,
|
||||
&refund->h_contract_terms,
|
||||
refund->rtransaction_id,
|
||||
&refund->refund_amount,
|
||||
&refund->merchant_pub,
|
||||
&refund->merchant_sig))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
json_decref (history);
|
||||
|
@ -1897,6 +1897,50 @@ TALER_wallet_recoup_refresh_sign (
|
||||
struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/* ********************* merchant signing ************************** */
|
||||
|
||||
|
||||
/**
|
||||
* Create merchant signature approving a refund.
|
||||
*
|
||||
* @param coin_pub coin to be refunded
|
||||
* @param h_contract_terms contract to be refunded
|
||||
* @param rtransaction_id unique ID for this (partial) refund
|
||||
* @param amount amount to be refunded
|
||||
* @param merchant_priv private key to sign with
|
||||
* @param[out] merchant_sig where to write the signature
|
||||
*/
|
||||
void
|
||||
TALER_merchant_refund_sign (
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_PrivateContractHash *h_contract_terms,
|
||||
uint64_t rtransaction_id,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_MerchantPrivateKeyP *merchant_priv,
|
||||
struct TALER_MerchantSignatureP *merchant_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Verify merchant signature approving a refund.
|
||||
*
|
||||
* @param coin_pub coin to be refunded
|
||||
* @param h_contract_terms contract to be refunded
|
||||
* @param rtransaction_id unique ID for this (partial) refund
|
||||
* @param amount amount to be refunded
|
||||
* @param merchant_pub public key of the merchant
|
||||
* @param merchant_sig signature to verify
|
||||
* @return #GNUNET_OK if the signature is valid
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_merchant_refund_verify (
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_PrivateContractHash *h_contract_terms,
|
||||
uint64_t rtransaction_id,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_MerchantPublicKeyP *merchant_pub,
|
||||
const struct TALER_MerchantSignatureP *merchant_sig);
|
||||
|
||||
|
||||
/* ********************* offline signing ************************** */
|
||||
|
||||
|
||||
|
@ -630,12 +630,6 @@ struct TALER_RefundRequestPS
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -598,25 +598,23 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
else if (0 == strcasecmp (type,
|
||||
"REFUND"))
|
||||
{
|
||||
struct TALER_PrivateContractHash h_contract_terms;
|
||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||
struct TALER_MerchantSignatureP sig;
|
||||
struct TALER_Amount refund_fee;
|
||||
struct TALER_Amount sig_amount;
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
uint64_t rtransaction_id;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any ("refund_fee",
|
||||
&refund_fee),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_sig",
|
||||
&sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
|
||||
&rr.h_contract_terms),
|
||||
&h_contract_terms),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_pub",
|
||||
&rr.merchant),
|
||||
&merchant_pub),
|
||||
GNUNET_JSON_spec_uint64 ("rtransaction_id",
|
||||
&rr.rtransaction_id),
|
||||
&rtransaction_id),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -636,16 +634,13 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
&sig_amount);
|
||||
rr.rtransaction_id = GNUNET_htonll (rr.rtransaction_id);
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
&sig_amount);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||
&rr,
|
||||
&sig.eddsa_sig,
|
||||
&rr.merchant.eddsa_pub))
|
||||
TALER_merchant_refund_verify (coin_pub,
|
||||
&h_contract_terms,
|
||||
rtransaction_id,
|
||||
&sig_amount,
|
||||
&merchant_pub,
|
||||
&sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
|
@ -95,8 +95,10 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh,
|
||||
{
|
||||
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_sig",
|
||||
exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
exchange_pub),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -291,22 +293,20 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
|
||||
struct TALER_MerchantSignatureP sig;
|
||||
struct TALER_Amount refund_fee;
|
||||
struct TALER_Amount sig_amount;
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.coin_pub = rh->depconf.coin_pub
|
||||
};
|
||||
struct TALER_PrivateContractHash h_contract_terms;
|
||||
uint64_t rtransaction_id;
|
||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||
struct GNUNET_JSON_Specification ispec[] = {
|
||||
TALER_JSON_spec_amount_any ("refund_fee",
|
||||
&refund_fee),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_sig",
|
||||
&sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
|
||||
&rr.h_contract_terms),
|
||||
&h_contract_terms),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_pub",
|
||||
&rr.merchant),
|
||||
&merchant_pub),
|
||||
GNUNET_JSON_spec_uint64 ("rtransaction_id",
|
||||
&rr.rtransaction_id), /* Note: converted to NBO below */
|
||||
&rtransaction_id),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -328,30 +328,29 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
&sig_amount);
|
||||
rr.rtransaction_id = GNUNET_htonll (rr.rtransaction_id);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||
&rr,
|
||||
&sig.eddsa_sig,
|
||||
&rr.merchant.eddsa_pub))
|
||||
TALER_merchant_refund_verify (&rh->depconf.coin_pub,
|
||||
&h_contract_terms,
|
||||
rtransaction_id,
|
||||
&sig_amount,
|
||||
&merchant_pub,
|
||||
&sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
|
||||
&rr.h_contract_terms)) ||
|
||||
&h_contract_terms)) ||
|
||||
(0 != GNUNET_memcmp (&rh->depconf.merchant,
|
||||
&rr.merchant)) )
|
||||
&merchant_pub)) )
|
||||
{
|
||||
/* refund is about a different merchant/contract */
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (rr.rtransaction_id == rh->depconf.rtransaction_id)
|
||||
if (rtransaction_id == rh->depconf.rtransaction_id)
|
||||
{
|
||||
/* Eh, this shows either a dependency failure or idempotency,
|
||||
but must not happen in a conflict reply. Fail! */
|
||||
@ -468,15 +467,13 @@ 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;
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.coin_pub = rh->depconf.coin_pub
|
||||
};
|
||||
struct TALER_PrivateContractHash h_contract_terms;
|
||||
uint64_t rtransaction_id;
|
||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||
struct GNUNET_JSON_Specification ispec[] = {
|
||||
TALER_JSON_spec_amount_any ("amount",
|
||||
&amount),
|
||||
@ -487,9 +484,9 @@ verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh,
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_sig",
|
||||
&sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
|
||||
&rr.h_contract_terms),
|
||||
&h_contract_terms),
|
||||
GNUNET_JSON_spec_fixed_auto ("merchant_pub",
|
||||
&rr.merchant),
|
||||
&merchant_pub),
|
||||
GNUNET_JSON_spec_uint64 ("rtransaction_id",
|
||||
&rtransaction_id),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -504,26 +501,27 @@ verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh,
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
rr.rtransaction_id = GNUNET_htonll (rtransaction_id);
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
&amount);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||
&rr,
|
||||
&sig.eddsa_sig,
|
||||
&rh->depconf.merchant.eddsa_pub))
|
||||
TALER_merchant_refund_verify (&rh->depconf.coin_pub,
|
||||
&h_contract_terms,
|
||||
rtransaction_id,
|
||||
&amount,
|
||||
&merchant_pub,
|
||||
&sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if ( (rr.rtransaction_id != rh->depconf.rtransaction_id) ||
|
||||
TALER_amount_ntoh (&depconf_amount,
|
||||
&rh->depconf.refund_amount);
|
||||
if ( (rtransaction_id != rh->depconf.rtransaction_id) ||
|
||||
(0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
|
||||
&rr.h_contract_terms)) ||
|
||||
&h_contract_terms)) ||
|
||||
(0 != GNUNET_memcmp (&rh->depconf.merchant,
|
||||
&rr.merchant)) ||
|
||||
(0 == TALER_amount_cmp_nbo (&rh->depconf.refund_amount,
|
||||
&rr.refund_amount)) )
|
||||
&merchant_pub)) ||
|
||||
(0 == TALER_amount_cmp (&depconf_amount,
|
||||
&amount)) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -675,13 +673,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
|
||||
TALER_EXCHANGE_RefundCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.h_contract_terms = *h_contract_terms,
|
||||
.rtransaction_id = GNUNET_htonll (rtransaction_id),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||
struct TALER_MerchantSignatureP merchant_sig;
|
||||
struct TALER_EXCHANGE_RefundHandle *rh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
@ -692,23 +684,22 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv->eddsa_priv,
|
||||
&rr.merchant.eddsa_pub);
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
amount);
|
||||
GNUNET_CRYPTO_eddsa_sign (&merchant_priv->eddsa_priv,
|
||||
&rr,
|
||||
&merchant_sig.eddsa_sig);
|
||||
|
||||
|
||||
&merchant_pub.eddsa_pub);
|
||||
TALER_merchant_refund_sign (coin_pub,
|
||||
h_contract_terms,
|
||||
rtransaction_id,
|
||||
amount,
|
||||
merchant_priv,
|
||||
&merchant_sig);
|
||||
{
|
||||
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
||||
char *end;
|
||||
|
||||
end = GNUNET_STRINGS_data_to_string (coin_pub,
|
||||
sizeof (struct
|
||||
TALER_CoinSpendPublicKeyP),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
end = GNUNET_STRINGS_data_to_string (
|
||||
coin_pub,
|
||||
sizeof (struct TALER_CoinSpendPublicKeyP),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
@ -723,7 +714,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_JSON_pack_uint64 ("rtransaction_id",
|
||||
rtransaction_id),
|
||||
GNUNET_JSON_pack_data_auto ("merchant_pub",
|
||||
&rr.merchant),
|
||||
&merchant_pub),
|
||||
GNUNET_JSON_pack_data_auto ("merchant_sig",
|
||||
&merchant_sig));
|
||||
rh = GNUNET_new (struct TALER_EXCHANGE_RefundHandle);
|
||||
@ -742,7 +733,7 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
|
||||
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 = rr.merchant;
|
||||
rh->depconf.merchant = merchant_pub;
|
||||
rh->depconf.rtransaction_id = GNUNET_htonll (rtransaction_id);
|
||||
TALER_amount_hton (&rh->depconf.refund_amount,
|
||||
amount);
|
||||
|
@ -76,6 +76,7 @@ libtalerutil_la_SOURCES = \
|
||||
getopt.c \
|
||||
lang.c \
|
||||
iban.c \
|
||||
merchant_signatures.c \
|
||||
mhd.c \
|
||||
offline_signatures.c \
|
||||
payto.c \
|
||||
|
78
src/util/merchant_signatures.c
Normal file
78
src/util/merchant_signatures.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020 Taler Systems SA
|
||||
|
||||
TALER is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file merchant_signatures.c
|
||||
* @brief Utility functions for Taler merchant signatures
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler_util.h"
|
||||
#include "taler_signatures.h"
|
||||
|
||||
|
||||
void
|
||||
TALER_merchant_refund_sign (
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_PrivateContractHash *h_contract_terms,
|
||||
uint64_t rtransaction_id,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_MerchantPrivateKeyP *merchant_priv,
|
||||
struct TALER_MerchantSignatureP *merchant_sig)
|
||||
{
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.h_contract_terms = *h_contract_terms,
|
||||
.coin_pub = *coin_pub,
|
||||
.rtransaction_id = GNUNET_htonll (rtransaction_id)
|
||||
};
|
||||
|
||||
TALER_amount_hton (&rr.refund_amount,
|
||||
amount);
|
||||
GNUNET_CRYPTO_eddsa_sign (&merchant_priv->eddsa_priv,
|
||||
&rr,
|
||||
&merchant_sig->eddsa_sig);
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_merchant_refund_verify (
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_PrivateContractHash *h_contract_terms,
|
||||
uint64_t rtransaction_id,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_MerchantPublicKeyP *merchant_pub,
|
||||
const struct TALER_MerchantSignatureP *merchant_sig)
|
||||
{
|
||||
struct TALER_RefundRequestPS rr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
|
||||
.purpose.size = htonl (sizeof (rr)),
|
||||
.h_contract_terms = *h_contract_terms,
|
||||
.coin_pub = *coin_pub,
|
||||
.rtransaction_id = GNUNET_htonll (rtransaction_id)
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* end of merchant_signatures.c */
|
Loading…
Reference in New Issue
Block a user