centralize exchange online signature logic

This commit is contained in:
Christian Grothoff 2022-03-29 15:21:49 +02:00
parent 3249687b2a
commit 074ea7502e
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
24 changed files with 2322 additions and 1301 deletions

View File

@ -182,17 +182,18 @@ verify_and_execute_deposit_confirmation (
/* check deposit confirmation signature */
if (GNUNET_OK !=
TALER_exchange_deposit_confirm_verify (&dc->h_contract_terms,
&dc->h_wire,
NULL /* h_extensions! */,
dc->exchange_timestamp,
dc->wire_deadline,
dc->refund_deadline,
&dc->amount_without_fee,
&dc->coin_pub,
&dc->merchant,
&dc->exchange_pub,
&dc->exchange_sig))
TALER_exchange_online_deposit_confirmation_verify (
&dc->h_contract_terms,
&dc->h_wire,
NULL /* h_extensions! */,
dc->exchange_timestamp,
dc->wire_deadline,
dc->refund_deadline,
&dc->amount_without_fee,
&dc->coin_pub,
&dc->merchant,
&dc->exchange_pub,
&dc->exchange_sig))
{
TALER_LOG_WARNING (
"Invalid signature on /deposit-confirmation request\n");

View File

@ -57,41 +57,36 @@
* @return MHD result code
*/
static MHD_RESULT
reply_deposit_success (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_ExtensionContractHashP *h_extensions,
const struct
TALER_PrivateContractHashP *h_contract_terms,
struct GNUNET_TIME_Timestamp exchange_timestamp,
struct GNUNET_TIME_Timestamp refund_deadline,
struct GNUNET_TIME_Timestamp wire_deadline,
const struct TALER_MerchantPublicKeyP *merchant,
const struct TALER_Amount *amount_without_fee)
reply_deposit_success (
struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_ExtensionContractHashP *h_extensions,
const struct TALER_PrivateContractHashP *h_contract_terms,
struct GNUNET_TIME_Timestamp exchange_timestamp,
struct GNUNET_TIME_Timestamp refund_deadline,
struct GNUNET_TIME_Timestamp wire_deadline,
const struct TALER_MerchantPublicKeyP *merchant,
const struct TALER_Amount *amount_without_fee)
{
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
struct TALER_DepositConfirmationPS dc = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
.purpose.size = htonl (sizeof (dc)),
.h_contract_terms = *h_contract_terms,
.h_wire = *h_wire,
.exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
.refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
.wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
.coin_pub = *coin_pub,
.merchant_pub = *merchant
};
enum TALER_ErrorCode ec;
if (NULL != h_extensions)
dc.h_extensions = *h_extensions;
TALER_amount_hton (&dc.amount_without_fee,
amount_without_fee);
if (TALER_EC_NONE !=
(ec = TEH_keys_exchange_sign (&dc,
&pub,
&sig)))
(ec = TALER_exchange_online_deposit_confirmation_sign (
&TEH_keys_exchange_sign_,
h_contract_terms,
h_wire,
h_extensions,
exchange_timestamp,
wire_deadline,
refund_deadline,
amount_without_fee,
coin_pub,
merchant,
&pub,
&sig)))
{
return TALER_MHD_reply_with_ec (connection,
ec,

View File

@ -46,34 +46,30 @@
* @return MHD result code
*/
static MHD_RESULT
reply_deposit_details (struct MHD_Connection *connection,
const struct
TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *coin_contribution,
const struct TALER_WireTransferIdentifierRawP *wtid,
struct GNUNET_TIME_Timestamp exec_time)
reply_deposit_details (
struct MHD_Connection *connection,
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *coin_contribution,
const struct TALER_WireTransferIdentifierRawP *wtid,
struct GNUNET_TIME_Timestamp exec_time)
{
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
struct TALER_ConfirmWirePS cw = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
.purpose.size = htonl (sizeof (cw)),
.h_wire = *h_wire,
.h_contract_terms = *h_contract_terms,
.wtid = *wtid,
.coin_pub = *coin_pub,
.execution_time = GNUNET_TIME_timestamp_hton (exec_time)
};
enum TALER_ErrorCode ec;
TALER_amount_hton (&cw.coin_contribution,
coin_contribution);
if (TALER_EC_NONE !=
(ec = TEH_keys_exchange_sign (&cw,
&pub,
&sig)))
(ec = TALER_exchange_online_confirm_wire_sign (
&TEH_keys_exchange_sign_,
h_wire,
h_contract_terms,
wtid,
coin_pub,
exec_time,
coin_contribution,
&pub,
&sig)))
{
return TALER_MHD_reply_with_ec (connection,
ec,

View File

@ -1797,19 +1797,17 @@ create_krd (struct TEH_KeyStateHandle *ksh,
GNUNET_TIME_timestamp2s (last_cpd));
/* Sign hash over denomination keys */
{
struct TALER_ExchangeKeySetPS ks = {
.purpose.size = htonl (sizeof (ks)),
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
.list_issue_date = GNUNET_TIME_timestamp_hton (last_cpd),
.hc = *denom_keys_hash
};
enum TALER_ErrorCode ec;
if (TALER_EC_NONE !=
(ec = TEH_keys_exchange_sign2 (ksh,
&ks,
&exchange_pub,
&exchange_sig)))
(ec =
TALER_exchange_online_key_set_sign (
&TEH_keys_exchange_sign2_,
ksh,
last_cpd,
denom_keys_hash,
&exchange_pub,
&exchange_sig)))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Could not create key response data: cannot sign (%s)\n",
@ -2770,11 +2768,12 @@ TEH_keys_exchange_sign_ (
enum TALER_ErrorCode
TEH_keys_exchange_sign2_ (
struct TEH_KeyStateHandle *ksh,
void *cls,
const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig)
{
struct TEH_KeyStateHandle *ksh = cls;
enum TALER_ErrorCode ec;
TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_EDDSA]++;

View File

@ -367,7 +367,7 @@ TEH_keys_exchange_sign_ (
* number of bytes of the data structure, including its header. Use
* #TEH_keys_exchange_sign() instead of calling this function directly!
*
* @param ksh key state state to look in
* @param cls key state state to look in
* @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
@ -375,7 +375,7 @@ TEH_keys_exchange_sign_ (
*/
enum TALER_ErrorCode
TEH_keys_exchange_sign2_ (
struct TEH_KeyStateHandle *ksh,
void *cls,
const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);

View File

@ -414,19 +414,15 @@ TEH_handler_kyc_check (
{
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
struct TALER_ExchangeAccountSetupSuccessPS as = {
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
.purpose.size = htonl (sizeof (as)),
.h_payto = kyp->h_payto,
.timestamp = GNUNET_TIME_timestamp_hton (now)
};
enum TALER_ErrorCode ec;
if (TALER_EC_NONE !=
(ec = TEH_keys_exchange_sign (&as,
&pub,
&sig)))
(ec = TALER_exchange_online_account_setup_success_sign (
&TEH_keys_exchange_sign_,
&kyp->h_payto,
now,
&pub,
&sig)))
{
return TALER_MHD_reply_with_ec (rc->connection,
ec,

View File

@ -48,18 +48,15 @@ reply_melt_success (struct MHD_Connection *connection,
{
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
struct TALER_RefreshMeltConfirmationPS body = {
.purpose.size = htonl (sizeof (body)),
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
.rc = *rc,
.noreveal_index = htonl (noreveal_index)
};
enum TALER_ErrorCode ec;
if (TALER_EC_NONE !=
(ec = TEH_keys_exchange_sign (&body,
&pub,
&sig)))
(ec = TALER_exchange_online_melt_confirmation_sign (
&TEH_keys_exchange_sign_,
rc,
noreveal_index,
&pub,
&sig)))
{
return TALER_MHD_reply_with_ec (connection,
ec,

View File

@ -50,22 +50,18 @@ reply_refund_success (struct MHD_Connection *connection,
{
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
struct TALER_RefundConfirmationPS rc = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
.purpose.size = htonl (sizeof (rc)),
.h_contract_terms = refund->h_contract_terms,
.coin_pub = *coin_pub,
.merchant = refund->merchant_pub,
.rtransaction_id = GNUNET_htonll (refund->rtransaction_id)
};
enum TALER_ErrorCode ec;
TALER_amount_hton (&rc.refund_amount,
&refund->refund_amount);
if (TALER_EC_NONE !=
(ec = TEH_keys_exchange_sign (&rc,
&pub,
&sig)))
(ec = TALER_exchange_online_refund_confirmation_sign (
&TEH_keys_exchange_sign_,
&refund->h_contract_terms,
coin_pub,
&refund->merchant_pub,
refund->rtransaction_id,
&refund->refund_amount,
&pub,
&sig)))
{
return TALER_MHD_reply_with_ec (connection,
ec,

View File

@ -241,21 +241,16 @@ TEH_RESPONSE_compile_transaction_history (
pos->details.old_coin_recoup;
struct TALER_ExchangePublicKeyP epub;
struct TALER_ExchangeSignatureP esig;
struct TALER_RecoupRefreshConfirmationPS pc = {
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
.purpose.size = htonl (sizeof (pc)),
.timestamp = GNUNET_TIME_timestamp_hton (pr->timestamp),
.coin_pub = pr->coin.coin_pub,
.old_coin_pub = pr->old_coin_pub
};
TALER_amount_hton (&pc.recoup_amount,
&pr->value);
if (TALER_EC_NONE !=
TEH_keys_exchange_sign (&pc,
&epub,
&esig))
TALER_exchange_online_confirm_recoup_refresh_sign (
&TEH_keys_exchange_sign_,
pr->timestamp,
&pr->value,
&pr->coin.coin_pub,
&pr->old_coin_pub,
&epub,
&esig))
{
GNUNET_break (0);
json_decref (history);
@ -295,20 +290,16 @@ TEH_RESPONSE_compile_transaction_history (
pos->details.recoup;
struct TALER_ExchangePublicKeyP epub;
struct TALER_ExchangeSignatureP esig;
struct TALER_RecoupConfirmationPS pc = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
.purpose.size = htonl (sizeof (pc)),
.timestamp = GNUNET_TIME_timestamp_hton (recoup->timestamp),
.coin_pub = *coin_pub,
.reserve_pub = recoup->reserve_pub
};
TALER_amount_hton (&pc.recoup_amount,
&recoup->value);
if (TALER_EC_NONE !=
TEH_keys_exchange_sign (&pc,
&epub,
&esig))
TALER_exchange_online_confirm_recoup_sign (
&TEH_keys_exchange_sign_,
recoup->timestamp,
&recoup->value,
coin_pub,
&recoup->reserve_pub,
&epub,
&esig))
{
GNUNET_break (0);
json_decref (history);
@ -351,21 +342,16 @@ TEH_RESPONSE_compile_transaction_history (
pos->details.recoup_refresh;
struct TALER_ExchangePublicKeyP epub;
struct TALER_ExchangeSignatureP esig;
struct TALER_RecoupRefreshConfirmationPS pc = {
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
.purpose.size = htonl (sizeof (pc)),
.timestamp = GNUNET_TIME_timestamp_hton (pr->timestamp),
.coin_pub = *coin_pub,
.old_coin_pub = pr->old_coin_pub
};
TALER_amount_hton (&pc.recoup_amount,
&pr->value);
if (TALER_EC_NONE !=
TEH_keys_exchange_sign (&pc,
&epub,
&esig))
TALER_exchange_online_confirm_recoup_refresh_sign (
&TEH_keys_exchange_sign_,
pr->timestamp,
&pr->value,
coin_pub,
&pr->old_coin_pub,
&epub,
&esig))
{
GNUNET_break (0);
json_decref (history);
@ -424,18 +410,12 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
enum TALER_ErrorCode ec;
now = GNUNET_TIME_timestamp_get ();
{
struct TALER_DenominationUnknownAffirmationPS dua = {
.purpose.size = htonl (sizeof (dua)),
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
.timestamp = GNUNET_TIME_timestamp_hton (now),
.h_denom_pub = *dph,
};
ec = TEH_keys_exchange_sign (&dua,
&epub,
&esig);
}
ec = TALER_exchange_online_denomination_unknown_sign (
&TEH_keys_exchange_sign_,
now,
dph,
&epub,
&esig);
if (TALER_EC_NONE != ec)
{
GNUNET_break (0);
@ -471,22 +451,14 @@ TEH_RESPONSE_reply_expired_denom_pub_hash (
enum TALER_ErrorCode ecr;
struct GNUNET_TIME_Timestamp now
= GNUNET_TIME_timestamp_get ();
struct TALER_DenominationExpiredAffirmationPS dua = {
.purpose.size = htonl (sizeof (dua)),
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
.timestamp = GNUNET_TIME_timestamp_hton (now),
.h_denom_pub = *dph,
};
/* strncpy would create a compiler warning */
memcpy (dua.operation,
oper,
GNUNET_MIN (sizeof (dua.operation),
strlen (oper)));
ecr = TEH_keys_exchange_sign (&dua,
&epub,
&esig);
ecr = TALER_exchange_online_denomination_expired_sign (
&TEH_keys_exchange_sign_,
now,
dph,
oper,
&epub,
&esig);
if (TALER_EC_NONE != ecr)
{
GNUNET_break (0);
@ -523,18 +495,12 @@ TEH_RESPONSE_reply_invalid_denom_cipher_for_operation (
enum TALER_ErrorCode ec;
now = GNUNET_TIME_timestamp_get ();
{
struct TALER_DenominationUnknownAffirmationPS dua = {
.purpose.size = htonl (sizeof (dua)),
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
.timestamp = GNUNET_TIME_timestamp_hton (now),
.h_denom_pub = *dph,
};
ec = TEH_keys_exchange_sign (&dua,
&epub,
&esig);
}
ec = TALER_exchange_online_denomination_unknown_sign (
&TEH_keys_exchange_sign_,
now,
dph,
&epub,
&esig);
if (TALER_EC_NONE != ec)
{
GNUNET_break (0);
@ -679,26 +645,19 @@ TEH_RESPONSE_compile_reserve_history (
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
if (TALER_EC_NONE !=
TALER_exchange_online_confirm_recoup_sign (
&TEH_keys_exchange_sign_,
recoup->timestamp,
&recoup->value,
&recoup->coin.coin_pub,
&recoup->reserve_pub,
&pub,
&sig))
{
struct TALER_RecoupConfirmationPS pc = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
.purpose.size = htonl (sizeof (pc)),
.timestamp = GNUNET_TIME_timestamp_hton (recoup->timestamp),
.coin_pub = recoup->coin.coin_pub,
.reserve_pub = recoup->reserve_pub
};
TALER_amount_hton (&pc.recoup_amount,
&recoup->value);
if (TALER_EC_NONE !=
TEH_keys_exchange_sign (&pc,
&pub,
&sig))
{
GNUNET_break (0);
json_decref (json_history);
return NULL;
}
GNUNET_break (0);
json_decref (json_history);
return NULL;
}
if (0 !=
@ -731,30 +690,21 @@ TEH_RESPONSE_compile_reserve_history (
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
if (TALER_EC_NONE !=
TALER_exchange_online_reserve_closed_sign (
&TEH_keys_exchange_sign_,
closing->execution_date,
&closing->amount,
&closing->closing_fee,
closing->receiver_account_details,
&closing->wtid,
&pos->details.closing->reserve_pub,
&pub,
&sig))
{
struct TALER_ReserveCloseConfirmationPS rcc = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
.purpose.size = htonl (sizeof (rcc)),
.timestamp = GNUNET_TIME_timestamp_hton (closing->execution_date),
.reserve_pub = pos->details.closing->reserve_pub,
.wtid = closing->wtid
};
TALER_amount_hton (&rcc.closing_amount,
&closing->amount);
TALER_amount_hton (&rcc.closing_fee,
&closing->closing_fee);
TALER_payto_hash (closing->receiver_account_details,
&rcc.h_payto);
if (TALER_EC_NONE !=
TEH_keys_exchange_sign (&rcc,
&pub,
&sig))
{
GNUNET_break (0);
json_decref (json_history);
return NULL;
}
GNUNET_break (0);
json_decref (json_history);
return NULL;
}
if (0 !=
json_array_append_new (

View File

@ -93,11 +93,11 @@ reply_transfer_details (struct MHD_Connection *connection,
const struct AggregatedDepositDetail *wdd_head)
{
json_t *deposits;
struct TALER_WireDepositDetailP dd;
struct GNUNET_HashContext *hash_context;
struct TALER_WireDepositDataPS wdp;
struct GNUNET_HashCode h_details;
struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig;
struct TALER_PaytoHashP h_payto;
deposits = json_array ();
GNUNET_assert (NULL != deposits);
@ -106,16 +106,12 @@ reply_transfer_details (struct MHD_Connection *connection,
NULL != wdd_pos;
wdd_pos = wdd_pos->next)
{
dd.h_contract_terms = wdd_pos->h_contract_terms;
dd.execution_time = GNUNET_TIME_timestamp_hton (exec_time);
dd.coin_pub = wdd_pos->coin_pub;
TALER_amount_hton (&dd.deposit_value,
&wdd_pos->deposit_value);
TALER_amount_hton (&dd.deposit_fee,
&wdd_pos->deposit_fee);
GNUNET_CRYPTO_hash_context_read (hash_context,
&dd,
sizeof (struct TALER_WireDepositDetailP));
TALER_exchange_online_wire_deposit_append (hash_context,
&wdd_pos->h_contract_terms,
exec_time,
&wdd_pos->coin_pub,
&wdd_pos->deposit_value,
&wdd_pos->deposit_fee);
if (0 !=
json_array_append_new (
deposits,
@ -137,24 +133,21 @@ reply_transfer_details (struct MHD_Connection *connection,
"json_array_append_new() failed");
}
}
wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT);
wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS));
TALER_amount_hton (&wdp.total,
total);
TALER_amount_hton (&wdp.wire_fee,
wire_fee);
wdp.merchant_pub = *merchant_pub;
TALER_payto_hash (payto_uri,
&wdp.h_payto);
GNUNET_CRYPTO_hash_context_finish (hash_context,
&wdp.h_details);
&h_details);
{
enum TALER_ErrorCode ec;
if (TALER_EC_NONE !=
(ec = TEH_keys_exchange_sign (&wdp,
&pub,
&sig)))
(ec = TALER_exchange_online_wire_deposit_sign (
&TEH_keys_exchange_sign_,
total,
wire_fee,
merchant_pub,
payto_uri,
&h_details,
&pub,
&sig)))
{
json_decref (deposits);
return TALER_MHD_reply_with_ec (connection,
@ -163,6 +156,8 @@ reply_transfer_details (struct MHD_Connection *connection,
}
}
TALER_payto_hash (payto_uri,
&h_payto);
return TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_OK,
@ -173,7 +168,7 @@ reply_transfer_details (struct MHD_Connection *connection,
GNUNET_JSON_pack_data_auto ("merchant_pub",
merchant_pub),
GNUNET_JSON_pack_data_auto ("h_payto",
&wdp.h_payto),
&h_payto),
GNUNET_JSON_pack_timestamp ("execution_time",
exec_time),
GNUNET_JSON_pack_array_steal ("deposits",

View File

@ -1455,6 +1455,132 @@ struct TALER_ExchangeWithdrawValues
};
/**
* @brief Information about a signing key of the exchange. Signing keys are used
* to sign exchange messages other than coins, i.e. to confirm that a
* deposit was successful or that a refresh was accepted.
*
* FIXME: remove this from the public API...
*/
struct TALER_ExchangeSigningKeyValidityPS
{
/**
* Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When does this signing key begin to be valid?
*/
struct GNUNET_TIME_TimestampNBO start;
/**
* When does this signing key expire? Note: This is currently when
* the Exchange will definitively stop using it. Signatures made with
* the key remain valid until @e end. When checking validity periods,
* clients should allow for some overlap between keys and tolerate
* the use of either key during the overlap time (due to the
* possibility of clock skew).
*/
struct GNUNET_TIME_TimestampNBO expire;
/**
* When do signatures with this signing key become invalid? After
* this point, these signatures cannot be used in (legal) disputes
* anymore, as the Exchange is then allowed to destroy its side of the
* evidence. @e end is expected to be significantly larger than @e
* expire (by a year or more).
*/
struct GNUNET_TIME_TimestampNBO end;
/**
* The public online signing key that the exchange will use
* between @e start and @e expire.
*/
struct TALER_ExchangePublicKeyP signkey_pub;
};
/**
* @brief Information about a denomination key. Denomination keys
* are used to sign coins of a certain value into existence.
*
* FIXME: remove this from the public API...
*/
struct TALER_DenominationKeyValidityPS
{
/**
* Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* The long-term offline master key of the exchange that was
* used to create @e signature.
*/
struct TALER_MasterPublicKeyP master;
/**
* Start time of the validity period for this key.
*/
struct GNUNET_TIME_TimestampNBO start;
/**
* The exchange will sign fresh coins between @e start and this time.
* @e expire_withdraw will be somewhat larger than @e start to
* ensure a sufficiently large anonymity set, while also allowing
* the Exchange to limit the financial damage in case of a key being
* compromised. Thus, exchanges with low volume are expected to have a
* longer withdraw period (@e expire_withdraw - @e start) than exchanges
* with high transaction volume. The period may also differ between
* types of coins. A exchange may also have a few denomination keys
* with the same value with overlapping validity periods, to address
* issues such as clock skew.
*/
struct GNUNET_TIME_TimestampNBO expire_withdraw;
/**
* Coins signed with the denomination key must be spent or refreshed
* between @e start and this expiration time. After this time, the
* exchange will refuse transactions involving this key as it will
* "drop" the table with double-spending information (shortly after)
* this time. Note that wallets should refresh coins significantly
* before this time to be on the safe side. @e expire_deposit must be
* significantly larger than @e expire_withdraw (by months or even
* years).
*/
struct GNUNET_TIME_TimestampNBO expire_deposit;
/**
* When do signatures with this denomination key become invalid?
* After this point, these signatures cannot be used in (legal)
* disputes anymore, as the Exchange is then allowed to destroy its side
* of the evidence. @e expire_legal is expected to be significantly
* larger than @e expire_deposit (by a year or more).
*/
struct GNUNET_TIME_TimestampNBO expire_legal;
/**
* The value of the coins signed with this denomination key.
*/
struct TALER_AmountNBO value;
/**
* Fees for the coin.
*/
struct TALER_DenomFeeSetNBOP fees;
/**
* Hash code of the denomination public key. (Used to avoid having
* the variable-size RSA key in this struct.)
*/
struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
};
/**
* Free internals of @a denom_pub, but not @a denom_pub itself.
*
@ -2678,40 +2804,6 @@ TALER_CRYPTO_helper_esign_disconnect (
struct TALER_CRYPTO_ExchangeSignHelper *esh);
/* ********************* exchange signing ************************** */
/**
* Verify a deposit confirmation.
*
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
* @param h_wire hash of the merchants account details
* @param h_extensions hash over the extensions, can be NULL
* @param exchange_timestamp timestamp when the contract was finalized, must not be too far off
* @param wire_deadline date until which the exchange should wire the funds
* @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
* @param amount_without_fee the amount to be deposited after fees
* @param coin_pub public key of the deposited coin
* @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
* @param exchange_pub exchange's online signing public key
* @param exchange_sig the signature made with purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT
* @return #GNUNET_OK if the signature is valid
*/
enum GNUNET_GenericReturnValue
TALER_exchange_deposit_confirm_verify (
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_ExtensionContractHashP *h_extensions,
struct GNUNET_TIME_Timestamp exchange_timestamp,
struct GNUNET_TIME_Timestamp wire_deadline,
struct GNUNET_TIME_Timestamp refund_deadline,
const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_ExchangeSignatureP *exchange_sig);
/* ********************* wallet signing ************************** */
@ -3333,6 +3425,518 @@ TALER_merchant_refund_verify (
const struct TALER_MerchantSignatureP *merchant_sig);
/* ********************* exchange online signing ************************** */
/**
* Signature of a function that signs the message in @a purpose with the
* exchange's signing key.
*
* The @a purpose data is the beginning of the data of which the signature is
* to be created. The `size` field in @a purpose must correctly indicate the
* number of bytes of the data structure, including its header. *
* @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 #TALER_EC_NONE on success
*/
typedef enum TALER_ErrorCode
(*TALER_ExchangeSignCallback)(
const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Signature of a function that signs the message in @a purpose with the
* exchange's signing key.
*
* The @a purpose data is the beginning of the data of which the signature is
* to be created. The `size` field in @a purpose must correctly indicate the
* number of bytes of the data structure, including its header. *
* @param cls closure
* @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 #TALER_EC_NONE on success
*/
typedef enum TALER_ErrorCode
(*TALER_ExchangeSignCallback2)(
void *cls,
const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Create deposit confirmation signature.
*
* @param scb function to call to create the signature
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
* @param h_wire hash of the merchants account details
* @param h_extensions hash over the extensions, can be NULL
* @param exchange_timestamp timestamp when the contract was finalized, must not be too far off
* @param wire_deadline date until which the exchange should wire the funds
* @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
* @param amount_without_fee the amount to be deposited after fees
* @param coin_pub public key of the deposited coin
* @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_deposit_confirmation_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_ExtensionContractHashP *h_extensions,
struct GNUNET_TIME_Timestamp exchange_timestamp,
struct GNUNET_TIME_Timestamp wire_deadline,
struct GNUNET_TIME_Timestamp refund_deadline,
const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant_pub,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify deposit confirmation signature.
*
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
* @param h_wire hash of the merchants account details
* @param h_extensions hash over the extensions, can be NULL
* @param exchange_timestamp timestamp when the contract was finalized, must not be too far off
* @param wire_deadline date until which the exchange should wire the funds
* @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
* @param amount_without_fee the amount to be deposited after fees
* @param coin_pub public key of the deposited coin
* @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_deposit_confirmation_verify (
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_ExtensionContractHashP *h_extensions,
struct GNUNET_TIME_Timestamp exchange_timestamp,
struct GNUNET_TIME_Timestamp wire_deadline,
struct GNUNET_TIME_Timestamp refund_deadline,
const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create refund confirmation signature.
*
* @param scb function to call to create the signature
* @param XXX wire transfer subject used
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_refund_confirmation_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant,
uint64_t rtransaction_id,
const struct TALER_Amount *refund_amount,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify refund confirmation signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_refund_confirmation_verify (
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant,
uint64_t rtransaction_id,
const struct TALER_Amount *refund_amount,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create refresh melt confirmation signature.
*
* @param scb function to call to create the signature
* @param XXX
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_melt_confirmation_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_RefreshCommitmentP *rc,
uint32_t noreveal_index,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify refresh melt confirmation signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_melt_confirmation_verify (
const struct TALER_RefreshCommitmentP *rc,
uint32_t noreveal_index,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create exchange key set signature.
*
* @param scb function to call to create the signature
* @param timestamp time when the key set was issued
* @param hc hash over all the keys
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_key_set_sign (
TALER_ExchangeSignCallback2 scb,
void *cls,
struct GNUNET_TIME_Timestamp timestamp,
const struct GNUNET_HashCode *hc,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify key set signature.
*
* @param timestamp time when the key set was issued
* @param hc hash over all the keys
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_key_set_verify (
struct GNUNET_TIME_Timestamp timestamp,
const struct GNUNET_HashCode *hc,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create account setup success signature.
*
* @param scb function to call to create the signature
* @param h_payto target of the KYC account
* @param timestamp time when the KYC was confirmed
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_account_setup_success_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_PaytoHashP *h_payto,
struct GNUNET_TIME_Timestamp timestamp,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify account setup success signature.
*
* @param h_payto target of the KYC account
* @param timestamp time when the KYC was confirmed
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_account_setup_success_verify (
const struct TALER_PaytoHashP *h_payto,
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
void
TALER_exchange_online_wire_deposit_append (
struct GNUNET_HashContext *hash_context,
const struct TALER_PrivateContractHashP *h_contract_terms,
struct GNUNET_TIME_Timestamp execution_time,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *deposit_value,
const struct TALER_Amount *deposit_fee);
/**
* Create wire deposit signature.
*
* @param scb function to call to create the signature
* @param XXX
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_wire_deposit_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_Amount *total,
const struct TALER_Amount *wire_fee,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const char *payto,
const struct GNUNET_HashCode *h_details,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify wire deposit signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_wire_deposit_verify (
const struct TALER_Amount *total,
const struct TALER_Amount *wire_fee,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_PaytoHashP *h_payto,
const struct GNUNET_HashCode *h_details,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create wire confirmation signature.
*
* @param scb function to call to create the signature
* @param XXX
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_confirm_wire_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct GNUNET_TIME_Timestamp execution_time,
const struct TALER_Amount *coin_contribution,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify confirm wire signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_confirm_wire_verify (
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct GNUNET_TIME_Timestamp execution_time,
const struct TALER_Amount *coin_contribution,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create confirm recoup signature.
*
* @param scb function to call to create the signature
* @param XXX
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_confirm_recoup_sign (
TALER_ExchangeSignCallback scb,
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *recoup_amount,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_ReservePublicKeyP *reserve_pub,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify confirm recoup signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_confirm_recoup_verify (
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *recoup_amount,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create confirm recoup refresh signature.
*
* @param scb function to call to create the signature
* @param XXX
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_confirm_recoup_refresh_sign (
TALER_ExchangeSignCallback scb,
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *recoup_amount,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify confirm recoup refresh signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_confirm_recoup_refresh_verify (
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *recoup_amount,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create denomination unknown signature.
*
* @param scb function to call to create the signature
* @param XXX
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_denomination_unknown_sign (
TALER_ExchangeSignCallback scb,
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_DenominationHashP *h_denom_pub,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify denomination unknown signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_denomination_unknown_verify (
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create denomination expired signature.
*
* @param scb function to call to create the signature
* @param XXX
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_denomination_expired_sign (
TALER_ExchangeSignCallback scb,
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_DenominationHashP *h_denom_pub,
const char *op,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify denomination expired signature.
*
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_denomination_expired_verify (
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_DenominationHashP *h_denom_pub,
const char *op,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/**
* Create reserve closure signature.
*
* @param scb function to call to create the signature
* @param timestamp time when the reserve was closed
* @param closing_amount amount left in the reserve
* @param closing_fee closing fee charged
* @param payto target of the wire transfer
* @param wtid wire transfer subject used
* @param reserve_pub public key of the closed reserve
* @param[out] pub where to write the public key
* @param[out] sig where to write the signature
*/
enum TALER_ErrorCode
TALER_exchange_online_reserve_closed_sign (
TALER_ExchangeSignCallback scb,
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *closing_amount,
const struct TALER_Amount *closing_fee,
const char *payto,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_ReservePublicKeyP *reserve_pub,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/**
* Verify reserve closure signature.
*
* @param timestamp time when the reserve was closed
* @param closing_amount amount left in the reserve
* @param closing_fee closing fee charged
* @param payto target of the wire transfer
* @param wtid wire transfer subject used
* @param reserve_pub public key of the closed reserve
* @param pub where to write the public key
* @param sig where to write the signature
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_reserve_closed_verify (
struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *closing_amount,
const struct TALER_Amount *closing_fee,
const char *payto,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ExchangePublicKeyP *pub,
const struct TALER_ExchangeSignatureP *sig);
/* ********************* offline signing ************************** */

View File

@ -369,467 +369,6 @@
GNUNET_NETWORK_STRUCT_BEGIN
/**
* @brief format used by the denomination crypto helper when affirming
* that it created a denomination key.
*/
struct TALER_DenominationKeyAnnouncementPS
{
/**
* Purpose must be #TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY.
* Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash of the denomination public key.
*/
struct TALER_DenominationHashP h_denom;
/**
* Hash of the section name in the configuration of this denomination.
*/
struct GNUNET_HashCode h_section_name;
/**
* When does the key become available?
*/
struct GNUNET_TIME_TimestampNBO anchor_time;
/**
* How long is the key available after @e anchor_time?
*/
struct GNUNET_TIME_RelativeNBO duration_withdraw;
};
/**
* @brief format used by the signing crypto helper when affirming
* that it created an exchange signing key.
*/
struct TALER_SigningKeyAnnouncementPS
{
/**
* Purpose must be #TALER_SIGNATURE_SM_SIGNING_KEY.
* Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Public signing key of the exchange this is about.
*/
struct TALER_ExchangePublicKeyP exchange_pub;
/**
* When does the key become available?
*/
struct GNUNET_TIME_TimestampNBO anchor_time;
/**
* How long is the key available after @e anchor_time?
*/
struct GNUNET_TIME_RelativeNBO duration;
};
/**
* @brief Format used to generate the signature on a confirmation
* from the exchange that a deposit request succeeded.
*/
struct TALER_DepositConfirmationPS
{
/**
* Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. Signed
* by a `struct TALER_ExchangePublicKeyP` using EdDSA.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash over the contract for which this deposit is made.
*/
struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
/**
* Hash over the wiring information of the merchant.
*/
struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
/**
* Hash over the extension options of the deposit, 0 if there
* were not extension options.
*/
struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED;
/**
* Time when this confirmation was generated / when the exchange received
* the deposit request.
*/
struct GNUNET_TIME_TimestampNBO exchange_timestamp;
/**
* By when does the exchange expect to pay the merchant
* (as per the merchant's request).
*/
struct GNUNET_TIME_TimestampNBO wire_deadline;
/**
* How much time does the @e merchant have to issue a refund
* request? Zero if refunds are not allowed. After this time, the
* coin cannot be refunded. Note that the wire transfer will not be
* performed by the exchange until the refund deadline. This value
* is taken from the original deposit request.
*/
struct GNUNET_TIME_TimestampNBO refund_deadline;
/**
* Amount to be deposited, excluding fee. Calculated from the
* amount with fee and the fee from the deposit request.
*/
struct TALER_AmountNBO amount_without_fee;
/**
* The public key of the coin that was deposited.
*/
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_pub;
};
/**
* @brief Format used to generate the signature on a request to refund
* a coin into the account of the customer.
*/
struct TALER_RefundConfirmationPS
{
/**
* Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash over the proposal data to identify the contract
* which is being refunded.
*/
struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
/**
* The coin's public key. This is the value that must have been
* signed (blindly) by the Exchange.
*/
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.
*/
uint64_t rtransaction_id GNUNET_PACKED;
/**
* Amount to be refunded, including refund fee charged by the
* exchange to the customer.
*/
struct TALER_AmountNBO refund_amount;
};
/**
* @brief Format of the block signed by the Exchange in response to a successful
* "/refresh/melt" request. Hereby the exchange affirms that all of the
* coins were successfully melted. This also commits the exchange to a
* particular index to not be revealed during the refresh.
*/
struct TALER_RefreshMeltConfirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT. Signed
* by a `struct TALER_ExchangePublicKeyP` using EdDSA.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Commitment made in the /refresh/melt.
*/
struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
/**
* Index that the client will not have to reveal, in NBO.
* Must be smaller than #TALER_CNC_KAPPA.
*/
uint32_t noreveal_index GNUNET_PACKED;
};
/**
* @brief Signature made by the exchange over the full set of keys, used
* to detect cheating exchanges that give out different sets to
* different users.
*/
struct TALER_ExchangeKeySetPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET. Signed
* by a `struct TALER_ExchangePublicKeyP` using EdDSA.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Time of the key set issue.
*/
struct GNUNET_TIME_TimestampNBO list_issue_date;
/**
* Hash over the various denomination signing keys returned.
*/
struct GNUNET_HashCode hc GNUNET_PACKED;
};
/**
* @brief Signature by which an exchange affirms that an account
* successfully passed the KYC checks.
*/
struct TALER_ExchangeAccountSetupSuccessPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS. Signed by a
* `struct TALER_ExchangePublicKeyP` using EdDSA.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash over the payto for which the signature was
* made.
*/
struct TALER_PaytoHashP h_payto;
/**
* When was the signature made.
*/
struct GNUNET_TIME_TimestampNBO timestamp;
};
/**
* @brief Information about a signing key of the exchange. Signing keys are used
* to sign exchange messages other than coins, i.e. to confirm that a
* deposit was successful or that a refresh was accepted.
*/
struct TALER_ExchangeSigningKeyValidityPS
{
/**
* Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When does this signing key begin to be valid?
*/
struct GNUNET_TIME_TimestampNBO start;
/**
* When does this signing key expire? Note: This is currently when
* the Exchange will definitively stop using it. Signatures made with
* the key remain valid until @e end. When checking validity periods,
* clients should allow for some overlap between keys and tolerate
* the use of either key during the overlap time (due to the
* possibility of clock skew).
*/
struct GNUNET_TIME_TimestampNBO expire;
/**
* When do signatures with this signing key become invalid? After
* this point, these signatures cannot be used in (legal) disputes
* anymore, as the Exchange is then allowed to destroy its side of the
* evidence. @e end is expected to be significantly larger than @e
* expire (by a year or more).
*/
struct GNUNET_TIME_TimestampNBO end;
/**
* The public online signing key that the exchange will use
* between @e start and @e expire.
*/
struct TALER_ExchangePublicKeyP signkey_pub;
};
/**
* @brief Information about a denomination key. Denomination keys
* are used to sign coins of a certain value into existence.
*/
struct TALER_DenominationKeyValidityPS
{
/**
* Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* The long-term offline master key of the exchange that was
* used to create @e signature.
*/
struct TALER_MasterPublicKeyP master;
/**
* Start time of the validity period for this key.
*/
struct GNUNET_TIME_TimestampNBO start;
/**
* The exchange will sign fresh coins between @e start and this time.
* @e expire_withdraw will be somewhat larger than @e start to
* ensure a sufficiently large anonymity set, while also allowing
* the Exchange to limit the financial damage in case of a key being
* compromised. Thus, exchanges with low volume are expected to have a
* longer withdraw period (@e expire_withdraw - @e start) than exchanges
* with high transaction volume. The period may also differ between
* types of coins. A exchange may also have a few denomination keys
* with the same value with overlapping validity periods, to address
* issues such as clock skew.
*/
struct GNUNET_TIME_TimestampNBO expire_withdraw;
/**
* Coins signed with the denomination key must be spent or refreshed
* between @e start and this expiration time. After this time, the
* exchange will refuse transactions involving this key as it will
* "drop" the table with double-spending information (shortly after)
* this time. Note that wallets should refresh coins significantly
* before this time to be on the safe side. @e expire_deposit must be
* significantly larger than @e expire_withdraw (by months or even
* years).
*/
struct GNUNET_TIME_TimestampNBO expire_deposit;
/**
* When do signatures with this denomination key become invalid?
* After this point, these signatures cannot be used in (legal)
* disputes anymore, as the Exchange is then allowed to destroy its side
* of the evidence. @e expire_legal is expected to be significantly
* larger than @e expire_deposit (by a year or more).
*/
struct GNUNET_TIME_TimestampNBO expire_legal;
/**
* The value of the coins signed with this denomination key.
*/
struct TALER_AmountNBO value;
/**
* Fees for the coin.
*/
struct TALER_DenomFeeSetNBOP fees;
/**
* Hash code of the denomination public key. (Used to avoid having
* the variable-size RSA key in this struct.)
*/
struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
};
/**
* @brief Information signed by an auditor affirming
* the master public key and the denomination keys
* of a exchange.
*/
struct TALER_ExchangeKeyValidityPS
{
/**
* Purpose is #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash of the auditor's URL (including 0-terminator).
*/
struct GNUNET_HashCode auditor_url_hash;
/**
* The long-term offline master key of the exchange, affirmed by the
* auditor.
*/
struct TALER_MasterPublicKeyP master;
/**
* Start time of the validity period for this key.
*/
struct GNUNET_TIME_TimestampNBO start;
/**
* The exchange will sign fresh coins between @e start and this time.
* @e expire_withdraw will be somewhat larger than @e start to
* ensure a sufficiently large anonymity set, while also allowing
* the Exchange to limit the financial damage in case of a key being
* compromised. Thus, exchanges with low volume are expected to have a
* longer withdraw period (@e expire_withdraw - @e start) than exchanges
* with high transaction volume. The period may also differ between
* types of coins. A exchange may also have a few denomination keys
* with the same value with overlapping validity periods, to address
* issues such as clock skew.
*/
struct GNUNET_TIME_TimestampNBO expire_withdraw;
/**
* Coins signed with the denomination key must be spent or refreshed
* between @e start and this expiration time. After this time, the
* exchange will refuse transactions involving this key as it will
* "drop" the table with double-spending information (shortly after)
* this time. Note that wallets should refresh coins significantly
* before this time to be on the safe side. @e expire_deposit must be
* significantly larger than @e expire_withdraw (by months or even
* years).
*/
struct GNUNET_TIME_TimestampNBO expire_deposit;
/**
* When do signatures with this denomination key become invalid?
* After this point, these signatures cannot be used in (legal)
* disputes anymore, as the Exchange is then allowed to destroy its side
* of the evidence. @e expire_legal is expected to be significantly
* larger than @e expire_deposit (by a year or more).
*/
struct GNUNET_TIME_TimestampNBO expire_legal;
/**
* The value of the coins signed with this denomination key.
*/
struct TALER_AmountNBO value;
/**
* Fees for the coin.
*/
struct TALER_DenomFeeSetNBOP fees;
/**
* Hash code of the denomination public key. (Used to avoid having
* the variable-size RSA key in this struct.)
*/
struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
};
/**
* @brief Format used to generate the signature on a request to obtain
@ -867,81 +406,6 @@ struct TALER_DepositTrackPS
};
/**
* @brief Format internally used for packing the detailed information
* to generate the signature for /track/transfer signatures.
*/
struct TALER_WireDepositDetailP
{
/**
* Hash of the contract
*/
struct TALER_PrivateContractHashP h_contract_terms;
/**
* Time when the wire transfer was performed by the exchange.
*/
struct GNUNET_TIME_TimestampNBO execution_time;
/**
* Coin's public key.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
* Total value of the coin.
*/
struct TALER_AmountNBO deposit_value;
/**
* Fees charged by the exchange for the deposit.
*/
struct TALER_AmountNBO deposit_fee;
};
/**
* @brief Format used to generate the signature for /wire/deposit
* replies.
*/
struct TALER_WireDepositDataPS
{
/**
* Purpose header for the signature over the contract with
* purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Total amount that was transferred.
*/
struct TALER_AmountNBO total;
/**
* Wire fee that was charged.
*/
struct TALER_AmountNBO wire_fee;
/**
* Public key of the merchant (for all aggregated transactions).
*/
struct TALER_MerchantPublicKeyP merchant_pub;
/**
* Hash of bank account of the merchant.
*/
struct TALER_PaytoHashP h_payto;
/**
* Hash of the individual deposits that were aggregated,
* each in the format of a `struct TALER_WireDepositDetailP`.
*/
struct GNUNET_HashCode h_details;
};
/**
* The contract sent by the merchant to the wallet.
*/
@ -979,231 +443,6 @@ struct TALER_PaymentResponsePS
};
/**
* Details affirmed by the exchange about a wire transfer the exchange
* claims to have done with respect to a deposit operation.
*/
struct TALER_ConfirmWirePS
{
/**
* Purpose header for the signature over the contract with
* purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash over the wiring information of the merchant.
*/
struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
/**
* Hash over the contract for which this deposit is made.
*/
struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
/**
* Raw value (binary encoding) of the wire transfer subject.
*/
struct TALER_WireTransferIdentifierRawP wtid;
/**
* The coin's public key. This is the value that must have been
* signed (blindly) by the Exchange.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
* When did the exchange execute this transfer? Note that the
* timestamp may not be exactly the same on the wire, i.e.
* because the wire has a different timezone or resolution.
*/
struct GNUNET_TIME_TimestampNBO execution_time;
/**
* The contribution of @e coin_pub to the total transfer volume.
* This is the value of the deposit minus the fee.
*/
struct TALER_AmountNBO coin_contribution;
};
/**
* Response by which the exchange affirms that it will
* refund a coin as part of the emergency /recoup
* protocol. The recoup will go back to the bank
* account that created the reserve.
*/
struct TALER_RecoupConfirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When did the exchange receive the recoup request?
* Indirectly determines when the wire transfer is (likely)
* to happen.
*/
struct GNUNET_TIME_TimestampNBO timestamp;
/**
* How much of the coin's value will the exchange transfer?
* (Needed in case the coin was partially spent.)
*/
struct TALER_AmountNBO recoup_amount;
/**
* Public key of the coin.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
* Public key of the reserve that will receive the recoup.
*/
struct TALER_ReservePublicKeyP reserve_pub;
};
/**
* Response by which the exchange affirms that it will refund a refreshed coin
* as part of the emergency /recoup protocol. The recoup will go back to the
* old coin's balance.
*/
struct TALER_RecoupRefreshConfirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When did the exchange receive the recoup request?
* Indirectly determines when the wire transfer is (likely)
* to happen.
*/
struct GNUNET_TIME_TimestampNBO timestamp;
/**
* How much of the coin's value will the exchange transfer?
* (Needed in case the coin was partially spent.)
*/
struct TALER_AmountNBO recoup_amount;
/**
* Public key of the refreshed coin.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
* Public key of the old coin that will receive the recoup.
*/
struct TALER_CoinSpendPublicKeyP old_coin_pub;
};
/**
* Response by which the exchange affirms that it does not
* currently know a denomination by the given hash.
*/
struct TALER_DenominationUnknownAffirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When did the exchange sign this message.
*/
struct GNUNET_TIME_TimestampNBO timestamp;
/**
* Hash of the public denomination key we do not know.
*/
struct TALER_DenominationHashP h_denom_pub;
};
/**
* Response by which the exchange affirms that it does not
* currently consider the given denomination to be valid
* for the requested operation.
*/
struct TALER_DenominationExpiredAffirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When did the exchange sign this message.
*/
struct GNUNET_TIME_TimestampNBO timestamp;
/**
* Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s.
*/
char operation[8];
/**
* Hash of the public denomination key we do not know.
*/
struct TALER_DenominationHashP h_denom_pub;
};
/**
* Response by which the exchange affirms that it has
* closed a reserve and send back the funds.
*/
struct TALER_ReserveCloseConfirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When did the exchange initiate the wire transfer.
*/
struct GNUNET_TIME_TimestampNBO timestamp;
/**
* How much did the exchange send?
*/
struct TALER_AmountNBO closing_amount;
/**
* How much did the exchange charge for closing the reserve?
*/
struct TALER_AmountNBO closing_fee;
/**
* Public key of the reserve that received the recoup.
*/
struct TALER_ReservePublicKeyP reserve_pub;
/**
* Hash of the receiver's bank account.
*/
struct TALER_PaytoHashP h_payto;
/**
* Wire transfer subject.
*/
struct TALER_WireTransferIdentifierRawP wtid;
};
GNUNET_NETWORK_STRUCT_END
#endif

View File

@ -188,17 +188,18 @@ verify_signatures (const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_MasterSignatureP *master_sig)
{
if (GNUNET_OK !=
TALER_exchange_deposit_confirm_verify (h_contract_terms,
h_wire,
h_extensions,
exchange_timestamp,
wire_deadline,
refund_deadline,
amount_without_fee,
coin_pub,
merchant_pub,
exchange_pub,
exchange_sig))
TALER_exchange_online_deposit_confirmation_verify (
h_contract_terms,
h_wire,
h_extensions,
exchange_timestamp,
wire_deadline,
refund_deadline,
amount_without_fee,
coin_pub,
merchant_pub,
exchange_pub,
exchange_sig))
{
GNUNET_break_op (0);
TALER_LOG_WARNING (

View File

@ -219,18 +219,16 @@ TALER_EXCHANGE_parse_reserve_history (
else if (0 == strcasecmp (type,
"RECOUP"))
{
struct TALER_RecoupConfirmationPS pc;
struct GNUNET_TIME_Timestamp timestamp;
const struct TALER_EXCHANGE_Keys *key_state;
struct GNUNET_JSON_Specification recoup_spec[] = {
GNUNET_JSON_spec_fixed_auto ("coin_pub",
&pc.coin_pub),
&rh->details.recoup_details.coin_pub),
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
&rh->details.recoup_details.exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
&rh->details.recoup_details.exchange_pub),
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
&pc.timestamp),
GNUNET_JSON_spec_timestamp ("timestamp",
&rh->details.recoup_details.timestamp),
GNUNET_JSON_spec_end ()
};
@ -244,15 +242,6 @@ TALER_EXCHANGE_parse_reserve_history (
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
rh->details.recoup_details.coin_pub = pc.coin_pub;
TALER_amount_hton (&pc.recoup_amount,
&amount);
pc.purpose.size = htonl (sizeof (pc));
pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP);
pc.reserve_pub = *reserve_pub;
timestamp = GNUNET_TIME_timestamp_ntoh (pc.timestamp);
rh->details.recoup_details.timestamp = timestamp;
key_state = TALER_EXCHANGE_get_keys (exchange);
if (GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (key_state,
@ -263,11 +252,13 @@ TALER_EXCHANGE_parse_reserve_history (
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
&pc,
&rh->details.recoup_details.exchange_sig.eddsa_signature,
&rh->details.recoup_details.exchange_pub.eddsa_pub))
TALER_exchange_online_confirm_recoup_verify (
rh->details.recoup_details.timestamp,
&amount,
&rh->details.recoup_details.coin_pub,
reserve_pub,
&rh->details.recoup_details.exchange_pub,
&rh->details.recoup_details.exchange_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@ -287,8 +278,6 @@ TALER_EXCHANGE_parse_reserve_history (
"CLOSING"))
{
const struct TALER_EXCHANGE_Keys *key_state;
struct TALER_ReserveCloseConfirmationPS rcc;
struct GNUNET_TIME_Timestamp timestamp;
struct GNUNET_JSON_Specification closing_spec[] = {
GNUNET_JSON_spec_string (
"receiver_account_details",
@ -299,10 +288,10 @@ TALER_EXCHANGE_parse_reserve_history (
&rh->details.close_details.exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
&rh->details.close_details.exchange_pub),
TALER_JSON_spec_amount_any_nbo ("closing_fee",
&rcc.closing_fee),
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
&rcc.timestamp),
TALER_JSON_spec_amount_any ("closing_fee",
&rh->details.close_details.fee),
GNUNET_JSON_spec_timestamp ("timestamp",
&rh->details.close_details.timestamp),
GNUNET_JSON_spec_end ()
};
@ -316,33 +305,26 @@ TALER_EXCHANGE_parse_reserve_history (
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
TALER_amount_hton (&rcc.closing_amount,
&amount);
TALER_payto_hash (rh->details.close_details.receiver_account_details,
&rcc.h_payto);
rcc.wtid = rh->details.close_details.wtid;
rcc.purpose.size = htonl (sizeof (rcc));
rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
rcc.reserve_pub = *reserve_pub;
timestamp = GNUNET_TIME_timestamp_ntoh (rcc.timestamp);
rh->details.close_details.timestamp = timestamp;
TALER_amount_ntoh (&rh->details.close_details.fee,
&rcc.closing_fee);
key_state = TALER_EXCHANGE_get_keys (exchange);
if (GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (key_state,
&rh->details.close_details.
exchange_pub))
TALER_EXCHANGE_test_signing_key (
key_state,
&rh->details.close_details.exchange_pub))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
&rcc,
&rh->details.close_details.exchange_sig.eddsa_signature,
&rh->details.close_details.exchange_pub.eddsa_pub))
TALER_exchange_online_reserve_closed_verify (
rh->details.close_details.timestamp,
&amount,
&rh->details.close_details.fee,
rh->details.close_details.receiver_account_details,
&rh->details.close_details.wtid,
reserve_pub,
&rh->details.close_details.exchange_pub,
&rh->details.close_details.exchange_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@ -671,35 +653,29 @@ TALER_EXCHANGE_verify_coin_history (
else if (0 == strcasecmp (type,
"RECOUP"))
{
struct TALER_RecoupConfirmationPS pc = {
.purpose.size = htonl (sizeof (pc)),
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
.coin_pub = *coin_pub
};
struct TALER_ReservePublicKeyP reserve_pub;
struct GNUNET_TIME_Timestamp timestamp;
union TALER_DenominationBlindingKeyP coin_bks;
struct TALER_Amount recoup_amount;
struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_ExchangeSignatureP exchange_sig;
struct TALER_CoinSpendSignatureP coin_sig;
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount_any_nbo ("amount",
&pc.recoup_amount),
TALER_JSON_spec_amount_any ("amount",
&recoup_amount),
&amount),
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
&exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
&exchange_pub),
GNUNET_JSON_spec_fixed_auto ("reserve_pub",
&pc.reserve_pub),
&reserve_pub),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&coin_sig),
GNUNET_JSON_spec_fixed_auto ("coin_blind",
&coin_bks),
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
h_denom_pub),
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
&pc.timestamp),
GNUNET_JSON_spec_timestamp ("timestamp",
&timestamp),
GNUNET_JSON_spec_end ()
};
@ -711,13 +687,14 @@ TALER_EXCHANGE_verify_coin_history (
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
TALER_amount_hton (&pc.recoup_amount,
&amount);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
&pc,
&exchange_sig.eddsa_signature,
&exchange_pub.eddsa_pub))
TALER_exchange_online_confirm_recoup_verify (
timestamp,
&amount,
coin_pub,
&reserve_pub,
&exchange_pub,
&exchange_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@ -738,22 +715,16 @@ TALER_EXCHANGE_verify_coin_history (
{
/* This is the coin that was subjected to a recoup,
the value being credited to the old coin. */
struct TALER_RecoupRefreshConfirmationPS pc = {
.purpose.size = htonl (sizeof (pc)),
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
.coin_pub = *coin_pub
};
struct TALER_CoinSpendPublicKeyP old_coin_pub;
union TALER_DenominationBlindingKeyP coin_bks;
struct TALER_Amount recoup_amount;
struct TALER_Amount amount;
struct GNUNET_TIME_Timestamp timestamp;
struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_ExchangeSignatureP exchange_sig;
struct TALER_CoinSpendSignatureP coin_sig;
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount_any_nbo ("amount",
&pc.recoup_amount),
TALER_JSON_spec_amount_any ("amount",
&recoup_amount),
&amount),
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
&exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
@ -761,13 +732,13 @@ TALER_EXCHANGE_verify_coin_history (
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&coin_sig),
GNUNET_JSON_spec_fixed_auto ("old_coin_pub",
&pc.old_coin_pub),
&old_coin_pub),
GNUNET_JSON_spec_fixed_auto ("coin_blind",
&coin_bks),
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
h_denom_pub),
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
&pc.timestamp),
GNUNET_JSON_spec_timestamp ("timestamp",
&timestamp),
GNUNET_JSON_spec_end ()
};
@ -779,14 +750,14 @@ TALER_EXCHANGE_verify_coin_history (
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
TALER_amount_hton (&pc.recoup_amount,
&amount);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
&pc,
&exchange_sig.eddsa_signature,
&exchange_pub.eddsa_pub))
TALER_exchange_online_confirm_recoup_refresh_verify (
timestamp,
&amount,
coin_pub,
&old_coin_pub,
&exchange_pub,
&exchange_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@ -807,25 +778,21 @@ TALER_EXCHANGE_verify_coin_history (
{
/* This is the coin that was credited in a recoup,
the value being credited to the this coin. */
struct TALER_RecoupRefreshConfirmationPS pc = {
.purpose.size = htonl (sizeof (pc)),
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
.old_coin_pub = *coin_pub
};
struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_ExchangeSignatureP exchange_sig;
struct TALER_CoinSpendPublicKeyP new_coin_pub;
struct GNUNET_TIME_Timestamp timestamp;
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount_any_nbo ("amount",
&pc.recoup_amount),
TALER_JSON_spec_amount_any ("amount",
&amount),
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
&exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
&exchange_pub),
GNUNET_JSON_spec_fixed_auto ("coin_pub",
&pc.coin_pub),
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
&pc.timestamp),
&new_coin_pub),
GNUNET_JSON_spec_timestamp ("timestamp",
&timestamp),
GNUNET_JSON_spec_end ()
};
@ -837,14 +804,14 @@ TALER_EXCHANGE_verify_coin_history (
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
TALER_amount_hton (&pc.recoup_amount,
&amount);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
&pc,
&exchange_sig.eddsa_signature,
&exchange_pub.eddsa_pub))
TALER_exchange_online_confirm_recoup_refresh_verify (
timestamp,
&amount,
&new_coin_pub,
coin_pub,
&exchange_pub,
&exchange_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;

View File

@ -361,17 +361,18 @@ handle_deposit_finished (void *cls,
}
if (GNUNET_OK !=
TALER_exchange_deposit_confirm_verify (&dh->h_contract_terms,
&dh->h_wire,
&dh->h_extensions,
dh->exchange_timestamp,
dh->wire_deadline,
dh->refund_deadline,
&dh->amount_without_fee,
&dh->coin_pub,
&dh->merchant_pub,
&dh->exchange_pub,
&dh->exchange_sig))
TALER_exchange_online_deposit_confirmation_verify (
&dh->h_contract_terms,
&dh->h_wire,
&dh->h_extensions,
dh->exchange_timestamp,
dh->wire_deadline,
dh->refund_deadline,
&dh->amount_without_fee,
&dh->coin_pub,
&dh->merchant_pub,
&dh->exchange_pub,
&dh->exchange_sig))
{
GNUNET_break_op (0);
dr.hr.http_status = 0;

View File

@ -70,10 +70,38 @@ struct TALER_EXCHANGE_DepositGetHandle
void *cb_cls;
/**
* Information the exchange should sign in response.
* (with pre-filled fields from the request).
* Hash over the wiring information of the merchant.
*/
struct TALER_ConfirmWirePS depconf;
struct TALER_MerchantWireHashP h_wire;
/**
* Hash over the contract for which this deposit is made.
*/
struct TALER_PrivateContractHashP h_contract_terms;
/**
* Raw value (binary encoding) of the wire transfer subject.
*/
struct TALER_WireTransferIdentifierRawP wtid;
/**
* The coin's public key. This is the value that must have been
* signed (blindly) by the Exchange.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
* When did the exchange execute this transfer? Note that the
* timestamp may not be exactly the same on the wire, i.e.
* because the wire has a different timezone or resolution.
*/
struct GNUNET_TIME_Timestamp execution_time;
/**
* The contribution of @e coin_pub to the total transfer volume.
* This is the value of the deposit minus the fee.
*/
struct TALER_Amount coin_contribution;
};
@ -87,6 +115,7 @@ struct TALER_EXCHANGE_DepositGetHandle
* @param exchange_sig the exchange's signature
* @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
*/
// FIXME: inline...
static enum GNUNET_GenericReturnValue
verify_deposit_wtid_signature_ok (
const struct TALER_EXCHANGE_DepositGetHandle *dwh,
@ -104,10 +133,15 @@ verify_deposit_wtid_signature_ok (
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE,
&dwh->depconf,
&exchange_sig->eddsa_signature,
&exchange_pub->eddsa_pub))
TALER_exchange_online_confirm_wire_verify (
&dwh->h_wire,
&dwh->h_contract_terms,
&dwh->wtid,
&dwh->coin_pub,
dwh->execution_time,
&dwh->coin_contribution,
exchange_pub,
exchange_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@ -168,11 +202,10 @@ handle_deposit_wtid_finished (void *cls,
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
break;
}
dwh->depconf.execution_time = GNUNET_TIME_timestamp_hton (
dr.details.success.execution_time);
dwh->depconf.wtid = dr.details.success.wtid;
TALER_amount_hton (&dwh->depconf.coin_contribution,
&dr.details.success.coin_contribution);
// FIXME: remove once we inline function below...
dwh->execution_time = dr.details.success.execution_time;
dwh->wtid = dr.details.success.wtid;
dwh->coin_contribution = dr.details.success.coin_contribution;
if (GNUNET_OK !=
verify_deposit_wtid_signature_ok (dwh,
&dr.details.success.exchange_pub,
@ -285,6 +318,7 @@ TALER_EXCHANGE_deposits_get (
GNUNET_break (0);
return NULL;
}
// FIXME: move to helper!
dtp.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION);
dtp.purpose.size = htonl (sizeof (dtp));
dtp.h_contract_terms = *h_contract_terms;
@ -351,11 +385,9 @@ TALER_EXCHANGE_deposits_get (
GNUNET_free (dwh);
return NULL;
}
dwh->depconf.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS));
dwh->depconf.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE);
dwh->depconf.h_wire = *h_wire;
dwh->depconf.h_contract_terms = *h_contract_terms;
dwh->depconf.coin_pub = *coin_pub;
dwh->h_wire = *h_wire;
dwh->h_contract_terms = *h_contract_terms;
dwh->coin_pub = *coin_pub;
eh = TALER_EXCHANGE_curl_easy_get_ (dwh->url);
if (NULL == eh)

View File

@ -1136,11 +1136,7 @@ decode_keys_json (const json_t *resp_obj,
if (check_sig)
{
struct TALER_ExchangeKeySetPS ks = {
.purpose.size = htonl (sizeof (ks)),
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
.list_issue_date = GNUNET_TIME_timestamp_hton (key_data->list_issue_date)
};
struct GNUNET_HashCode hc;
/* If we had any age restricted denominations, add their hash to the end of
* the normal denominations. */
@ -1160,16 +1156,18 @@ decode_keys_json (const json_t *resp_obj,
}
GNUNET_CRYPTO_hash_context_finish (hash_context,
&ks.hc);
&hc);
hash_context = NULL;
EXITIF (GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (key_data,
&pub));
EXITIF (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
&ks,
&sig.eddsa_signature,
&pub.eddsa_pub));
TALER_exchange_online_key_set_verify (
key_data->list_issue_date,
&hc,
&pub,
&sig));
}
return GNUNET_OK;
EXITIF_exit:

View File

@ -105,12 +105,6 @@ handle_kyc_check_finished (void *cls,
GNUNET_JSON_spec_end ()
};
const struct TALER_EXCHANGE_Keys *key_state;
struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = {
.purpose.size = htonl (sizeof (kyc_purpose)),
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
.h_payto = kch->h_payto
};
if (GNUNET_OK !=
GNUNET_JSON_parse (j,
@ -122,8 +116,6 @@ handle_kyc_check_finished (void *cls,
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
}
kyc_purpose.timestamp = GNUNET_TIME_timestamp_hton (
ks.details.kyc_ok.timestamp);
key_state = TALER_EXCHANGE_get_keys (kch->exchange);
if (GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (key_state,
@ -137,11 +129,11 @@ handle_kyc_check_finished (void *cls,
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS,
&kyc_purpose,
&ks.details.kyc_ok.exchange_sig.eddsa_signature,
&ks.details.kyc_ok.exchange_pub.eddsa_pub))
TALER_exchange_online_account_setup_success_verify (
&kch->h_payto,
ks.details.kyc_ok.timestamp,
&ks.details.kyc_ok.exchange_pub,
&ks.details.kyc_ok.exchange_sig))
{
GNUNET_break_op (0);
ks.http_status = 0;

View File

@ -170,7 +170,7 @@ verify_melt_signature_ok (struct TALER_EXCHANGE_MeltHandle *mh,
}
if (GNUNET_OK !=
TALER_exchange_melt_confirmation_verify (
TALER_exchange_online_melt_confirmation_verify (
&mh->md.rc,
mh->noreveal_index,
exchange_pub,

View File

@ -70,9 +70,33 @@ struct TALER_EXCHANGE_RefundHandle
void *cb_cls;
/**
* Information the exchange should sign in response.
* Hash over the proposal data to identify the contract
* which is being refunded.
*/
struct TALER_RefundConfirmationPS depconf;
struct TALER_PrivateContractHashP h_contract_terms;
/**
* The coin's public key. This is the value that must have been
* signed (blindly) by the Exchange.
*/
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.
*/
uint64_t rtransaction_id;
/**
* Amount to be refunded, including refund fee charged by the
* exchange to the customer.
*/
struct TALER_Amount refund_amount;
};
@ -119,10 +143,14 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh,
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
&rh->depconf,
&exchange_sig->eddsa_signature,
&exchange_pub->eddsa_pub))
TALER_exchange_online_refund_confirmation_verify (
&rh->h_contract_terms,
&rh->coin_pub,
&rh->merchant,
rh->rtransaction_id,
&rh->refund_amount,
exchange_pub,
exchange_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@ -253,16 +281,16 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
wallet_timestamp,
&merchant_pub,
refund_deadline,
&rh->depconf.coin_pub,
&rh->coin_pub,
&sig))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
if ( (0 != GNUNET_memcmp (&rh->h_contract_terms,
&h_contract_terms)) ||
(0 != GNUNET_memcmp (&rh->depconf.merchant,
(0 != GNUNET_memcmp (&rh->merchant,
&merchant_pub)) )
{
/* deposit information is about a different merchant/contract */
@ -334,7 +362,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
TALER_merchant_refund_verify (&rh->depconf.coin_pub,
TALER_merchant_refund_verify (&rh->coin_pub,
&h_contract_terms,
rtransaction_id,
&sig_amount,
@ -345,9 +373,9 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
if ( (0 != GNUNET_memcmp (&rh->h_contract_terms,
&h_contract_terms)) ||
(0 != GNUNET_memcmp (&rh->depconf.merchant,
(0 != GNUNET_memcmp (&rh->merchant,
&merchant_pub)) )
{
/* refund is about a different merchant/contract */
@ -355,7 +383,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
if (rtransaction_id == rh->depconf.rtransaction_id)
if (rtransaction_id == rh->rtransaction_id)
{
/* Eh, this shows either a dependency failure or idempotency,
but must not happen in a conflict reply. Fail! */
@ -398,16 +426,12 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
}
{
struct TALER_Amount amount;
TALER_amount_ntoh (&amount,
&rh->depconf.refund_amount);
if (have_refund)
{
if (0 >
TALER_amount_add (&rtotal,
&rtotal,
&amount))
&rh->refund_amount))
{
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
@ -416,7 +440,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
}
else
{
rtotal = amount;
rtotal = rh->refund_amount;
}
}
if (-1 == TALER_amount_cmp (&dtotal,
@ -472,7 +496,6 @@ 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;
@ -507,7 +530,7 @@ verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh,
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
TALER_merchant_refund_verify (&rh->depconf.coin_pub,
TALER_merchant_refund_verify (&rh->coin_pub,
&h_contract_terms,
rtransaction_id,
&amount,
@ -518,14 +541,12 @@ verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh,
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
TALER_amount_ntoh (&depconf_amount,
&rh->depconf.refund_amount);
if ( (rtransaction_id != rh->depconf.rtransaction_id) ||
(0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
if ( (rtransaction_id != rh->rtransaction_id) ||
(0 != GNUNET_memcmp (&rh->h_contract_terms,
&h_contract_terms)) ||
(0 != GNUNET_memcmp (&rh->depconf.merchant,
(0 != GNUNET_memcmp (&rh->merchant,
&merchant_pub)) ||
(0 == TALER_amount_cmp (&depconf_amount,
(0 == TALER_amount_cmp (&rh->refund_amount,
&amount)) )
{
GNUNET_break_op (0);
@ -669,15 +690,15 @@ handle_refund_finished (void *cls,
struct TALER_EXCHANGE_RefundHandle *
TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount,
const struct
TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
TALER_EXCHANGE_RefundCallback cb,
void *cb_cls)
TALER_EXCHANGE_refund (
struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount,
const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
TALER_EXCHANGE_RefundCallback cb,
void *cb_cls)
{
struct TALER_MerchantPublicKeyP merchant_pub;
struct TALER_MerchantSignatureP merchant_sig;
@ -735,15 +756,11 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
GNUNET_free (rh);
return NULL;
}
rh->depconf.purpose.size = htonl (sizeof (struct TALER_RefundConfirmationPS));
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 = merchant_pub;
rh->depconf.rtransaction_id = GNUNET_htonll (rtransaction_id);
TALER_amount_hton (&rh->depconf.refund_amount,
amount);
rh->h_contract_terms = *h_contract_terms;
rh->coin_pub = *coin_pub;
rh->merchant = merchant_pub;
rh->rtransaction_id = rtransaction_id;
rh->refund_amount = *amount;
eh = TALER_EXCHANGE_curl_easy_get_ (rh->url);
if ( (NULL == eh) ||
(GNUNET_OK !=

View File

@ -177,43 +177,29 @@ check_transfers_get_response_ok (
return GNUNET_SYSERR;
}
/* build up big hash for signature checking later */
{
struct TALER_WireDepositDetailP dd;
dd.h_contract_terms = detail->h_contract_terms;
dd.execution_time = GNUNET_TIME_timestamp_hton (td.execution_time);
dd.coin_pub = detail->coin_pub;
TALER_amount_hton (&dd.deposit_value,
&detail->coin_value);
TALER_amount_hton (&dd.deposit_fee,
&detail->coin_fee);
GNUNET_CRYPTO_hash_context_read (hash_context,
&dd,
sizeof (dd));
}
TALER_exchange_online_wire_deposit_append (
hash_context,
&detail->h_contract_terms,
td.execution_time,
&detail->coin_pub,
&detail->coin_value,
&detail->coin_fee);
}
/* Check signature */
{
struct TALER_WireDepositDataPS wdp = {
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
.purpose.size = htonl (sizeof (wdp)),
.merchant_pub = merchant_pub,
.h_payto = td.h_payto
};
struct GNUNET_HashCode h_details;
TALER_amount_hton (&wdp.total,
&td.total_amount);
TALER_amount_hton (&wdp.wire_fee,
&td.wire_fee);
GNUNET_CRYPTO_hash_context_finish (hash_context,
&wdp.h_details);
&h_details);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
&wdp,
&td.exchange_sig.eddsa_signature,
&td.exchange_pub.eddsa_pub))
TALER_exchange_online_wire_deposit_verify (
&td.total_amount,
&td.wire_fee,
&merchant_pub,
&td.h_payto,
&h_details,
&td.exchange_pub,
&td.exchange_sig))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
@ -330,16 +316,6 @@ handle_transfers_get_finished (void *cls,
}
/**
* Query the exchange about which transactions were combined
* to create a wire transfer.
*
* @param exchange exchange to query
* @param wtid raw wire transfer identifier to get information about
* @param cb callback to call
* @param cb_cls closure for @a cb
* @return handle to cancel operation
*/
struct TALER_EXCHANGE_TransfersGetHandle *
TALER_EXCHANGE_transfers_get (
struct TALER_EXCHANGE_Handle *exchange,
@ -369,8 +345,7 @@ TALER_EXCHANGE_transfers_get (
char *end;
end = GNUNET_STRINGS_data_to_string (wtid,
sizeof (struct
TALER_WireTransferIdentifierRawP),
sizeof (wtid),
wtid_str,
sizeof (wtid_str));
*end = '\0';

View File

@ -23,6 +23,89 @@
#include "taler_signatures.h"
/**
* @brief Information signed by an auditor affirming
* the master public key and the denomination keys
* of a exchange.
*/
struct TALER_ExchangeKeyValidityPS
{
/**
* Purpose is #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash of the auditor's URL (including 0-terminator).
*/
struct GNUNET_HashCode auditor_url_hash;
/**
* The long-term offline master key of the exchange, affirmed by the
* auditor.
*/
struct TALER_MasterPublicKeyP master;
/**
* Start time of the validity period for this key.
*/
struct GNUNET_TIME_TimestampNBO start;
/**
* The exchange will sign fresh coins between @e start and this time.
* @e expire_withdraw will be somewhat larger than @e start to
* ensure a sufficiently large anonymity set, while also allowing
* the Exchange to limit the financial damage in case of a key being
* compromised. Thus, exchanges with low volume are expected to have a
* longer withdraw period (@e expire_withdraw - @e start) than exchanges
* with high transaction volume. The period may also differ between
* types of coins. A exchange may also have a few denomination keys
* with the same value with overlapping validity periods, to address
* issues such as clock skew.
*/
struct GNUNET_TIME_TimestampNBO expire_withdraw;
/**
* Coins signed with the denomination key must be spent or refreshed
* between @e start and this expiration time. After this time, the
* exchange will refuse transactions involving this key as it will
* "drop" the table with double-spending information (shortly after)
* this time. Note that wallets should refresh coins significantly
* before this time to be on the safe side. @e expire_deposit must be
* significantly larger than @e expire_withdraw (by months or even
* years).
*/
struct GNUNET_TIME_TimestampNBO expire_deposit;
/**
* When do signatures with this denomination key become invalid?
* After this point, these signatures cannot be used in (legal)
* disputes anymore, as the Exchange is then allowed to destroy its side
* of the evidence. @e expire_legal is expected to be significantly
* larger than @e expire_deposit (by a year or more).
*/
struct GNUNET_TIME_TimestampNBO expire_legal;
/**
* The value of the coins signed with this denomination key.
*/
struct TALER_AmountNBO value;
/**
* Fees for the coin.
*/
struct TALER_DenomFeeSetNBOP fees;
/**
* Hash code of the denomination public key. (Used to avoid having
* the variable-size RSA key in this struct.)
*/
struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
};
void
TALER_auditor_denom_validity_sign (
const char *auditor_url,

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,37 @@
#include "taler_signatures.h"
/**
* @brief format used by the signing crypto helper when affirming
* that it created an exchange signing key.
*/
struct TALER_SigningKeyAnnouncementPS
{
/**
* Purpose must be #TALER_SIGNATURE_SM_SIGNING_KEY.
* Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Public signing key of the exchange this is about.
*/
struct TALER_ExchangePublicKeyP exchange_pub;
/**
* When does the key become available?
*/
struct GNUNET_TIME_TimestampNBO anchor_time;
/**
* How long is the key available after @e anchor_time?
*/
struct GNUNET_TIME_RelativeNBO duration;
};
void
TALER_exchange_secmod_eddsa_sign (
const struct TALER_ExchangePublicKeyP *exchange_pub,
@ -69,6 +100,41 @@ TALER_exchange_secmod_eddsa_verify (
}
/**
* @brief format used by the denomination crypto helper when affirming
* that it created a denomination key.
*/
struct TALER_DenominationKeyAnnouncementPS
{
/**
* Purpose must be #TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY.
* Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash of the denomination public key.
*/
struct TALER_DenominationHashP h_denom;
/**
* Hash of the section name in the configuration of this denomination.
*/
struct GNUNET_HashCode h_section_name;
/**
* When does the key become available?
*/
struct GNUNET_TIME_TimestampNBO anchor_time;
/**
* How long is the key available after @e anchor_time?
*/
struct GNUNET_TIME_RelativeNBO duration_withdraw;
};
void
TALER_exchange_secmod_rsa_sign (
const struct TALER_RsaPubHashP *h_rsa,