Compare commits

...

8 Commits

69 changed files with 1300 additions and 781 deletions

@ -1 +1 @@
Subproject commit 832685b6a942a6ebbec8e1e5b8c33b6b85b0a727 Subproject commit b309c93f859f68124f76cef03b35b0143b8331cb

View File

@ -1218,7 +1218,7 @@ static enum GNUNET_GenericReturnValue
refresh_session_cb (void *cls, refresh_session_cb (void *cls,
uint64_t rowid, uint64_t rowid,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *amount_with_fee,

View File

@ -277,7 +277,7 @@ add_deposit (const struct Merchant *m)
struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_EXCHANGEDB_Deposit deposit;
uint64_t known_coin_id; uint64_t known_coin_id;
struct TALER_DenominationHashP dph; struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh; struct TALER_AgeCommitmentHashP agh;
RANDOMIZE (&d.coin.coin_pub); RANDOMIZE (&d.coin.coin_pub);
d.coin.denom_pub_hash = h_denom_pub; d.coin.denom_pub_hash = h_denom_pub;
@ -468,7 +468,7 @@ run (void *cls,
struct TALER_PlanchetMasterSecretP ps; struct TALER_PlanchetMasterSecretP ps;
struct TALER_ExchangeWithdrawValues alg_values; struct TALER_ExchangeWithdrawValues alg_values;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_AgeCommitmentHash hac; struct TALER_AgeCommitmentHashP hac;
union TALER_DenominationBlindingKeyP bks; union TALER_DenominationBlindingKeyP bks;
RANDOMIZE (&coin_pub); RANDOMIZE (&coin_pub);

View File

@ -125,6 +125,7 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_age-withdraw.c taler-exchange-httpd_age-withdraw.h \ taler-exchange-httpd_age-withdraw.c taler-exchange-httpd_age-withdraw.h \
taler-exchange-httpd_age-withdraw_reveal.c taler-exchange-httpd_age-withdraw_reveal.h \ taler-exchange-httpd_age-withdraw_reveal.c taler-exchange-httpd_age-withdraw_reveal.h \
taler-exchange-httpd_auditors.c taler-exchange-httpd_auditors.h \ taler-exchange-httpd_auditors.c taler-exchange-httpd_auditors.h \
taler-exchange-httpd_aml-decision.c taler-exchange-httpd_aml-decision.h \
taler-exchange-httpd_batch-deposit.c taler-exchange-httpd_batch-deposit.h \ taler-exchange-httpd_batch-deposit.c taler-exchange-httpd_batch-deposit.h \
taler-exchange-httpd_batch-withdraw.c taler-exchange-httpd_batch-withdraw.h \ taler-exchange-httpd_batch-withdraw.c taler-exchange-httpd_batch-withdraw.h \
taler-exchange-httpd_common_deposit.c taler-exchange-httpd_common_deposit.h \ taler-exchange-httpd_common_deposit.c taler-exchange-httpd_common_deposit.h \
@ -141,12 +142,14 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_kyc-webhook.c taler-exchange-httpd_kyc-webhook.h \ taler-exchange-httpd_kyc-webhook.c taler-exchange-httpd_kyc-webhook.h \
taler-exchange-httpd_link.c taler-exchange-httpd_link.h \ taler-exchange-httpd_link.c taler-exchange-httpd_link.h \
taler-exchange-httpd_management.h \ taler-exchange-httpd_management.h \
taler-exchange-httpd_management_aml-officers.c \
taler-exchange-httpd_management_auditors.c \ taler-exchange-httpd_management_auditors.c \
taler-exchange-httpd_management_auditors_AP_disable.c \ taler-exchange-httpd_management_auditors_AP_disable.c \
taler-exchange-httpd_management_denominations_HDP_revoke.c \ taler-exchange-httpd_management_denominations_HDP_revoke.c \
taler-exchange-httpd_management_drain.c \ taler-exchange-httpd_management_drain.c \
taler-exchange-httpd_management_extensions.c \ taler-exchange-httpd_management_extensions.c \
taler-exchange-httpd_management_global_fees.c \ taler-exchange-httpd_management_global_fees.c \
taler-exchange-httpd_management_partners.c \
taler-exchange-httpd_management_post_keys.c \ taler-exchange-httpd_management_post_keys.c \
taler-exchange-httpd_management_signkey_EP_revoke.c \ taler-exchange-httpd_management_signkey_EP_revoke.c \
taler-exchange-httpd_management_wire_enable.c \ taler-exchange-httpd_management_wire_enable.c \

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2022 Taler Systems SA Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -30,6 +30,7 @@
#include "taler_kyclogic_lib.h" #include "taler_kyclogic_lib.h"
#include "taler_templating_lib.h" #include "taler_templating_lib.h"
#include "taler_mhd_lib.h" #include "taler_mhd_lib.h"
#include "taler-exchange-httpd_aml-decision.h"
#include "taler-exchange-httpd_auditors.h" #include "taler-exchange-httpd_auditors.h"
#include "taler-exchange-httpd_batch-deposit.h" #include "taler-exchange-httpd_batch-deposit.h"
#include "taler-exchange-httpd_batch-withdraw.h" #include "taler-exchange-httpd_batch-withdraw.h"
@ -322,6 +323,187 @@ handle_post_coins (struct TEH_RequestContext *rc,
} }
/**
* Signature of functions that handle operations
* authorized by AML officers.
*
* @param rc request context
* @param officer_pub the public key of the AML officer
* @param root uploaded JSON data
* @return MHD result code
*/
typedef MHD_RESULT
(*AmlOpPostHandler)(struct TEH_RequestContext *rc,
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
const json_t *root);
/**
* Handle a "/aml/$OFFICER_PUB/$OP" POST request. Parses the "officer_pub"
* EdDSA key of the officer and demultiplexes based on $OP.
*
* @param rc request context
* @param root uploaded JSON data
* @param args array of additional options
* @return MHD result code
*/
static MHD_RESULT
handle_post_aml (struct TEH_RequestContext *rc,
const json_t *root,
const char *const args[2])
{
struct TALER_AmlOfficerPublicKeyP officer_pub;
static const struct
{
/**
* Name of the operation (args[1])
*/
const char *op;
/**
* Function to call to perform the operation.
*/
AmlOpPostHandler handler;
} h[] = {
{
.op = "decision",
.handler = &TEH_handler_post_aml_decision
},
{
.op = NULL,
.handler = NULL
},
};
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&officer_pub,
sizeof (officer_pub)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_PUB_MALFORMED,
args[0]);
}
for (unsigned int i = 0; NULL != h[i].op; i++)
if (0 == strcmp (h[i].op,
args[1]))
return h[i].handler (rc,
&officer_pub,
root);
return r404 (rc->connection,
args[1]);
}
/**
* Signature of functions that handle operations
* authorized by AML officers.
*
* @param rc request context
* @param officer_pub the public key of the AML officer
* @param args remaining arguments
* @return MHD result code
*/
typedef MHD_RESULT
(*AmlOpGetHandler)(struct TEH_RequestContext *rc,
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
const char *const args[]);
/**
* Handle a "/aml/$OFFICER_PUB/$OP" GET request. Parses the "officer_pub"
* EdDSA key of the officer, checks the authentication signature, and
* demultiplexes based on $OP.
*
* @param rc request context
* @param args array of additional options
* @return MHD result code
*/
static MHD_RESULT
handle_get_aml (struct TEH_RequestContext *rc,
const char *const args[])
{
struct TALER_AmlOfficerPublicKeyP officer_pub;
static const struct
{
/**
* Name of the operation (args[1])
*/
const char *op;
/**
* Function to call to perform the operation.
*/
AmlOpGetHandler handler;
} h[] = {
#if FIXME_AML_GET_DECISIONS_NOT_IMPLEMENTED
{
.op = "decisions",
.handler = &TEH_handler_get_aml_decisions
},
{
.op = "decision",
.handler = &TEH_handler_get_aml_decision
},
#endif
{
.op = NULL,
.handler = NULL
},
};
if (NULL == args[0])
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_PUB_MALFORMED,
"argument missing");
}
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&officer_pub,
sizeof (officer_pub)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_PUB_MALFORMED,
args[0]);
}
if (NULL == args[1])
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS,
"AML GET operations must specify an operation identifier");
}
if (1) // FIXME: check AML officer GET signature!
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_FORBIDDEN,
TALER_EC_EXCHANGE_GENERIC_AML_OFFICER_GET_SIGNATURE_INVALID,
NULL);
}
for (unsigned int i = 0; NULL != h[i].op; i++)
if (0 == strcmp (h[i].op,
args[1]))
return h[i].handler (rc,
&officer_pub,
&args[2]);
return r404 (rc->connection,
args[1]);
}
/** /**
* Signature of functions that handle operations on reserves. * Signature of functions that handle operations on reserves.
* *
@ -890,6 +1072,8 @@ handle_post_management (struct TEH_RequestContext *rc,
&exchange_pub, &exchange_pub,
root); root);
} }
/* FIXME-STYLE: all of the following can likely be nicely combined
into an array-based dispatcher to deduplicate the logic... */
if (0 == strcmp (args[0], if (0 == strcmp (args[0],
"keys")) "keys"))
{ {
@ -967,6 +1151,30 @@ handle_post_management (struct TEH_RequestContext *rc,
return TEH_handler_management_post_drain (rc->connection, return TEH_handler_management_post_drain (rc->connection,
root); root);
} }
if (0 == strcmp (args[0],
"aml-officers"))
{
if (NULL != args[1])
{
GNUNET_break_op (0);
return r404 (rc->connection,
"/management/aml-officers/*");
}
return TEH_handler_management_aml_officers (rc->connection,
root);
}
if (0 == strcmp (args[0],
"partners"))
{
if (NULL != args[1])
{
GNUNET_break_op (0);
return r404 (rc->connection,
"/management/partners/*");
}
return TEH_handler_management_partners (rc->connection,
root);
}
GNUNET_break_op (0); GNUNET_break_op (0);
return r404 (rc->connection, return r404 (rc->connection,
"/management/*"); "/management/*");
@ -1289,6 +1497,22 @@ handle_mhd_request (void *cls,
.nargs = 4, .nargs = 4,
.nargs_is_upper_bound = true .nargs_is_upper_bound = true
}, },
/* AML endpoints */
{
.url = "aml",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &handle_get_aml,
.nargs = 4,
.nargs_is_upper_bound = true
},
{
.url = "aml",
.method = MHD_HTTP_METHOD_POST,
.handler.post = &handle_post_aml,
.nargs = 2
},
/* mark end of list */ /* mark end of list */
{ {
.url = NULL .url = NULL

View File

@ -213,7 +213,7 @@ struct TEH_RequestHandler
* *
* @param rc context for the request * @param rc context for the request
* @param json uploaded JSON data * @param json uploaded JSON data
* @param args array of arguments, needs to be of length @e args_expected * @param args array of arguments, needs to be of length @e nargs
* @return MHD result code * @return MHD result code
*/ */
MHD_RESULT MHD_RESULT
@ -225,7 +225,7 @@ struct TEH_RequestHandler
* Function to call to handle DELETE requests. * Function to call to handle DELETE requests.
* *
* @param rc context for the request * @param rc context for the request
* @param args array of arguments, needs to be of length @e args_expected * @param args array of arguments, needs to be of length @e nargs
* @return MHD result code * @return MHD result code
*/ */
MHD_RESULT MHD_RESULT

View File

@ -46,30 +46,27 @@ reply_age_withdraw_success (struct MHD_Connection *connection,
{ {
struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig; struct TALER_ExchangeSignatureP sig;
enum TALER_ErrorCode ec; enum TALER_ErrorCode ec =
TALER_exchange_online_age_withdraw_confirmation_sign (
&TEH_keys_exchange_sign_,
ach,
noreveal_index,
&pub,
&sig);
if (TALER_EC_NONE != if (TALER_EC_NONE != ec)
(ec = TALER_exchange_online_age_withdraw_confirmation_sign (
&TEH_keys_exchange_sign_,
ach,
noreveal_index,
&pub,
&sig)))
{
return TALER_MHD_reply_with_ec (connection, return TALER_MHD_reply_with_ec (connection,
ec, ec,
NULL); NULL);
}
return TALER_MHD_REPLY_JSON_PACK ( return TALER_MHD_REPLY_JSON_PACK (connection,
connection, MHD_HTTP_OK,
MHD_HTTP_OK, GNUNET_JSON_pack_uint64 ("noreveal_index",
GNUNET_JSON_pack_uint64 ("noreveal_index", noreveal_index),
noreveal_index), GNUNET_JSON_pack_data_auto ("exchange_sig",
GNUNET_JSON_pack_data_auto ("exchange_sig", &sig),
&sig), GNUNET_JSON_pack_data_auto ("exchange_pub",
GNUNET_JSON_pack_data_auto ("exchange_pub", &pub));
&pub));
} }
@ -84,7 +81,12 @@ struct AgeWithdrawContext
struct TALER_EXCHANGEDB_KycStatus kyc; struct TALER_EXCHANGEDB_KycStatus kyc;
/** /**
* The commitment request, for n*kappa coins. * Hash of the wire source URL, needed when kyc is needed.
*/
struct TALER_PaytoHashP h_payto;
/**
* The data from the age-withdraw request
*/ */
struct TALER_EXCHANGEDB_AgeWithdrawCommitment commitment; struct TALER_EXCHANGEDB_AgeWithdrawCommitment commitment;
@ -95,7 +97,6 @@ struct AgeWithdrawContext
}; };
#if 0
/** /**
* Function called to iterate over KYC-relevant * Function called to iterate over KYC-relevant
* transaction amounts for a particular time range. * transaction amounts for a particular time range.
@ -112,28 +113,27 @@ struct AgeWithdrawContext
* @param cb_cls closure for @a cb * @param cb_cls closure for @a cb
*/ */
static void static void
withdraw_amount_cb (void *cls, age_withdraw_amount_cb (void *cls,
struct GNUNET_TIME_Absolute limit, struct GNUNET_TIME_Absolute limit,
TALER_EXCHANGEDB_KycAmountCallback cb, TALER_EXCHANGEDB_KycAmountCallback cb,
void *cb_cls) void *cb_cls)
{ {
struct AgeWithdrawContext *awc = cls; struct AgeWithdrawContext *awc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Signaling amount %s for KYC check during age-withdrawal\n", "Signaling amount %s for KYC check during age-withdrawal\n",
TALER_amount2s (&awc->amount_with_fee)); TALER_amount2s (&awc->commitment.amount_with_fee));
if (GNUNET_OK != if (GNUNET_OK !=
cb (cb_cls, cb (cb_cls,
&awc->amount_with_fee, &awc->commitment.amount_with_fee,
awc->now.abs_time)) awc->now.abs_time))
return; return;
qs = TEH_plugin->select_withdraw_amounts_for_kyc_check ( qs = TEH_plugin->select_withdraw_amounts_for_kyc_check (TEH_plugin->cls,
TEH_plugin->cls, &awc->h_payto,
&wc->h_payto, limit,
limit, cb,
cb, cb_cls);
cb_cls);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Got %d additional transactions for this age-withdrawal and limit %llu\n", "Got %d additional transactions for this age-withdrawal and limit %llu\n",
qs, qs,
@ -142,12 +142,7 @@ withdraw_amount_cb (void *cls,
} }
#endif
#if 0
/** /**
* TODO: REWRITE
* Function implementing age withdraw transaction. Runs the * Function implementing age withdraw transaction. Runs the
* transaction logic; IF it returns a non-error code, the transaction * transaction logic; IF it returns a non-error code, the transaction
* logic MUST NOT queue a MHD response. IF it returns an hard error, * logic MUST NOT queue a MHD response. IF it returns an hard error,
@ -155,10 +150,10 @@ withdraw_amount_cb (void *cls,
* IF it returns the soft error code, the function MAY be called again * IF it returns the soft error code, the function MAY be called again
* to retry and MUST not queue a MHD response. * to retry and MUST not queue a MHD response.
* *
* Note that "wc->collectable.sig" is set before entering this function as we * Note that "awc->commitment.sig" is set before entering this function as we
* signed before entering the transaction. * signed before entering the transaction.
* *
* @param cls a `struct WithdrawContext *` * @param cls a `struct AgeWithdrawContext *`
* @param connection MHD request which triggered the transaction * @param connection MHD request which triggered the transaction
* @param[out] mhd_ret set to MHD response status for @a connection, * @param[out] mhd_ret set to MHD response status for @a connection,
* if transaction failed (!) * if transaction failed (!)
@ -169,21 +164,19 @@ age_withdraw_transaction (void *cls,
struct MHD_Connection *connection, struct MHD_Connection *connection,
MHD_RESULT *mhd_ret) MHD_RESULT *mhd_ret)
{ {
struct AgeWithdrawContext *wc = cls; struct AgeWithdrawContext *awc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
bool found = false; bool found = false;
bool balance_ok = false; bool balance_ok = false;
bool nonce_ok = false;
uint64_t ruuid; uint64_t ruuid;
const struct TALER_CsNonce *nonce;
const struct TALER_BlindedPlanchet *bp;
wc->now = GNUNET_TIME_timestamp_get (); awc->now = GNUNET_TIME_timestamp_get ();
qs = TEH_plugin->reserves_get_origin (TEH_plugin->cls, qs = TEH_plugin->reserves_get_origin (TEH_plugin->cls,
&wc->collectable.reserve_pub, &awc->commitment.reserve_pub,
&wc->h_payto); &awc->h_payto);
if (qs < 0) if (qs < 0)
return qs; return qs;
/* If no results, reserve was created by merge, /* If no results, reserve was created by merge,
in which case no KYC check is required as the in which case no KYC check is required as the
merge already did that. */ merge already did that. */
@ -192,46 +185,42 @@ age_withdraw_transaction (void *cls,
const char *kyc_required; const char *kyc_required;
kyc_required = TALER_KYCLOGIC_kyc_test_required ( kyc_required = TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW, TALER_KYCLOGIC_KYC_TRIGGER_AGE_WITHDRAW,
&wc->h_payto, &awc->h_payto,
TEH_plugin->select_satisfied_kyc_processes, TEH_plugin->select_satisfied_kyc_processes,
TEH_plugin->cls, TEH_plugin->cls,
&withdraw_amount_cb, &age_withdraw_amount_cb,
wc); awc);
if (NULL != kyc_required) if (NULL != kyc_required)
{ {
/* insert KYC requirement into DB! */ /* insert KYC requirement into DB! */
wc->kyc.ok = false; awc->kyc.ok = false;
return TEH_plugin->insert_kyc_requirement_for_account ( return TEH_plugin->insert_kyc_requirement_for_account (
TEH_plugin->cls, TEH_plugin->cls,
kyc_required, kyc_required,
&wc->h_payto, &awc->h_payto,
&wc->kyc.requirement_row); &awc->kyc.requirement_row);
} }
} }
wc->kyc.ok = true;
bp = &wc->blinded_planchet; awc->kyc.ok = true;
nonce = (TALER_DENOMINATION_CS == bp->cipher) qs = TEH_plugin->do_age_withdraw (TEH_plugin->cls,
? &bp->details.cs_blinded_planchet.nonce &awc->commitment,
: NULL; awc->now,
qs = TEH_plugin->do_withdraw (TEH_plugin->cls, &found,
nonce, &balance_ok,
&wc->collectable, &ruuid);
wc->now,
&found,
&balance_ok,
&nonce_ok,
&ruuid);
if (0 > qs) if (0 > qs)
{ {
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TALER_MHD_reply_with_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED, TALER_EC_GENERIC_DB_FETCH_FAILED,
"do_withdraw"); "do_age_withdraw");
return qs; return qs;
} }
if (! found) else if (! found)
{ {
*mhd_ret = TALER_MHD_reply_with_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
@ -239,34 +228,23 @@ age_withdraw_transaction (void *cls,
NULL); NULL);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if (! balance_ok) else if (! balance_ok)
{ {
TEH_plugin->rollback (TEH_plugin->cls); TEH_plugin->rollback (TEH_plugin->cls);
*mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance ( *mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance (
connection, connection,
TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS, TALER_EC_EXCHANGE_AGE_WITHDRAW_INSUFFICIENT_FUNDS,
&wc->collectable.amount_with_fee, &awc->commitment.amount_with_fee,
&wc->collectable.reserve_pub); &awc->commitment.reserve_pub);
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (! nonce_ok)
{
TEH_plugin->rollback (TEH_plugin->cls);
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_CONFLICT,
TALER_EC_EXCHANGE_WITHDRAW_NONCE_REUSE,
NULL);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
TEH_METRICS_num_success[TEH_MT_SUCCESS_WITHDRAW]++; TEH_METRICS_num_success[TEH_MT_SUCCESS_AGE_WITHDRAW]++;
return qs; return qs;
} }
#endif
/** /**
* Check if the @a rc is replayed and we already have an * Check if the @a rc is replayed and we already have an
* answer. If so, replay the existing answer and return the * answer. If so, replay the existing answer and return the
@ -284,10 +262,12 @@ request_is_idempotent (struct TEH_RequestContext *rc,
MHD_RESULT *mret) MHD_RESULT *mret)
{ {
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
struct TALER_EXCHANGEDB_AgeWithdrawCommitment commitment;
qs = TEH_plugin->get_age_withdraw_info (TEH_plugin->cls, qs = TEH_plugin->get_age_withdraw_info (TEH_plugin->cls,
&awc->reserve_pub, &awc->commitment.reserve_pub,
&awc->commitment); &awc->commitment.h_commitment,
&commitment);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -304,16 +284,9 @@ request_is_idempotent (struct TEH_RequestContext *rc,
/* generate idempotent reply */ /* generate idempotent reply */
TEH_METRICS_num_requests[TEH_MT_REQUEST_IDEMPOTENT_AGE_WITHDRAW]++; TEH_METRICS_num_requests[TEH_MT_REQUEST_IDEMPOTENT_AGE_WITHDRAW]++;
*mret = TALER_MHD_REPLY_JSON_PACK ( *mret = reply_age_withdraw_success (rc->connection,
rc->connection, &commitment.h_commitment,
MHD_HTTP_OK, commitment.noreveal_index);
GNUNET_JSON_pack_uint64 ("noreveal_index",
&awc->commitment.noreveal_index),
GNUNET_JSON_pack_data_auto ("exchange_sig",
&awc->commitment.sig),
GNUNET_JSON_pack_data_auto ("exchange_pub",
/* TODO:oec: where does the pub come from? */
&pub));
return true; return true;
} }
@ -323,6 +296,7 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const json_t *root) const json_t *root)
{ {
MHD_RESULT mhd_ret;
struct AgeWithdrawContext awc; struct AgeWithdrawContext awc;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("reserve_sig", GNUNET_JSON_spec_fixed_auto ("reserve_sig",
@ -330,12 +304,12 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
GNUNET_JSON_spec_fixed_auto ("h_commitment", GNUNET_JSON_spec_fixed_auto ("h_commitment",
&awc.commitment.h_commitment), &awc.commitment.h_commitment),
TALER_JSON_spec_amount ("amount", TALER_JSON_spec_amount ("amount",
&awc.commitment.amount_with_fee); TEH_currency,
&awc.commitment.amount_with_fee),
GNUNET_JSON_spec_uint8 ("max_age_group", GNUNET_JSON_spec_uint8 ("max_age_group",
&awc.commitment.max_age_group), &awc.commitment.max_age_group),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
enum TALER_ErrorCode ec;
memset (&awc, 0, sizeof (awc)); memset (&awc, 0, sizeof (awc));
awc.commitment.reserve_pub = *reserve_pub; awc.commitment.reserve_pub = *reserve_pub;
@ -352,36 +326,31 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
} }
/* If request was made before successfully, return the previous answer */ do {
if (request_is_idempotent (rc, /* If request was made before successfully, return the previous answer */
&awc, if (request_is_idempotent (rc,
&mret)) &awc,
{ &mhd_ret))
GNUNET_JSON_parse_free (spec); break;
return mret;
}
/* Verify the signature of the request body with the reserve key */ /* Verify the signature of the request body with the reserve key */
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_wallet_age_withdraw_verify (&awc.commitment.h_commitment, TALER_wallet_age_withdraw_verify (&awc.commitment.h_commitment,
&awc.commitment.amount_with_fee, &awc.commitment.amount_with_fee,
&awc.commitment.max_age_group, awc.commitment.max_age_group,
&awc.commitment.reserve_pub, &awc.commitment.reserve_pub,
&awc.commitment.reserve_sig)) &awc.commitment.reserve_sig))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); mhd_ret = TALER_MHD_reply_with_error (rc->connection,
return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_FORBIDDEN,
MHD_HTTP_FORBIDDEN, TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID,
TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID, NULL);
NULL); break;
} }
/* run transaction */
{
MHD_RESULT mhd_ret;
/* Run the transaction */
if (GNUNET_OK != if (GNUNET_OK !=
TEH_DB_run_transaction (rc->connection, TEH_DB_run_transaction (rc->connection,
"run age withdraw", "run age withdraw",
@ -389,27 +358,24 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
&mhd_ret, &mhd_ret,
&age_withdraw_transaction, &age_withdraw_transaction,
&awc)) &awc))
{ break;
/* Even if #withdraw_transaction() failed, it may have created a signature
(or we might have done it optimistically above). */ /* Clean up and send back final response */
/* TODO:oec:which function to call here!? */ GNUNET_JSON_parse_free (spec);
TALER_blinded_denom_sig_free (&awc.commitment.sig);
GNUNET_JSON_parse_free (spec); if (! awc.kyc.ok)
return mhd_ret; return TEH_RESPONSE_reply_kyc_required (rc->connection,
} &awc.h_payto,
} &awc.kyc);
return reply_age_withdraw_success (rc->connection,
&awc.commitment.h_commitment,
awc.commitment.noreveal_index);
} while(0);
/* Clean up and send back final response */
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return mhd_ret;
if (! awc.kyc.ok)
return TEH_RESPONSE_reply_kyc_required (rc->connection,
&awc.h_payto,
&awc.kyc);
return reply_age_withdraw_success (rc->connection,
&awc.commitment.h_commitment,
awc.commitment.noreveal_index);
} }

View File

@ -31,27 +31,26 @@
MHD_RESULT MHD_RESULT
TEH_handler_management_post_aml_decision ( TEH_handler_post_aml_decision (
struct MHD_Connection *connection, struct TEH_RequestContext *rc,
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
const json_t *root) const json_t *root)
{ {
struct MHD_Connection *connection = rc->connection;
const char *justification; const char *justification;
struct GNUNET_TIME_Timestamp decision_time; struct GNUNET_TIME_Timestamp decision_time;
struct TALER_Amount new_threshold; struct TALER_Amount new_threshold;
struct TALER_PaytoHashP h_payto; struct TALER_PaytoHashP h_payto;
uint32_t new_state32; uint32_t new_state32;
enum TALER_AmlDecisionState new_state; enum TALER_AmlDecisionState new_state;
struct TALER_AmlOfficerPublicKeyP officer_pub;
struct TALER_AmlOfficerSignatureP officer_sig; struct TALER_AmlOfficerSignatureP officer_sig;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
// FIXME: officer_pub is in URL path, not in JSON body!
GNUNET_JSON_spec_fixed_auto ("officer_pub",
&officer_pub),
GNUNET_JSON_spec_fixed_auto ("officer_sig", GNUNET_JSON_spec_fixed_auto ("officer_sig",
&officer_sig), &officer_sig),
GNUNET_JSON_spec_fixed_auto ("h_payto", GNUNET_JSON_spec_fixed_auto ("h_payto",
&h_payto), &h_payto),
TALER_JSON_spec_amount ("new_threshold", TALER_JSON_spec_amount ("new_threshold",
TEH_currency,
&new_threshold), &new_threshold),
GNUNET_JSON_spec_string ("justification", GNUNET_JSON_spec_string ("justification",
&justification), &justification),
@ -76,13 +75,13 @@ TEH_handler_management_post_aml_decision (
new_state = (enum TALER_AmlDecisionState) new_state32; new_state = (enum TALER_AmlDecisionState) new_state32;
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_exchange_aml_decision_verify (justification, TALER_officer_aml_decision_verify (justification,
decision_time, decision_time,
&new_threshold, &new_threshold,
&h_payto, &h_payto,
new_state, new_state,
&officer_pub, &officer_pub,
&officer_sig)) &officer_sig))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TALER_MHD_reply_with_error ( return TALER_MHD_reply_with_error (
@ -97,25 +96,25 @@ TEH_handler_management_post_aml_decision (
bool invalid_officer; bool invalid_officer;
do { do {
qs = TEH_plugin->add_aml_decision (TEH_plugin->cls, // FIXME: bound loop?
justification, qs = TEH_plugin->insert_aml_decision (TEH_plugin->cls,
decision_time, &h_payto,
&new_threshold, &new_threshold,
&h_payto, new_state,
new_state, decision_time,
&officer_pub, justification,
&officer_sig, &officer_pub,
&invalid_officer, &officer_sig,
&last_date); &invalid_officer,
&last_date);
} while (GNUNET_DB_STATUS_SOFT_ERROR == qs); } while (GNUNET_DB_STATUS_SOFT_ERROR == qs);
if (qs < 0) if (qs < 0)
{ {
GNUNET_break (0); GNUNET_break (0);
*mhd_ret = TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED, TALER_EC_GENERIC_DB_STORE_FAILED,
"add aml_decision"); "add aml_decision");
return qs;
} }
if (invalid_officer) if (invalid_officer)
{ {
@ -127,7 +126,7 @@ TEH_handler_management_post_aml_decision (
} }
if (GNUNET_TIME_timestamp_cmp (last_date, if (GNUNET_TIME_timestamp_cmp (last_date,
>, >,
validity_start)) decision_time))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TALER_MHD_reply_with_error ( return TALER_MHD_reply_with_error (

View File

@ -0,0 +1,45 @@
/*
This file is part of TALER
Copyright (C) 2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
* @file taler-exchange-httpd_aml_decision.h
* @brief Handle /aml/$OFFICER_PUB/decision requests
* @author Christian Grothoff
*/
#ifndef TALER_EXCHANGE_HTTPD_AML_DECISION_H
#define TALER_EXCHANGE_HTTPD_AML_DECISION_H
#include <microhttpd.h>
#include "taler-exchange-httpd.h"
/**
* Handle an "/aml/$OFFICER_PUB/decision" request. Parses the decision
* details, checks the signatures and if appropriately authorized excecutes
* the decision.
*
* @param rc request context
* @param officer_pub public key of the AML officer who made the request
* @param root uploaded JSON data
* @return MHD result code
*/
MHD_RESULT
TEH_handler_post_aml_decision (
struct TEH_RequestContext *rc,
const struct TALER_AmlOfficerPublicKeyP *officer_pub,
const json_t *root);
#endif

View File

@ -37,7 +37,7 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin,
{ {
enum TALER_EXCHANGEDB_CoinKnownStatus cks; enum TALER_EXCHANGEDB_CoinKnownStatus cks;
struct TALER_DenominationHashP h_denom_pub; struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash age_hash; struct TALER_AgeCommitmentHashP age_hash;
/* make sure coin is 'known' in database */ /* make sure coin is 'known' in database */
cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls, cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls,

View File

@ -174,6 +174,32 @@ TEH_handler_management_post_drain (
const json_t *root); const json_t *root);
/**
* Handle a POST "/management/aml-officers" request.
*
* @param connection the MHD connection to handle
* @param root uploaded JSON data
* @return MHD result code
*/
MHD_RESULT
TEH_handler_management_aml_officers (
struct MHD_Connection *connection,
const json_t *root);
/**
* Handle a POST "/management/partners" request.
*
* @param connection the MHD connection to handle
* @param root uploaded JSON data
* @return MHD result code
*/
MHD_RESULT
TEH_handler_management_partners (
struct MHD_Connection *connection,
const json_t *root);
/** /**
* Initialize extension configuration handling. * Initialize extension configuration handling.
* *

View File

@ -92,14 +92,15 @@ TEH_handler_management_aml_officers (
struct GNUNET_TIME_Timestamp last_date; struct GNUNET_TIME_Timestamp last_date;
do { do {
qs = TEH_plugin->set_aml_officer (TEH_plugin->cls, // FIXME: bound loop!
&officer_pub, qs = TEH_plugin->insert_aml_officer (TEH_plugin->cls,
officer_name, &officer_pub,
change_date, &master_sig,
is_active, officer_name,
read_only, is_active,
&master_sig, read_only,
&last_date); change_date,
&last_date);
} while (GNUNET_DB_STATUS_SOFT_ERROR == qs); } while (GNUNET_DB_STATUS_SOFT_ERROR == qs);
if (qs < 0) if (qs < 0)
{ {
@ -107,13 +108,13 @@ TEH_handler_management_aml_officers (
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED, TALER_EC_GENERIC_DB_STORE_FAILED,
"XXX"); "insert_aml_officer");
} }
if (GNUNET_TIME_timestamp_cmp (last_date, if (GNUNET_TIME_timestamp_cmp (last_date,
>, >,
change_date)) change_date))
{ {
GNUNER_break_op (0); GNUNET_break_op (0);
return TALER_MHD_reply_with_error ( return TALER_MHD_reply_with_error (
connection, connection,
MHD_HTTP_CONFLICT, MHD_HTTP_CONFLICT,

View File

@ -51,13 +51,14 @@ TEH_handler_management_partners (
GNUNET_JSON_spec_string ("partner_base_url", GNUNET_JSON_spec_string ("partner_base_url",
&partner_base_url), &partner_base_url),
TALER_JSON_spec_amount ("wad_fee", TALER_JSON_spec_amount ("wad_fee",
TEH_currency,
&wad_fee), &wad_fee),
GNUNET_JSON_spec_timestamp ("start_date", GNUNET_JSON_spec_timestamp ("start_date",
&start_date), &start_date),
GNUNET_JSON_spec_timestamp ("end_date", GNUNET_JSON_spec_timestamp ("end_date",
&start_date), &start_date),
GNUNET_JSON_spec_time_rel ("wad_frequency", GNUNET_JSON_spec_relative_time ("wad_frequency",
&wad_frequency), &wad_frequency),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
@ -94,14 +95,14 @@ TEH_handler_management_partners (
{ {
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->add_partner (TEH_plugin->cls, qs = TEH_plugin->insert_partner (TEH_plugin->cls,
&partner_pub, &partner_pub,
start_date, start_date,
end_date, end_date,
wad_frequency, wad_frequency,
&wad_fee, &wad_fee,
partner_base_url, partner_base_url,
&master_sig); &master_sig);
if (qs < 0) if (qs < 0)
{ {
GNUNET_break (0); GNUNET_break (0);
@ -110,6 +111,14 @@ TEH_handler_management_partners (
TALER_EC_GENERIC_DB_STORE_FAILED, TALER_EC_GENERIC_DB_STORE_FAILED,
"add_partner"); "add_partner");
} }
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
/* FIXME: check for idempotency! */
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_CONFLICT,
TALER_EC_EXCHANGE_MANAGEMENT_ADD_PARTNER_DATA_CONFLICT,
NULL);
}
} }
return TALER_MHD_reply_static ( return TALER_MHD_reply_static (
connection, connection,

View File

@ -34,18 +34,20 @@ enum TEH_MetricTypeRequest
TEH_MT_REQUEST_OTHER = 0, TEH_MT_REQUEST_OTHER = 0,
TEH_MT_REQUEST_DEPOSIT = 1, TEH_MT_REQUEST_DEPOSIT = 1,
TEH_MT_REQUEST_WITHDRAW = 2, TEH_MT_REQUEST_WITHDRAW = 2,
TEH_MT_REQUEST_MELT = 3, TEH_MT_REQUEST_AGE_WITHDRAW = 3,
TEH_MT_REQUEST_PURSE_CREATE = 4, TEH_MT_REQUEST_MELT = 4,
TEH_MT_REQUEST_PURSE_MERGE = 5, TEH_MT_REQUEST_PURSE_CREATE = 5,
TEH_MT_REQUEST_RESERVE_PURSE = 6, TEH_MT_REQUEST_PURSE_MERGE = 6,
TEH_MT_REQUEST_PURSE_DEPOSIT = 7, TEH_MT_REQUEST_RESERVE_PURSE = 7,
TEH_MT_REQUEST_IDEMPOTENT_DEPOSIT = 8, TEH_MT_REQUEST_PURSE_DEPOSIT = 8,
TEH_MT_REQUEST_IDEMPOTENT_WITHDRAW = 9, TEH_MT_REQUEST_IDEMPOTENT_DEPOSIT = 9,
TEH_MT_REQUEST_IDEMPOTENT_MELT = 10, TEH_MT_REQUEST_IDEMPOTENT_WITHDRAW = 10,
TEH_MT_REQUEST_IDEMPOTENT_BATCH_WITHDRAW = 11, TEH_MT_REQUEST_IDEMPOTENT_AGE_WITHDRAW = 11,
TEH_MT_REQUEST_BATCH_DEPOSIT = 12, TEH_MT_REQUEST_IDEMPOTENT_MELT = 12,
TEH_MT_REQUEST_POLICY_FULFILLMENT = 13, TEH_MT_REQUEST_IDEMPOTENT_BATCH_WITHDRAW = 13,
TEH_MT_REQUEST_COUNT = 14 /* MUST BE LAST! */ TEH_MT_REQUEST_BATCH_DEPOSIT = 14,
TEH_MT_REQUEST_POLICY_FULFILLMENT = 15,
TEH_MT_REQUEST_COUNT = 16 /* MUST BE LAST! */
}; };
/** /**
@ -55,10 +57,11 @@ enum TEH_MetricTypeSuccess
{ {
TEH_MT_SUCCESS_DEPOSIT = 0, TEH_MT_SUCCESS_DEPOSIT = 0,
TEH_MT_SUCCESS_WITHDRAW = 1, TEH_MT_SUCCESS_WITHDRAW = 1,
TEH_MT_SUCCESS_BATCH_WITHDRAW = 2, TEH_MT_SUCCESS_AGE_WITHDRAW = 2,
TEH_MT_SUCCESS_MELT = 3, TEH_MT_SUCCESS_BATCH_WITHDRAW = 3,
TEH_MT_SUCCESS_REFRESH_REVEAL = 4, TEH_MT_SUCCESS_MELT = 4,
TEH_MT_SUCCESS_COUNT = 5 /* MUST BE LAST! */ TEH_MT_SUCCESS_REFRESH_REVEAL = 5,
TEH_MT_SUCCESS_COUNT = 6 /* MUST BE LAST! */
}; };
/** /**

View File

@ -260,7 +260,7 @@ create_transaction (void *cls,
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub; struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac; struct TALER_AgeCommitmentHashP phac;
char *partner_url = NULL; char *partner_url = NULL;
TEH_plugin->rollback (TEH_plugin->cls); TEH_plugin->rollback (TEH_plugin->cls);

View File

@ -222,7 +222,7 @@ deposit_transaction (void *cls,
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub; struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac; struct TALER_AgeCommitmentHashP phac;
char *partner_url = NULL; char *partner_url = NULL;
TEH_plugin->rollback (TEH_plugin->cls); TEH_plugin->rollback (TEH_plugin->cls);

View File

@ -263,8 +263,8 @@ check_commitment (struct RevealContext *rctx,
const struct TALER_TransferPrivateKeyP *tpriv const struct TALER_TransferPrivateKeyP *tpriv
= &rctx->transfer_privs[i - off]; = &rctx->transfer_privs[i - off];
struct TALER_TransferSecretP ts; struct TALER_TransferSecretP ts;
struct TALER_AgeCommitmentHash h = {0}; struct TALER_AgeCommitmentHashP h = {0};
struct TALER_AgeCommitmentHash *hac = NULL; struct TALER_AgeCommitmentHashP *hac = NULL;
GNUNET_CRYPTO_ecdhe_key_get_public (&tpriv->ecdhe_priv, GNUNET_CRYPTO_ecdhe_key_get_public (&tpriv->ecdhe_priv,
&rce->transfer_pub.ecdhe_pub); &rce->transfer_pub.ecdhe_pub);
@ -657,11 +657,11 @@ resolve_refreshes_reveal_denominations (
/* Sanity check: Compare hash from melting with hash of this age commitment */ /* Sanity check: Compare hash from melting with hash of this age commitment */
{ {
struct TALER_AgeCommitmentHash hac = {0}; struct TALER_AgeCommitmentHashP hac = {0};
TALER_age_commitment_hash (oac, &hac); TALER_age_commitment_hash (oac, &hac);
if (0 != memcmp (&hac, if (0 != memcmp (&hac,
&rctx->melt.session.coin.h_age_commitment, &rctx->melt.session.coin.h_age_commitment,
sizeof(struct TALER_AgeCommitmentHash))) sizeof(struct TALER_AgeCommitmentHashP)))
goto clean_age; goto clean_age;
} }

View File

@ -129,7 +129,7 @@ TEH_RESPONSE_compile_transaction_history (
{ {
const struct TALER_EXCHANGEDB_MeltListEntry *melt = const struct TALER_EXCHANGEDB_MeltListEntry *melt =
pos->details.melt; pos->details.melt;
const struct TALER_AgeCommitmentHash *phac = NULL; const struct TALER_AgeCommitmentHashP *phac = NULL;
#if ENABLE_SANITY_CHECKS #if ENABLE_SANITY_CHECKS
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
@ -391,7 +391,7 @@ TEH_RESPONSE_compile_transaction_history (
{ {
struct TALER_EXCHANGEDB_PurseDepositListEntry *pd struct TALER_EXCHANGEDB_PurseDepositListEntry *pd
= pos->details.purse_deposit; = pos->details.purse_deposit;
const struct TALER_AgeCommitmentHash *phac = NULL; const struct TALER_AgeCommitmentHashP *phac = NULL;
if (! pd->no_age_commitment) if (! pd->no_age_commitment)
phac = &pd->h_age_commitment; phac = &pd->h_age_commitment;

View File

@ -25,6 +25,7 @@ CREATE TABLE partners
,wad_fee_frac INT4 NOT NULL ,wad_fee_frac INT4 NOT NULL
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
,partner_base_url TEXT NOT NULL ,partner_base_url TEXT NOT NULL
,PRIMARY KEY (partner_master_pub, start_date)
); );
COMMENT ON TABLE partners COMMENT ON TABLE partners
IS 'exchanges we do wad transfers to'; IS 'exchanges we do wad transfers to';

View File

@ -28,10 +28,10 @@
enum TALER_EXCHANGEDB_CoinKnownStatus enum TALER_EXCHANGEDB_CoinKnownStatus
TEH_PG_ensure_coin_known (void *cls, TEH_PG_ensure_coin_known (void *cls,
const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinPublicInfo *coin,
uint64_t *known_coin_id, uint64_t *known_coin_id,
struct TALER_DenominationHashP *denom_hash, struct TALER_DenominationHashP *denom_hash,
struct TALER_AgeCommitmentHash *h_age_commitment) struct TALER_AgeCommitmentHashP *h_age_commitment)
{ {
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
@ -60,12 +60,12 @@ TEH_PG_ensure_coin_known (void *cls,
&is_age_hash_null), &is_age_hash_null),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
/* Used in #postgres_insert_known_coin() to store the denomination public /* Used in #postgres_insert_known_coin() to store the denomination public
key and signature for a coin known to the exchange. key and signature for a coin known to the exchange.
See also: See also:
https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql/37543015#37543015 https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql/37543015#37543015
*/ */
PREPARE (pg, PREPARE (pg,
"insert_known_coin", "insert_known_coin",
"WITH dd" "WITH dd"

View File

@ -37,9 +37,9 @@
*/ */
enum TALER_EXCHANGEDB_CoinKnownStatus enum TALER_EXCHANGEDB_CoinKnownStatus
TEH_PG_ensure_coin_known (void *cls, TEH_PG_ensure_coin_known (void *cls,
const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinPublicInfo *coin,
uint64_t *known_coin_id, uint64_t *known_coin_id,
struct TALER_DenominationHashP *denom_hash, struct TALER_DenominationHashP *denom_hash,
struct TALER_AgeCommitmentHash *h_age_commitment); struct TALER_AgeCommitmentHashP *h_age_commitment);
#endif #endif

View File

@ -32,7 +32,7 @@ TEH_PG_get_purse_deposit (
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_Amount *amount, struct TALER_Amount *amount,
struct TALER_DenominationHashP *h_denom_pub, struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac, struct TALER_AgeCommitmentHashP *phac,
struct TALER_CoinSpendSignatureP *coin_sig, struct TALER_CoinSpendSignatureP *coin_sig,
char **partner_url) char **partner_url)
{ {
@ -61,7 +61,7 @@ TEH_PG_get_purse_deposit (
*partner_url = NULL; *partner_url = NULL;
/* Used in #postgres_get_purse_deposit */ /* Used in #postgres_get_purse_deposit */
PREPARE (pg, PREPARE (pg,
"select_purse_deposit_by_coin_pub", "select_purse_deposit_by_coin_pub",
"SELECT " "SELECT "

View File

@ -46,7 +46,7 @@ TEH_PG_get_purse_deposit (
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_Amount *amount, struct TALER_Amount *amount,
struct TALER_DenominationHashP *h_denom_pub, struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac, struct TALER_AgeCommitmentHashP *phac,
struct TALER_CoinSpendSignatureP *coin_sig, struct TALER_CoinSpendSignatureP *coin_sig,
char **partner_url); char **partner_url);

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2022 Taler Systems SA Copyright (C) 2022, 2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the 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 terms of the GNU General Public License as published by the Free Software
@ -32,10 +32,12 @@ TEH_PG_insert_aml_decision (
const struct TALER_PaytoHashP *h_payto, const struct TALER_PaytoHashP *h_payto,
const struct TALER_Amount *new_threshold, const struct TALER_Amount *new_threshold,
enum TALER_AmlDecisionState new_status, enum TALER_AmlDecisionState new_status,
struct GNUNET_TIME_Absolute decision_time, struct GNUNET_TIME_Timestamp decision_time,
const char *justification, const char *justification,
const struct TALER_AmlOfficerPublicKeyP *decider_pub, const struct TALER_AmlOfficerPublicKeyP *decider_pub,
const struct TALER_AmlOfficerSignatureP *decider_sig) const struct TALER_AmlOfficerSignatureP *decider_sig,
bool *invalid_officer,
struct GNUNET_TIME_Timestamp *last_date)
{ {
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
uint32_t ns = (uint32_t) new_status; uint32_t ns = (uint32_t) new_status;
@ -43,13 +45,15 @@ TEH_PG_insert_aml_decision (
GNUNET_PQ_query_param_auto_from_type (h_payto), GNUNET_PQ_query_param_auto_from_type (h_payto),
TALER_PQ_query_param_amount (new_threshold), TALER_PQ_query_param_amount (new_threshold),
GNUNET_PQ_query_param_uint32 (&ns), GNUNET_PQ_query_param_uint32 (&ns),
GNUNET_PQ_query_param_absolute_time (&decision_time), GNUNET_PQ_query_param_timestamp (&decision_time),
GNUNET_PQ_query_param_string (justification), GNUNET_PQ_query_param_string (justification),
GNUNET_PQ_query_param_auto_from_type (decider_pub), GNUNET_PQ_query_param_auto_from_type (decider_pub),
GNUNET_PQ_query_param_auto_from_type (decider_sig), GNUNET_PQ_query_param_auto_from_type (decider_sig),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
// FIXME: set invalid_officer
// FIXME: set last_date!
PREPARE (pg, PREPARE (pg,
"insert_aml_decision", "insert_aml_decision",
"INSERT INTO aml_history " "INSERT INTO aml_history "

View File

@ -38,6 +38,9 @@
* @param justification human-readable text justifying the decision * @param justification human-readable text justifying the decision
* @param decider_pub public key of the staff member * @param decider_pub public key of the staff member
* @param decider_sig signature of the staff member * @param decider_sig signature of the staff member
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
* @param[out] last_date set to the previous decision time;
* the INSERT is not performed if @a last_date is not before @a decision_time
* @return database transaction status * @return database transaction status
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
@ -46,10 +49,12 @@ TEH_PG_insert_aml_decision (
const struct TALER_PaytoHashP *h_payto, const struct TALER_PaytoHashP *h_payto,
const struct TALER_Amount *new_threshold, const struct TALER_Amount *new_threshold,
enum TALER_AmlDecisionState new_status, enum TALER_AmlDecisionState new_status,
struct GNUNET_TIME_Absolute decision_time, struct GNUNET_TIME_Timestamp decision_time,
const char *justification, const char *justification,
const struct TALER_AmlOfficerPublicKeyP *decider_pub, const struct TALER_AmlOfficerPublicKeyP *decider_pub,
const struct TALER_AmlOfficerSignatureP *decider_sig); const struct TALER_AmlOfficerSignatureP *decider_sig,
bool *invalid_officer,
struct GNUNET_TIME_Timestamp *last_date);
#endif #endif

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2022 Taler Systems SA Copyright (C) 2022, 2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the 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 terms of the GNU General Public License as published by the Free Software
@ -34,7 +34,8 @@ TEH_PG_insert_aml_officer (
const char *decider_name, const char *decider_name,
bool is_active, bool is_active,
bool read_only, bool read_only,
struct GNUNET_TIME_Absolute last_change) struct GNUNET_TIME_Timestamp last_change,
struct GNUNET_TIME_Timestamp *previous_change)
{ {
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
@ -43,10 +44,11 @@ TEH_PG_insert_aml_officer (
GNUNET_PQ_query_param_string (decider_name), GNUNET_PQ_query_param_string (decider_name),
GNUNET_PQ_query_param_bool (is_active), GNUNET_PQ_query_param_bool (is_active),
GNUNET_PQ_query_param_bool (read_only), GNUNET_PQ_query_param_bool (read_only),
GNUNET_PQ_query_param_absolute_time (&last_change), GNUNET_PQ_query_param_timestamp (&last_change),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
// FIXME: need to check for previous record!
PREPARE (pg, PREPARE (pg,
"insert_aml_staff", "insert_aml_staff",
"INSERT INTO aml_staff " "INSERT INTO aml_staff "

View File

@ -27,7 +27,10 @@
/** /**
* Insert AML staff record. * Insert AML staff record. If the time given in
* @a last_change is before the previous change in the
* database, only @e previous_change is returned and
* no actual change is committed to the database.
* *
* @param cls closure * @param cls closure
* @param decider_pub public key of the staff member * @param decider_pub public key of the staff member
@ -36,6 +39,7 @@
* @param is_active true to enable, false to set as inactive * @param is_active true to enable, false to set as inactive
* @param read_only true to set read-only access * @param read_only true to set read-only access
* @param last_change when was the change made effective * @param last_change when was the change made effective
* @param[out] previous_change set to the time of the previous change
* @return database transaction status * @return database transaction status
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
@ -46,6 +50,7 @@ TEH_PG_insert_aml_officer (
const char *decider_name, const char *decider_name,
bool is_active, bool is_active,
bool read_only, bool read_only,
struct GNUNET_TIME_Absolute last_change); struct GNUNET_TIME_Timestamp last_change,
struct GNUNET_TIME_Timestamp *previous_change);
#endif #endif

View File

@ -28,13 +28,13 @@
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
TEH_PG_insert_partner (void *cls, TEH_PG_insert_partner (void *cls,
const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_MasterPublicKeyP *master_pub,
struct GNUNET_TIME_Timestamp start_date, struct GNUNET_TIME_Timestamp start_date,
struct GNUNET_TIME_Timestamp end_date, struct GNUNET_TIME_Timestamp end_date,
struct GNUNET_TIME_Relative wad_frequency, struct GNUNET_TIME_Relative wad_frequency,
const struct TALER_Amount *wad_fee, const struct TALER_Amount *wad_fee,
const char *partner_base_url, const char *partner_base_url,
const struct TALER_MasterSignatureP *master_sig) const struct TALER_MasterSignatureP *master_sig)
{ {
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
@ -61,10 +61,9 @@ TEH_PG_insert_partner (void *cls,
" ,master_sig" " ,master_sig"
" ,partner_base_url" " ,partner_base_url"
" ) VALUES " " ) VALUES "
" ($1, $2, $3, $4, $5, $6, $7, $8);"); " ($1, $2, $3, $4, $5, $6, $7, $8)"
" ON CONFLICT DO NOTHING;");
return GNUNET_PQ_eval_prepared_non_select (pg->conn, return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_partner", "insert_partner",
params); params);
} }

View File

@ -75,7 +75,7 @@ refreshs_serial_helper_cb (void *cls,
struct TALER_DenominationPublicKey denom_pub; struct TALER_DenominationPublicKey denom_pub;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
bool ac_isnull; bool ac_isnull;
struct TALER_Amount amount_with_fee; struct TALER_Amount amount_with_fee;
uint32_t noreveal_index; uint32_t noreveal_index;
@ -130,10 +130,6 @@ refreshs_serial_helper_cb (void *cls,
} }
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
TEH_PG_select_refreshes_above_serial_id ( TEH_PG_select_refreshes_above_serial_id (
void *cls, void *cls,
@ -153,8 +149,8 @@ TEH_PG_select_refreshes_above_serial_id (
.status = GNUNET_OK .status = GNUNET_OK
}; };
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
/* Used in #postgres_select_refreshes_above_serial_id() to fetch /* Used in #postgres_select_refreshes_above_serial_id() to fetch
refresh session with id '\geq' the given parameter */ refresh session with id '\geq' the given parameter */
PREPARE (pg, PREPARE (pg,
"audit_get_refresh_commitments_incr", "audit_get_refresh_commitments_incr",
"SELECT" "SELECT"

View File

@ -449,7 +449,7 @@ audit_refresh_session_cb (
void *cls, void *cls,
uint64_t rowid, uint64_t rowid,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *amount_with_fee,
@ -1340,8 +1340,8 @@ run (void *cls)
{ {
struct TALER_PlanchetDetail pd; struct TALER_PlanchetDetail pd;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_AgeCommitmentHash age_hash; struct TALER_AgeCommitmentHashP age_hash;
struct TALER_AgeCommitmentHash *p_ah[2] = { struct TALER_AgeCommitmentHashP *p_ah[2] = {
NULL, NULL,
&age_hash &age_hash
}; };
@ -1465,7 +1465,7 @@ run (void *cls)
deadline = GNUNET_TIME_timestamp_get (); deadline = GNUNET_TIME_timestamp_get ();
{ {
struct TALER_DenominationHashP dph; struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh; struct TALER_AgeCommitmentHashP agh;
FAILIF (TALER_EXCHANGEDB_CKS_ADDED != FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
plugin->ensure_coin_known (plugin->cls, plugin->ensure_coin_known (plugin->cls,
@ -1713,7 +1713,7 @@ run (void *cls)
uint64_t new_known_coin_id; uint64_t new_known_coin_id;
struct TALER_CoinPublicInfo new_coin; struct TALER_CoinPublicInfo new_coin;
struct TALER_DenominationHashP dph; struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh; struct TALER_AgeCommitmentHashP agh;
bool recoup_ok; bool recoup_ok;
bool internal_failure; bool internal_failure;
@ -2086,7 +2086,7 @@ run (void *cls)
{ {
uint64_t known_coin_id; uint64_t known_coin_id;
struct TALER_DenominationHashP dph; struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh; struct TALER_AgeCommitmentHashP agh;
FAILIF (TALER_EXCHANGEDB_CKS_ADDED != FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
plugin->ensure_coin_known (plugin->cls, plugin->ensure_coin_known (plugin->cls,

View File

@ -37,7 +37,7 @@ static int result;
*/ */
#define FAILIF(cond) \ #define FAILIF(cond) \
do { \ do { \
if (! (cond)) {break;} \ if (! (cond)) {break;} \
GNUNET_break (0); \ GNUNET_break (0); \
goto drop; \ goto drop; \
} while (0) } while (0)
@ -183,6 +183,7 @@ create_denom_key_pair (unsigned int size,
return dkp; return dkp;
} }
/** /**
* Function called with the session hashes and transfer secret * Function called with the session hashes and transfer secret
* information for a given coin. * information for a given coin.
@ -223,7 +224,6 @@ handle_link_data_cb (void *cls,
} }
/** /**
* Main function that will be run by the scheduler. * Main function that will be run by the scheduler.
* *
@ -238,25 +238,25 @@ run (void *cls)
struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct GNUNET_CONFIGURATION_Handle *cfg = cls;
const uint32_t num_partitions = 10; const uint32_t num_partitions = 10;
struct DenomKeyPair *dkp = NULL; struct DenomKeyPair *dkp = NULL;
struct TALER_EXCHANGEDB_Deposit *depos=NULL; struct TALER_EXCHANGEDB_Deposit *depos = NULL;
struct TALER_Amount value; struct TALER_Amount value;
struct TALER_DenominationPublicKey *new_denom_pubs = NULL; struct TALER_DenominationPublicKey *new_denom_pubs = NULL;
struct GNUNET_TIME_Relative times = GNUNET_TIME_UNIT_ZERO; struct GNUNET_TIME_Relative times = GNUNET_TIME_UNIT_ZERO;
unsigned long long sqrs=0; unsigned long long sqrs = 0;
struct TALER_EXCHANGEDB_Refund *ref=NULL; struct TALER_EXCHANGEDB_Refund *ref = NULL;
unsigned int *perm; unsigned int *perm;
unsigned long long duration_sq; unsigned long long duration_sq;
struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin;
struct TALER_ExchangeWithdrawValues alg_values = { struct TALER_ExchangeWithdrawValues alg_values = {
.cipher = TALER_DENOMINATION_RSA .cipher = TALER_DENOMINATION_RSA
}; };
ref = GNUNET_new_array (ROUNDS +1, ref = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Refund); struct TALER_EXCHANGEDB_Refund);
depos = GNUNET_new_array (ROUNDS +1, depos = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Deposit); struct TALER_EXCHANGEDB_Deposit);
refresh = GNUNET_new_array (ROUNDS +1, refresh = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Refresh); struct TALER_EXCHANGEDB_Refresh);
if (NULL == if (NULL ==
(plugin = TALER_EXCHANGEDB_plugin_load (cfg))) (plugin = TALER_EXCHANGEDB_plugin_load (cfg)))
@ -297,140 +297,140 @@ run (void *cls)
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount (CURRENCY ":0.000010", TALER_string_to_amount (CURRENCY ":0.000010",
&fees.refund)); &fees.refund));
//DENOMINATION // DENOMINATION
{ {
//PAIR KEY LIST // PAIR KEY LIST
new_dkp = GNUNET_new_array (MELT_NEW_COINS, new_dkp = GNUNET_new_array (MELT_NEW_COINS,
struct DenomKeyPair *); struct DenomKeyPair *);
//PUBLIC KEY LIST // PUBLIC KEY LIST
new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS, new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_DenominationPublicKey); struct TALER_DenominationPublicKey);
//REFRESH REVEAL COIN LIST // REFRESH REVEAL COIN LIST
revealed_coins revealed_coins
= GNUNET_new_array (MELT_NEW_COINS, = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_EXCHANGEDB_RefreshRevealedCoin); struct TALER_EXCHANGEDB_RefreshRevealedCoin);
for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++) for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++)
{ {
struct GNUNET_TIME_Timestamp now; struct GNUNET_TIME_Timestamp now;
struct TALER_BlindedRsaPlanchet *rp; struct TALER_BlindedRsaPlanchet *rp;
struct TALER_BlindedPlanchet *bp; struct TALER_BlindedPlanchet *bp;
now = GNUNET_TIME_timestamp_get (); now = GNUNET_TIME_timestamp_get ();
//5 KEY PAIR // 5 KEY PAIR
new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE, new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE,
now, now,
&value, &value,
&fees); &fees);
GNUNET_assert (NULL != new_dkp[cnt]); GNUNET_assert (NULL != new_dkp[cnt]);
new_denom_pubs[cnt] = new_dkp[cnt]->pub; new_denom_pubs[cnt] = new_dkp[cnt]->pub;
ccoin = &revealed_coins[cnt]; ccoin = &revealed_coins[cnt];
bp = &ccoin->blinded_planchet; bp = &ccoin->blinded_planchet;
bp->cipher = TALER_DENOMINATION_RSA; bp->cipher = TALER_DENOMINATION_RSA;
rp = &bp->details.rsa_blinded_planchet; rp = &bp->details.rsa_blinded_planchet;
rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 (
GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_QUALITY_WEAK,
(RSA_KEY_SIZE / 8) - 1); (RSA_KEY_SIZE / 8) - 1);
rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size); rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
rp->blinded_msg, rp->blinded_msg,
rp->blinded_msg_size); rp->blinded_msg_size);
TALER_denom_pub_hash (&new_dkp[cnt]->pub, TALER_denom_pub_hash (&new_dkp[cnt]->pub,
&ccoin->h_denom_pub); &ccoin->h_denom_pub);
ccoin->exchange_vals = alg_values; ccoin->exchange_vals = alg_values;
TALER_coin_ev_hash (bp, TALER_coin_ev_hash (bp,
&ccoin->h_denom_pub, &ccoin->h_denom_pub,
&ccoin->coin_envelope_hash); &ccoin->coin_envelope_hash);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&ccoin->coin_sig, TALER_denom_sign_blinded (&ccoin->coin_sig,
&new_dkp[cnt]->priv, &new_dkp[cnt]->priv,
true, true,
bp)); bp));
} }
} }
perm = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_NONCE, perm = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_NONCE,
NUM_ROWS); NUM_ROWS);
//BEGIN // BEGIN
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
plugin->start (plugin->cls, plugin->start (plugin->cls,
"Transaction")); "Transaction"));
for (unsigned int j = 0; j < NUM_ROWS; j++) for (unsigned int j = 0; j < NUM_ROWS; j++)
{ {
union TALER_DenominationBlindingKeyP bks; union TALER_DenominationBlindingKeyP bks;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinPubHashP c_hash; struct TALER_CoinPubHashP c_hash;
unsigned int k = (unsigned int)rand()%5; unsigned int k = (unsigned int) rand () % 5;
unsigned int i = perm[j]; unsigned int i = perm[j];
if (i >= ROUNDS) if (i >= ROUNDS)
i = ROUNDS; /* throw-away slot, do not keep around */ i = ROUNDS; /* throw-away slot, do not keep around */
RND_BLK (&coin_pub); RND_BLK (&coin_pub);
RND_BLK (&c_hash); RND_BLK (&c_hash);
RND_BLK (&depos[i].coin.coin_pub); RND_BLK (&depos[i].coin.coin_pub);
TALER_denom_pub_hash (&new_dkp[k]->pub, TALER_denom_pub_hash (&new_dkp[k]->pub,
&depos[i].coin.denom_pub_hash); &depos[i].coin.denom_pub_hash);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_denom_sig_unblind (&depos[i].coin.denom_sig, TALER_denom_sig_unblind (&depos[i].coin.denom_sig,
&ccoin->coin_sig, &ccoin->coin_sig,
&bks, &bks,
&c_hash, &c_hash,
&alg_values, &alg_values,
&new_dkp[k]->pub)); &new_dkp[k]->pub));
{ {
/* ENSURE_COIN_KNOWN */ /* ENSURE_COIN_KNOWN */
uint64_t known_coin_id; uint64_t known_coin_id;
struct TALER_DenominationHashP dph; struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh; struct TALER_AgeCommitmentHashP agh;
bool zombie_required = false; bool zombie_required = false;
bool balance_ok; bool balance_ok;
FAILIF (TALER_EXCHANGEDB_CKS_ADDED != FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
plugin->ensure_coin_known (plugin->cls, plugin->ensure_coin_known (plugin->cls,
&depos[i].coin, &depos[i].coin,
&known_coin_id, &known_coin_id,
&dph, &dph,
&agh)); &agh));
/**** INSERT REFRESH COMMITMENTS ****/ /**** INSERT REFRESH COMMITMENTS ****/
refresh[i].coin = depos[i].coin; refresh[i].coin = depos[i].coin;
RND_BLK (&refresh[i].coin_sig); RND_BLK (&refresh[i].coin_sig);
RND_BLK (&refresh[i].rc); RND_BLK (&refresh[i].rc);
refresh[i].amount_with_fee = value; refresh[i].amount_with_fee = value;
refresh[i].noreveal_index = MELT_NOREVEAL_INDEX; refresh[i].noreveal_index = MELT_NOREVEAL_INDEX;
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->do_melt (plugin->cls, plugin->do_melt (plugin->cls,
NULL, NULL,
&refresh[i], &refresh[i],
known_coin_id, known_coin_id,
&zombie_required, &zombie_required,
&balance_ok)); &balance_ok));
FAILIF (! balance_ok); FAILIF (! balance_ok);
FAILIF (zombie_required); FAILIF (zombie_required);
}
/**** INSERT REFRESH_REVEAL + TRANSFER_KEYS *****/
RND_BLK (&tprivs);
RND_BLK (&tpub);
RND_BLK(&melt_serial_id);
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_refresh_reveal (plugin->cls,
melt_serial_id,
MELT_NEW_COINS,
revealed_coins,
TALER_CNC_KAPPA - 1,
tprivs,
&tpub));
if (ROUNDS == i)
TALER_denom_sig_free (&depos[i].coin.denom_sig);
} }
/**** INSERT REFRESH_REVEAL + TRANSFER_KEYS *****/
RND_BLK (&tprivs);
RND_BLK (&tpub);
RND_BLK (&melt_serial_id);
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_refresh_reveal (plugin->cls,
melt_serial_id,
MELT_NEW_COINS,
revealed_coins,
TALER_CNC_KAPPA - 1,
tprivs,
&tpub));
if (ROUNDS == i)
TALER_denom_sig_free (&depos[i].coin.denom_sig);
}
/* End of benchmark setup */ /* End of benchmark setup */
GNUNET_free(perm); GNUNET_free (perm);
// commit // commit
FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
plugin->commit (plugin->cls)); plugin->commit (plugin->cls));
/**** CALL GET LINK DATA ****/ /**** CALL GET LINK DATA ****/
for (unsigned int r=0; r< ROUNDS; r++) for (unsigned int r = 0; r< ROUNDS; r++)
{ {
struct GNUNET_TIME_Absolute time; struct GNUNET_TIME_Absolute time;
struct GNUNET_TIME_Relative duration; struct GNUNET_TIME_Relative duration;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
time = GNUNET_TIME_absolute_get(); time = GNUNET_TIME_absolute_get ();
qs = plugin->get_link_data (plugin->cls, qs = plugin->get_link_data (plugin->cls,
&refresh[r].coin.coin_pub, &refresh[r].coin.coin_pub,
&handle_link_data_cb, &handle_link_data_cb,
@ -441,7 +441,8 @@ run (void *cls)
times = GNUNET_TIME_relative_add (times, times = GNUNET_TIME_relative_add (times,
duration); duration);
duration_sq = duration.rel_value_us * duration.rel_value_us; duration_sq = duration.rel_value_us * duration.rel_value_us;
GNUNET_assert (duration_sq / duration.rel_value_us == duration.rel_value_us); GNUNET_assert (duration_sq / duration.rel_value_us ==
duration.rel_value_us);
GNUNET_assert (sqrs + duration_sq >= sqrs); GNUNET_assert (sqrs + duration_sq >= sqrs);
sqrs += duration_sq; sqrs += duration_sq;
} }
@ -456,15 +457,15 @@ run (void *cls)
ROUNDS); ROUNDS);
avg_dbl = avg.rel_value_us; avg_dbl = avg.rel_value_us;
variance = sqrs - (avg_dbl * avg_dbl * ROUNDS); variance = sqrs - (avg_dbl * avg_dbl * ROUNDS);
fprintf(stdout, fprintf (stdout,
"%8llu ± %6.0f\n", "%8llu ± %6.0f\n",
(unsigned long long) avg.rel_value_us, (unsigned long long) avg.rel_value_us,
sqrt (variance / (ROUNDS-1))); sqrt (variance / (ROUNDS - 1)));
} }
result = 0; result = 0;
drop: drop:
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
plugin->drop_tables (plugin->cls)); plugin->drop_tables (plugin->cls));
cleanup: cleanup:
if (NULL != dkp) if (NULL != dkp)
destroy_denom_key_pair (dkp); destroy_denom_key_pair (dkp);
@ -484,13 +485,13 @@ cleanup:
cnt++) cnt++)
destroy_denom_key_pair (new_dkp[cnt]); destroy_denom_key_pair (new_dkp[cnt]);
GNUNET_free (new_dkp); GNUNET_free (new_dkp);
for (unsigned int i=0; i< ROUNDS; i++) for (unsigned int i = 0; i< ROUNDS; i++)
{ {
TALER_denom_sig_free (&depos[i].coin.denom_sig); TALER_denom_sig_free (&depos[i].coin.denom_sig);
} }
GNUNET_free(depos); GNUNET_free (depos);
GNUNET_free(ref); GNUNET_free (ref);
GNUNET_free(refresh); GNUNET_free (refresh);
dkp = NULL; dkp = NULL;
TALER_EXCHANGEDB_plugin_unload (plugin); TALER_EXCHANGEDB_plugin_unload (plugin);
plugin = NULL; plugin = NULL;

View File

@ -37,7 +37,7 @@ static int result;
*/ */
#define FAILIF(cond) \ #define FAILIF(cond) \
do { \ do { \
if (! (cond)) {break;} \ if (! (cond)) {break;} \
GNUNET_break (0); \ GNUNET_break (0); \
goto drop; \ goto drop; \
} while (0) } while (0)
@ -183,8 +183,6 @@ create_denom_key_pair (unsigned int size,
} }
/** /**
* Main function that will be run by the scheduler. * Main function that will be run by the scheduler.
* *
@ -201,19 +199,19 @@ run (void *cls)
struct TALER_EXCHANGEDB_CollectableBlindcoin cbc; struct TALER_EXCHANGEDB_CollectableBlindcoin cbc;
struct TALER_DenominationPublicKey *new_denom_pubs = NULL; struct TALER_DenominationPublicKey *new_denom_pubs = NULL;
struct GNUNET_TIME_Relative times = GNUNET_TIME_UNIT_ZERO; struct GNUNET_TIME_Relative times = GNUNET_TIME_UNIT_ZERO;
unsigned long long sqrs=0; unsigned long long sqrs = 0;
struct TALER_EXCHANGEDB_Deposit *depos=NULL; struct TALER_EXCHANGEDB_Deposit *depos = NULL;
struct TALER_EXCHANGEDB_Refund *ref=NULL; struct TALER_EXCHANGEDB_Refund *ref = NULL;
unsigned int *perm; unsigned int *perm;
unsigned long long duration_sq; unsigned long long duration_sq;
struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin;
struct TALER_ExchangeWithdrawValues alg_values = { struct TALER_ExchangeWithdrawValues alg_values = {
.cipher = TALER_DENOMINATION_RSA .cipher = TALER_DENOMINATION_RSA
}; };
ref = GNUNET_new_array (ROUNDS +1, ref = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Refund); struct TALER_EXCHANGEDB_Refund);
depos = GNUNET_new_array (ROUNDS +1, depos = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Deposit); struct TALER_EXCHANGEDB_Deposit);
if (NULL == if (NULL ==
@ -255,183 +253,183 @@ run (void *cls)
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount (CURRENCY ":0.000010", TALER_string_to_amount (CURRENCY ":0.000010",
&fees.refund)); &fees.refund));
//DENOMINATION // DENOMINATION
{ {
ZR_BLK (&cbc); ZR_BLK (&cbc);
//PAIR KEY LIST // PAIR KEY LIST
new_dkp = GNUNET_new_array (MELT_NEW_COINS, new_dkp = GNUNET_new_array (MELT_NEW_COINS,
struct DenomKeyPair *); struct DenomKeyPair *);
//PUBLIC KEY LIST // PUBLIC KEY LIST
new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS, new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_DenominationPublicKey); struct TALER_DenominationPublicKey);
//REFRESH REVEAL COIN LIST // REFRESH REVEAL COIN LIST
revealed_coins revealed_coins
= GNUNET_new_array (MELT_NEW_COINS, = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_EXCHANGEDB_RefreshRevealedCoin); struct TALER_EXCHANGEDB_RefreshRevealedCoin);
for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++) for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++)
{ {
struct GNUNET_TIME_Timestamp now; struct GNUNET_TIME_Timestamp now;
struct TALER_BlindedRsaPlanchet *rp; struct TALER_BlindedRsaPlanchet *rp;
struct TALER_BlindedPlanchet *bp; struct TALER_BlindedPlanchet *bp;
now = GNUNET_TIME_timestamp_get (); now = GNUNET_TIME_timestamp_get ();
//5 KEY PAIR // 5 KEY PAIR
new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE, new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE,
now, now,
&value, &value,
&fees); &fees);
GNUNET_assert (NULL != new_dkp[cnt]); GNUNET_assert (NULL != new_dkp[cnt]);
new_denom_pubs[cnt] = new_dkp[cnt]->pub; new_denom_pubs[cnt] = new_dkp[cnt]->pub;
ccoin = &revealed_coins[cnt]; ccoin = &revealed_coins[cnt];
bp = &ccoin->blinded_planchet; bp = &ccoin->blinded_planchet;
bp->cipher = TALER_DENOMINATION_RSA; bp->cipher = TALER_DENOMINATION_RSA;
rp = &bp->details.rsa_blinded_planchet; rp = &bp->details.rsa_blinded_planchet;
rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 (
GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_QUALITY_WEAK,
(RSA_KEY_SIZE / 8) - 1); (RSA_KEY_SIZE / 8) - 1);
rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size); rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
rp->blinded_msg, rp->blinded_msg,
rp->blinded_msg_size); rp->blinded_msg_size);
TALER_denom_pub_hash (&new_dkp[cnt]->pub, TALER_denom_pub_hash (&new_dkp[cnt]->pub,
&ccoin->h_denom_pub); &ccoin->h_denom_pub);
ccoin->exchange_vals = alg_values; ccoin->exchange_vals = alg_values;
TALER_coin_ev_hash (bp, TALER_coin_ev_hash (bp,
&ccoin->h_denom_pub, &ccoin->h_denom_pub,
&ccoin->coin_envelope_hash); &ccoin->coin_envelope_hash);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&ccoin->coin_sig, TALER_denom_sign_blinded (&ccoin->coin_sig,
&new_dkp[cnt]->priv, &new_dkp[cnt]->priv,
true, true,
bp)); bp));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_coin_ev_hash (bp, TALER_coin_ev_hash (bp,
&cbc.denom_pub_hash, &cbc.denom_pub_hash,
&cbc.h_coin_envelope)); &cbc.h_coin_envelope));
GNUNET_assert ( GNUNET_assert (
GNUNET_OK == GNUNET_OK ==
TALER_denom_sign_blinded ( TALER_denom_sign_blinded (
&cbc.sig, &cbc.sig,
&new_dkp[cnt]->priv, &new_dkp[cnt]->priv,
false, false,
bp)); bp));
} }
} }
perm = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_NONCE, perm = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_NONCE,
NUM_ROWS); NUM_ROWS);
//BEGIN // BEGIN
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
plugin->start (plugin->cls, plugin->start (plugin->cls,
"Transaction")); "Transaction"));
for (unsigned int j = 0; j < NUM_ROWS; j++) for (unsigned int j = 0; j < NUM_ROWS; j++)
{
/*** NEED TO INSERT REFRESH COMMITMENTS + ENSURECOIN ***/
union TALER_DenominationBlindingKeyP bks;
struct GNUNET_TIME_Timestamp deadline;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_ReservePublicKeyP reserve_pub;
struct TALER_CoinPubHashP c_hash;
unsigned int k = (unsigned int) rand () % 5;
unsigned int i = perm[j];
if (i >= ROUNDS)
i = ROUNDS; /* throw-away slot, do not keep around */
depos[i].deposit_fee = fees.deposit;
RND_BLK (&coin_pub);
RND_BLK (&c_hash);
RND_BLK (&reserve_pub);
RND_BLK (&cbc.reserve_sig);
TALER_denom_pub_hash (&new_dkp[k]->pub,
&cbc.denom_pub_hash);
deadline = GNUNET_TIME_timestamp_get ();
RND_BLK (&depos[i].coin.coin_pub);
TALER_denom_pub_hash (&new_dkp[k]->pub,
&depos[i].coin.denom_pub_hash);
GNUNET_assert (GNUNET_OK ==
TALER_denom_sig_unblind (&depos[i].coin.denom_sig,
&ccoin->coin_sig,
&bks,
&c_hash,
&alg_values,
&new_dkp[k]->pub));
RND_BLK (&depos[i].merchant_pub);
RND_BLK (&depos[i].csig);
RND_BLK (&depos[i].h_contract_terms);
RND_BLK (&depos[i].wire_salt);
depos[i].amount_with_fee = value;
depos[i].refund_deadline = deadline;
depos[i].wire_deadline = deadline;
depos[i].receiver_wire_account =
"payto://iban/DE67830654080004822650?receiver-name=Test";
TALER_merchant_wire_signature_hash (
"payto://iban/DE67830654080004822650?receiver-name=Test",
&depos[i].wire_salt,
&h_wire_wt);
cbc.reserve_pub = reserve_pub;
cbc.amount_with_fee = value;
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (CURRENCY,
&cbc.withdraw_fee));
{ {
/*** NEED TO INSERT REFRESH COMMITMENTS + ENSURECOIN ***/ /* INSERT WIRE TARGETS */
union TALER_DenominationBlindingKeyP bks; bool found;
struct GNUNET_TIME_Timestamp deadline; bool nonce_ok;
struct TALER_CoinSpendPublicKeyP coin_pub; bool balance_ok;
struct TALER_ReservePublicKeyP reserve_pub; uint64_t ruuid;
struct TALER_CoinPubHashP c_hash; struct GNUNET_TIME_Timestamp now;
unsigned int k = (unsigned int)rand()%5; now = GNUNET_TIME_timestamp_get ();
unsigned int i = perm[j]; FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
if (i >= ROUNDS) plugin->do_withdraw (plugin->cls,
i = ROUNDS; /* throw-away slot, do not keep around */ NULL,
depos[i].deposit_fee = fees.deposit; &cbc,
RND_BLK (&coin_pub); now,
RND_BLK (&c_hash); &found,
RND_BLK (&reserve_pub); &balance_ok,
RND_BLK (&cbc.reserve_sig); &nonce_ok,
TALER_denom_pub_hash (&new_dkp[k]->pub, &ruuid));
&cbc.denom_pub_hash);
deadline = GNUNET_TIME_timestamp_get ();
RND_BLK (&depos[i].coin.coin_pub);
TALER_denom_pub_hash (&new_dkp[k]->pub,
&depos[i].coin.denom_pub_hash);
GNUNET_assert (GNUNET_OK ==
TALER_denom_sig_unblind (&depos[i].coin.denom_sig,
&ccoin->coin_sig,
&bks,
&c_hash,
&alg_values,
&new_dkp[k]->pub));
RND_BLK (&depos[i].merchant_pub);
RND_BLK (&depos[i].csig);
RND_BLK (&depos[i].h_contract_terms);
RND_BLK (&depos[i].wire_salt);
depos[i].amount_with_fee = value;
depos[i].refund_deadline = deadline;
depos[i].wire_deadline = deadline;
depos[i].receiver_wire_account =
"payto://iban/DE67830654080004822650?receiver-name=Test";
TALER_merchant_wire_signature_hash (
"payto://iban/DE67830654080004822650?receiver-name=Test",
&depos[i].wire_salt,
&h_wire_wt);
cbc.reserve_pub = reserve_pub;
cbc.amount_with_fee = value;
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (CURRENCY,
&cbc.withdraw_fee));
{
/* INSERT WIRE TARGETS */
bool found;
bool nonce_ok;
bool balance_ok;
uint64_t ruuid;
struct GNUNET_TIME_Timestamp now;
now = GNUNET_TIME_timestamp_get ();
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->do_withdraw (plugin->cls,
NULL,
&cbc,
now,
&found,
&balance_ok,
&nonce_ok,
&ruuid));
}
{
/* ENSURE_COIN_KNOWN */
uint64_t known_coin_id;
struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh;
FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
plugin->ensure_coin_known (plugin->cls,
&depos[i].coin,
&known_coin_id,
&dph,
&agh));
refresh.coin = depos[i].coin;
RND_BLK (&refresh.coin_sig);
RND_BLK (&refresh.rc);
refresh.amount_with_fee = value;
refresh.noreveal_index = MELT_NOREVEAL_INDEX;
}
/*STORE INTO DEPOSIT*/
{
struct GNUNET_TIME_Timestamp now;
now = GNUNET_TIME_timestamp_get ();
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_deposit (plugin->cls,
now,
&depos[i]));
}
if (ROUNDS == i)
TALER_denom_sig_free (&depos[i].coin.denom_sig);
} }
{
/* ENSURE_COIN_KNOWN */
uint64_t known_coin_id;
struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHashP agh;
FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
plugin->ensure_coin_known (plugin->cls,
&depos[i].coin,
&known_coin_id,
&dph,
&agh));
refresh.coin = depos[i].coin;
RND_BLK (&refresh.coin_sig);
RND_BLK (&refresh.rc);
refresh.amount_with_fee = value;
refresh.noreveal_index = MELT_NOREVEAL_INDEX;
}
/*STORE INTO DEPOSIT*/
{
struct GNUNET_TIME_Timestamp now;
now = GNUNET_TIME_timestamp_get ();
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->insert_deposit (plugin->cls,
now,
&depos[i]));
}
if (ROUNDS == i)
TALER_denom_sig_free (&depos[i].coin.denom_sig);
}
/* End of benchmark setup */ /* End of benchmark setup */
GNUNET_free(perm); GNUNET_free (perm);
// commit // commit
FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
plugin->commit (plugin->cls)); plugin->commit (plugin->cls));
/**** CALL GET LINK DATA ****/ /**** CALL GET LINK DATA ****/
for (unsigned int r=0; r< ROUNDS; r++) for (unsigned int r = 0; r< ROUNDS; r++)
{ {
struct GNUNET_TIME_Absolute time; struct GNUNET_TIME_Absolute time;
struct GNUNET_TIME_Relative duration; struct GNUNET_TIME_Relative duration;
struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_MerchantPublicKeyP merchant_pub;
char *payto_uri; char *payto_uri;
time = GNUNET_TIME_absolute_get(); time = GNUNET_TIME_absolute_get ();
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->get_ready_deposit (plugin->cls, plugin->get_ready_deposit (plugin->cls,
0, 0,
@ -443,7 +441,8 @@ run (void *cls)
times = GNUNET_TIME_relative_add (times, times = GNUNET_TIME_relative_add (times,
duration); duration);
duration_sq = duration.rel_value_us * duration.rel_value_us; duration_sq = duration.rel_value_us * duration.rel_value_us;
GNUNET_assert (duration_sq / duration.rel_value_us == duration.rel_value_us); GNUNET_assert (duration_sq / duration.rel_value_us ==
duration.rel_value_us);
GNUNET_assert (sqrs + duration_sq >= sqrs); GNUNET_assert (sqrs + duration_sq >= sqrs);
sqrs += duration_sq; sqrs += duration_sq;
} }
@ -458,15 +457,15 @@ run (void *cls)
ROUNDS); ROUNDS);
avg_dbl = avg.rel_value_us; avg_dbl = avg.rel_value_us;
variance = sqrs - (avg_dbl * avg_dbl * ROUNDS); variance = sqrs - (avg_dbl * avg_dbl * ROUNDS);
fprintf(stdout, fprintf (stdout,
"%8llu ± %6.0f\n", "%8llu ± %6.0f\n",
(unsigned long long) avg.rel_value_us, (unsigned long long) avg.rel_value_us,
sqrt (variance / (ROUNDS-1))); sqrt (variance / (ROUNDS - 1)));
} }
result = 0; result = 0;
drop: drop:
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
plugin->drop_tables (plugin->cls)); plugin->drop_tables (plugin->cls));
cleanup: cleanup:
if (NULL != revealed_coins) if (NULL != revealed_coins)
{ {
@ -484,12 +483,12 @@ cleanup:
cnt++) cnt++)
destroy_denom_key_pair (new_dkp[cnt]); destroy_denom_key_pair (new_dkp[cnt]);
GNUNET_free (new_dkp); GNUNET_free (new_dkp);
for (unsigned int i=0; i< ROUNDS ; i++) for (unsigned int i = 0; i< ROUNDS; i++)
{ {
TALER_denom_sig_free (&depos[i].coin.denom_sig); TALER_denom_sig_free (&depos[i].coin.denom_sig);
} }
GNUNET_free(depos); GNUNET_free (depos);
GNUNET_free(ref); GNUNET_free (ref);
TALER_EXCHANGEDB_plugin_unload (plugin); TALER_EXCHANGEDB_plugin_unload (plugin);
plugin = NULL; plugin = NULL;
} }

View File

@ -36,7 +36,7 @@ static int result;
*/ */
#define FAILIF(cond) \ #define FAILIF(cond) \
do { \ do { \
if (! (cond)) {break;} \ if (! (cond)) {break;} \
GNUNET_break (0); \ GNUNET_break (0); \
goto drop; \ goto drop; \
} while (0) } while (0)
@ -172,6 +172,8 @@ create_denom_key_pair (unsigned int size,
} }
return dkp; return dkp;
} }
/** /**
* Callback invoked with information about refunds applicable * Callback invoked with information about refunds applicable
* to a particular coin. * to a particular coin.
@ -209,7 +211,7 @@ run (void *cls)
const uint32_t num_partitions = 10; const uint32_t num_partitions = 10;
struct DenomKeyPair *dkp = NULL; struct DenomKeyPair *dkp = NULL;
struct GNUNET_TIME_Timestamp ts; struct GNUNET_TIME_Timestamp ts;
struct TALER_EXCHANGEDB_Deposit *depos=NULL; struct TALER_EXCHANGEDB_Deposit *depos = NULL;
struct GNUNET_TIME_Timestamp deadline; struct GNUNET_TIME_Timestamp deadline;
struct TALER_Amount value; struct TALER_Amount value;
union TALER_DenominationBlindingKeyP bks; union TALER_DenominationBlindingKeyP bks;
@ -217,18 +219,18 @@ run (void *cls)
struct TALER_EXCHANGEDB_CollectableBlindcoin cbc; struct TALER_EXCHANGEDB_CollectableBlindcoin cbc;
struct TALER_ExchangeWithdrawValues alg_values = { struct TALER_ExchangeWithdrawValues alg_values = {
.cipher = TALER_DENOMINATION_RSA .cipher = TALER_DENOMINATION_RSA
}; };
struct GNUNET_TIME_Relative times = GNUNET_TIME_UNIT_ZERO; struct GNUNET_TIME_Relative times = GNUNET_TIME_UNIT_ZERO;
unsigned long long sqrs = 0; unsigned long long sqrs = 0;
struct TALER_EXCHANGEDB_Refund *ref=NULL; struct TALER_EXCHANGEDB_Refund *ref = NULL;
unsigned int *perm; unsigned int *perm;
unsigned long long duration_sq; unsigned long long duration_sq;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin;
struct TALER_DenominationPublicKey *new_denom_pubs = NULL; struct TALER_DenominationPublicKey *new_denom_pubs = NULL;
ref = GNUNET_new_array (ROUNDS +1, ref = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Refund); struct TALER_EXCHANGEDB_Refund);
depos = GNUNET_new_array (ROUNDS +1, depos = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Deposit); struct TALER_EXCHANGEDB_Deposit);
ZR_BLK (&cbc); ZR_BLK (&cbc);
@ -276,66 +278,66 @@ run (void *cls)
ts = GNUNET_TIME_timestamp_get (); ts = GNUNET_TIME_timestamp_get ();
deadline = GNUNET_TIME_timestamp_get (); deadline = GNUNET_TIME_timestamp_get ();
//DENOMINATION // DENOMINATION
{ {
//PAIR KEY LIST // PAIR KEY LIST
new_dkp = GNUNET_new_array (MELT_NEW_COINS, new_dkp = GNUNET_new_array (MELT_NEW_COINS,
struct DenomKeyPair *); struct DenomKeyPair *);
//PUBLIC KEY LIST // PUBLIC KEY LIST
new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS, new_denom_pubs = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_DenominationPublicKey); struct TALER_DenominationPublicKey);
//REFRESH REVEAL COIN LIST // REFRESH REVEAL COIN LIST
revealed_coins revealed_coins
= GNUNET_new_array (MELT_NEW_COINS, = GNUNET_new_array (MELT_NEW_COINS,
struct TALER_EXCHANGEDB_RefreshRevealedCoin); struct TALER_EXCHANGEDB_RefreshRevealedCoin);
for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++) for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++)
{ {
struct GNUNET_TIME_Timestamp now; struct GNUNET_TIME_Timestamp now;
struct TALER_BlindedRsaPlanchet *rp; struct TALER_BlindedRsaPlanchet *rp;
struct TALER_BlindedPlanchet *bp; struct TALER_BlindedPlanchet *bp;
now = GNUNET_TIME_timestamp_get (); now = GNUNET_TIME_timestamp_get ();
//5 KEY PAIR // 5 KEY PAIR
new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE, new_dkp[cnt] = create_denom_key_pair (RSA_KEY_SIZE,
now, now,
&value, &value,
&fees); &fees);
GNUNET_assert (NULL != new_dkp[cnt]); GNUNET_assert (NULL != new_dkp[cnt]);
new_denom_pubs[cnt] = new_dkp[cnt]->pub; new_denom_pubs[cnt] = new_dkp[cnt]->pub;
ccoin = &revealed_coins[cnt]; ccoin = &revealed_coins[cnt];
bp = &ccoin->blinded_planchet; bp = &ccoin->blinded_planchet;
bp->cipher = TALER_DENOMINATION_RSA; bp->cipher = TALER_DENOMINATION_RSA;
rp = &bp->details.rsa_blinded_planchet; rp = &bp->details.rsa_blinded_planchet;
rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 (
GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_QUALITY_WEAK,
(RSA_KEY_SIZE / 8) - 1); (RSA_KEY_SIZE / 8) - 1);
rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size); rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
rp->blinded_msg, rp->blinded_msg,
rp->blinded_msg_size); rp->blinded_msg_size);
TALER_denom_pub_hash (&new_dkp[cnt]->pub, TALER_denom_pub_hash (&new_dkp[cnt]->pub,
&ccoin->h_denom_pub); &ccoin->h_denom_pub);
ccoin->exchange_vals = alg_values; ccoin->exchange_vals = alg_values;
TALER_coin_ev_hash (bp, TALER_coin_ev_hash (bp,
&ccoin->h_denom_pub, &ccoin->h_denom_pub,
&ccoin->coin_envelope_hash); &ccoin->coin_envelope_hash);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&ccoin->coin_sig, TALER_denom_sign_blinded (&ccoin->coin_sig,
&new_dkp[cnt]->priv, &new_dkp[cnt]->priv,
true, true,
bp)); bp));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_coin_ev_hash (bp, TALER_coin_ev_hash (bp,
&cbc.denom_pub_hash, &cbc.denom_pub_hash,
&cbc.h_coin_envelope)); &cbc.h_coin_envelope));
GNUNET_assert ( GNUNET_assert (
GNUNET_OK == GNUNET_OK ==
TALER_denom_sign_blinded ( TALER_denom_sign_blinded (
&cbc.sig, &cbc.sig,
&new_dkp[cnt]->priv, &new_dkp[cnt]->priv,
false, false,
bp)); bp));
} }
} }
perm = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_NONCE, perm = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_NONCE,
@ -344,10 +346,10 @@ run (void *cls)
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
plugin->start (plugin->cls, plugin->start (plugin->cls,
"Transaction")); "Transaction"));
for (unsigned int j=0; j< NUM_ROWS; j++) for (unsigned int j = 0; j< NUM_ROWS; j++)
{ {
unsigned int i = perm[j]; unsigned int i = perm[j];
unsigned int k = (unsigned int)rand()%5; unsigned int k = (unsigned int) rand () % 5;
if (i >= ROUNDS) if (i >= ROUNDS)
i = ROUNDS; /* throw-away slot, do not keep around */ i = ROUNDS; /* throw-away slot, do not keep around */
RND_BLK (&coin_pub); RND_BLK (&coin_pub);
@ -375,15 +377,15 @@ run (void *cls)
depos[i].receiver_wire_account = depos[i].receiver_wire_account =
"payto://iban/DE67830654080004822650?receiver-name=Test"; "payto://iban/DE67830654080004822650?receiver-name=Test";
TALER_merchant_wire_signature_hash ( TALER_merchant_wire_signature_hash (
"payto://iban/DE67830654080004822650?receiver-name=Test", "payto://iban/DE67830654080004822650?receiver-name=Test",
&depos[i].wire_salt, &depos[i].wire_salt,
&h_wire_wt); &h_wire_wt);
depos[i].timestamp = ts; depos[i].timestamp = ts;
uint64_t known_coin_id; uint64_t known_coin_id;
{//ENSURE_COIN_KNOWN {// ENSURE_COIN_KNOWN
struct TALER_DenominationHashP dph; struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh; struct TALER_AgeCommitmentHashP agh;
FAILIF (TALER_EXCHANGEDB_CKS_ADDED != FAILIF (TALER_EXCHANGEDB_CKS_ADDED !=
plugin->ensure_coin_known (plugin->cls, plugin->ensure_coin_known (plugin->cls,
&depos[i].coin, &depos[i].coin,
@ -409,7 +411,7 @@ run (void *cls)
bool conflict; bool conflict;
ref[i].coin = depos[i].coin; ref[i].coin = depos[i].coin;
ref[i].details.merchant_pub = depos[i].merchant_pub; ref[i].details.merchant_pub = depos[i].merchant_pub;
RND_BLK(&ref[i].details.merchant_sig); RND_BLK (&ref[i].details.merchant_sig);
ref[i].details.h_contract_terms = depos[i].h_contract_terms; ref[i].details.h_contract_terms = depos[i].h_contract_terms;
ref[i].coin.coin_pub = depos[i].coin.coin_pub; ref[i].coin.coin_pub = depos[i].coin.coin_pub;
ref[i].details.rtransaction_id = i; ref[i].details.rtransaction_id = i;
@ -454,7 +456,8 @@ run (void *cls)
times = GNUNET_TIME_relative_add (times, times = GNUNET_TIME_relative_add (times,
duration); duration);
duration_sq = duration.rel_value_us * duration.rel_value_us; duration_sq = duration.rel_value_us * duration.rel_value_us;
GNUNET_assert (duration_sq / duration.rel_value_us == duration.rel_value_us); GNUNET_assert (duration_sq / duration.rel_value_us ==
duration.rel_value_us);
GNUNET_assert (sqrs + duration_sq >= sqrs); GNUNET_assert (sqrs + duration_sq >= sqrs);
sqrs += duration_sq; sqrs += duration_sq;
} }
@ -468,15 +471,15 @@ run (void *cls)
ROUNDS); ROUNDS);
avg_dbl = avg.rel_value_us; avg_dbl = avg.rel_value_us;
variance = sqrs - (avg_dbl * avg_dbl * ROUNDS); variance = sqrs - (avg_dbl * avg_dbl * ROUNDS);
fprintf(stdout, fprintf (stdout,
"%8llu ± %6.0f\n", "%8llu ± %6.0f\n",
(unsigned long long) avg.rel_value_us, (unsigned long long) avg.rel_value_us,
sqrt (variance / (ROUNDS-1))); sqrt (variance / (ROUNDS - 1)));
} }
result = 0; result = 0;
drop: drop:
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
plugin->drop_tables (plugin->cls)); plugin->drop_tables (plugin->cls));
cleanup: cleanup:
if (NULL != dkp) if (NULL != dkp)
destroy_denom_key_pair (dkp); destroy_denom_key_pair (dkp);
@ -496,12 +499,12 @@ cleanup:
cnt++) cnt++)
destroy_denom_key_pair (new_dkp[cnt]); destroy_denom_key_pair (new_dkp[cnt]);
GNUNET_free (new_dkp); GNUNET_free (new_dkp);
for (unsigned int i=0; i< ROUNDS +1 ; i++) for (unsigned int i = 0; i< ROUNDS + 1; i++)
{ {
TALER_denom_sig_free (&depos[i].coin.denom_sig); TALER_denom_sig_free (&depos[i].coin.denom_sig);
} }
GNUNET_free(depos); GNUNET_free (depos);
GNUNET_free(ref); GNUNET_free (ref);
dkp = NULL; dkp = NULL;
TALER_EXCHANGEDB_plugin_unload (plugin); TALER_EXCHANGEDB_plugin_unload (plugin);
plugin = NULL; plugin = NULL;

View File

@ -435,6 +435,13 @@ struct TALER_AgeCommitmentPublicKeyP
#endif #endif
}; };
/*
* @brief Hash to represent the commitment to n*kappa blinded keys during a age-withdrawal.
*/
struct TALER_AgeWithdrawCommitmentHashP
{
struct GNUNET_HashCode hash;
};
/** /**
* @brief Type of online public keys used by the wallet to establish a purse and the associated contract meta data. * @brief Type of online public keys used by the wallet to establish a purse and the associated contract meta data.
@ -1259,13 +1266,13 @@ struct TALER_AgeAttestation
#endif #endif
}; };
extern const struct TALER_AgeCommitmentHash TALER_ZeroAgeCommitmentHash; extern const struct TALER_AgeCommitmentHashP TALER_ZeroAgeCommitmentHash;
#define TALER_AgeCommitmentHash_isNullOrZero(ph) ((NULL == ph) || \ #define TALER_AgeCommitmentHash_isNullOrZero(ph) ((NULL == ph) || \
(0 == memcmp (ph, \ (0 == memcmp (ph, \
& \ & \
TALER_ZeroAgeCommitmentHash, \ TALER_ZeroAgeCommitmentHash, \
sizeof(struct \ sizeof(struct \
TALER_AgeCommitmentHash)))) TALER_AgeCommitmentHashP))))
/** /**
* @brief Type of public signing keys for verifying blindly signed coins. * @brief Type of public signing keys for verifying blindly signed coins.
@ -1448,7 +1455,7 @@ struct TALER_CoinPublicInfo
* Hash of the age commitment. If no age commitment was provided, it must be * Hash of the age commitment. If no age commitment was provided, it must be
* set to all zeroes. * set to all zeroes.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
/** /**
* True, if age commitment is not applicable. * True, if age commitment is not applicable.
@ -1624,7 +1631,7 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig);
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_denom_blind (const struct TALER_DenominationPublicKey *dk, TALER_denom_blind (const struct TALER_DenominationPublicKey *dk,
const union TALER_DenominationBlindingKeyP *coin_bks, const union TALER_DenominationBlindingKeyP *coin_bks,
const struct TALER_AgeCommitmentHash *age_commitment_hash, const struct TALER_AgeCommitmentHashP *age_commitment_hash,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_CoinPubHashP *c_hash, struct TALER_CoinPubHashP *c_hash,
@ -1873,7 +1880,7 @@ TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
*/ */
void void
TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub, TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_AgeCommitmentHash *age_commitment_hash, const struct TALER_AgeCommitmentHashP *age_commitment_hash,
struct TALER_CoinPubHashP *coin_h); struct TALER_CoinPubHashP *coin_h);
@ -1928,7 +1935,7 @@ struct TALER_FreshCoin
/** /**
* Optional hash of an age commitment bound to this coin, maybe NULL. * Optional hash of an age commitment bound to this coin, maybe NULL.
*/ */
const struct TALER_AgeCommitmentHash *h_age_commitment; const struct TALER_AgeCommitmentHashP *h_age_commitment;
}; };
@ -2111,7 +2118,7 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
const union TALER_DenominationBlindingKeyP *bks, const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
const struct TALER_AgeCommitmentHash *ach, const struct TALER_AgeCommitmentHashP *ach,
struct TALER_CoinPubHashP *c_hash, struct TALER_CoinPubHashP *c_hash,
struct TALER_PlanchetDetail *pd); struct TALER_PlanchetDetail *pd);
@ -2155,7 +2162,7 @@ TALER_planchet_to_coin (
const struct TALER_BlindedDenominationSignature *blind_sig, const struct TALER_BlindedDenominationSignature *blind_sig,
const union TALER_DenominationBlindingKeyP *bks, const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
const struct TALER_AgeCommitmentHash *ach, const struct TALER_AgeCommitmentHashP *ach,
const struct TALER_CoinPubHashP *c_hash, const struct TALER_CoinPubHashP *c_hash,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_FreshCoin *coin); struct TALER_FreshCoin *coin);
@ -3110,7 +3117,7 @@ TALER_wallet_purse_deposit_sign (
const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig); struct TALER_CoinSpendSignatureP *coin_sig);
@ -3133,7 +3140,7 @@ TALER_wallet_purse_deposit_verify (
const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig); const struct TALER_CoinSpendSignatureP *coin_sig);
@ -3469,7 +3476,7 @@ TALER_wallet_deposit_sign (
const struct TALER_Amount *deposit_fee, const struct TALER_Amount *deposit_fee,
const struct TALER_MerchantWireHashP *h_wire, const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_ExtensionPolicyHashP *h_policy, const struct TALER_ExtensionPolicyHashP *h_policy,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
struct GNUNET_TIME_Timestamp wallet_timestamp, struct GNUNET_TIME_Timestamp wallet_timestamp,
@ -3502,7 +3509,7 @@ TALER_wallet_deposit_verify (
const struct TALER_Amount *deposit_fee, const struct TALER_Amount *deposit_fee,
const struct TALER_MerchantWireHashP *h_wire, const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_ExtensionPolicyHashP *h_policy, const struct TALER_ExtensionPolicyHashP *h_policy,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
struct GNUNET_TIME_Timestamp wallet_timestamp, struct GNUNET_TIME_Timestamp wallet_timestamp,
@ -3529,7 +3536,7 @@ TALER_wallet_melt_sign (
const struct TALER_Amount *melt_fee, const struct TALER_Amount *melt_fee,
const struct TALER_RefreshCommitmentP *rc, const struct TALER_RefreshCommitmentP *rc,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig); struct TALER_CoinSpendSignatureP *coin_sig);
@ -3552,7 +3559,7 @@ TALER_wallet_melt_verify (
const struct TALER_Amount *melt_fee, const struct TALER_Amount *melt_fee,
const struct TALER_RefreshCommitmentP *rc, const struct TALER_RefreshCommitmentP *rc,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig); const struct TALER_CoinSpendSignatureP *coin_sig);
@ -3630,6 +3637,40 @@ TALER_wallet_withdraw_verify (
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig); const struct TALER_ReserveSignatureP *reserve_sig);
/**
* Sign age-withdraw request.
*
* @param h_commitment hash all n*kappa blinded coins in the commitment for the age-withdraw
* @param amount_with_fee amount to debit the reserve for
* @param max_age_group maximum age group that the withdrawn coins must be restricted to
* @param reserve_priv private key to sign with
* @param[out] reserve_sig resulting signature
*/
void
TALER_wallet_age_withdraw_sign (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
const struct TALER_Amount *amount_with_fee,
uint32_t max_age_group,
const struct TALER_ReservePrivateKeyP *reserve_priv,
struct TALER_ReserveSignatureP *reserve_sig);
/**
* Verify an age-withdraw request.
*
* @param h_commitment hash all n*kappa blinded coins in the commitment for the age-withdraw
* @param amount_with_fee amount to debit the reserve for
* @param max_age_group maximum age group that the withdrawn coins must be restricted to
* @param reserve_pub public key of the reserve
* @param reserve_sig resulting signature
* @return #GNUNET_OK if the signature is valid
*/
enum GNUNET_GenericReturnValue
TALER_wallet_age_withdraw_verify (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
const struct TALER_Amount *amount_with_fee,
uint32_t max_age_group,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig);
/** /**
* Verify exchange melt confirmation. * Verify exchange melt confirmation.
@ -5687,7 +5728,7 @@ struct TALER_AgeCommitmentProof
void void
TALER_age_commitment_hash ( TALER_age_commitment_hash (
const struct TALER_AgeCommitment *commitment, const struct TALER_AgeCommitment *commitment,
struct TALER_AgeCommitmentHash *hash); struct TALER_AgeCommitmentHashP *hash);
/** /**
@ -5738,7 +5779,7 @@ TALER_age_commitment_attest (
/** /**
* @brief Verify the attestation for an given age and age commitment * @brief Verify the attestation for a given age and age commitment
* *
* @param commitment The age commitment that went into the attestation. Only the public keys are needed. * @param commitment The age commitment that went into the attestation. Only the public keys are needed.
* @param age Age (not age group) for which the an attestation should be done * @param age Age (not age group) for which the an attestation should be done
@ -5752,6 +5793,24 @@ TALER_age_commitment_verify (
const struct TALER_AgeAttestation *attest); const struct TALER_AgeAttestation *attest);
/**
* Create age-withdraw confirmation signature.
*
* @param scb function to call to create the signature
* @param awch age-withdraw commitment that identifies the n*kappa blinded coins
* @param noreveal_index gamma cut-and-choose value chosen by the exchange
* @param[out] pub where to write the exchange public key
* @param[out] sig where to write the exchange signature
* @return #TALER_EC_NONE on success
*/
enum TALER_ErrorCode
TALER_exchange_online_age_withdraw_confirmation_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
uint32_t noreveal_index,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig);
/** /**
* @brief helper function to free memory of a struct TALER_AgeCommitment * @brief helper function to free memory of a struct TALER_AgeCommitment
* *

View File

@ -844,7 +844,7 @@ struct TALER_EXCHANGE_CoinDepositDetail
/** /**
* Hash over the age commitment of the coin. * Hash over the age commitment of the coin.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
/** /**
* The coins public key. * The coins public key.
@ -2155,7 +2155,7 @@ struct TALER_EXCHANGE_WithdrawCoinInput
/** /**
* Age commitment for the coin. * Age commitment for the coin.
*/ */
const struct TALER_AgeCommitmentHash *ach; const struct TALER_AgeCommitmentHashP *ach;
}; };
@ -2579,7 +2579,7 @@ struct TALER_EXCHANGE_RefreshData
* might be NULL. * might be NULL.
*/ */
const struct TALER_AgeCommitmentProof *melt_age_commitment_proof; const struct TALER_AgeCommitmentProof *melt_age_commitment_proof;
const struct TALER_AgeCommitmentHash *melt_h_age_commitment; const struct TALER_AgeCommitmentHashP *melt_h_age_commitment;
/** /**
* amount specifying how much the coin will contribute to the melt * amount specifying how much the coin will contribute to the melt
@ -2752,7 +2752,7 @@ struct TALER_EXCHANGE_RevealedCoinInfo
* Age commitment and its hash of the coin, might be NULL. * Age commitment and its hash of the coin, might be NULL.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof *age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHashP *h_age_commitment;
/** /**
* Blinding keys used to blind the fresh coin. * Blinding keys used to blind the fresh coin.
@ -2896,7 +2896,7 @@ struct TALER_EXCHANGE_LinkedCoinInfo
* Age commitment and its hash, if applicable. Might be NULL. * Age commitment and its hash, if applicable. Might be NULL.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof *age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHashP *h_age_commitment;
/** /**
* Master secret of this coin. * Master secret of this coin.

View File

@ -391,7 +391,7 @@ struct TALER_EXCHANGEDB_TableData
struct struct
{ {
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_AgeCommitmentHash age_hash; struct TALER_AgeCommitmentHashP age_hash;
uint64_t denominations_serial; uint64_t denominations_serial;
struct TALER_DenominationSignature denom_sig; struct TALER_DenominationSignature denom_sig;
} known_coins; } known_coins;
@ -1094,7 +1094,7 @@ struct TALER_EXCHANGEDB_AgeWithdrawCommitment
* The exchange's signature of the response. * The exchange's signature of the response.
*/ */
struct TALER_ExchangeSignatureP sig; struct TALER_ExchangeSignatureP sig;
} };
/** /**
@ -1668,7 +1668,7 @@ struct TALER_EXCHANGEDB_DepositListEntry
* Age commitment hash, if applicable to the denomination. Should be all * Age commitment hash, if applicable to the denomination. Should be all
* zeroes if age commitment is not applicable to the denonimation. * zeroes if age commitment is not applicable to the denonimation.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
/** /**
* true, if age commitment is not applicable * true, if age commitment is not applicable
@ -1946,7 +1946,7 @@ struct TALER_EXCHANGEDB_PurseDepositListEntry
* Hash of the age commitment used to sign the coin, if age restriction was * Hash of the age commitment used to sign the coin, if age restriction was
* applicable to the denomination. * applicable to the denomination.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
/** /**
* Set to true if the coin was refunded. * Set to true if the coin was refunded.
@ -2053,7 +2053,7 @@ struct TALER_EXCHANGEDB_PurseDeposit
* applicable to the denomination. May be all zeroes if no age restriction * applicable to the denomination. May be all zeroes if no age restriction
* applies. * applies.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
/** /**
* Set to true if @e h_age_commitment is not available. * Set to true if @e h_age_commitment is not available.
@ -2533,7 +2533,7 @@ typedef enum GNUNET_GenericReturnValue
void *cls, void *cls,
uint64_t rowid, uint64_t rowid,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *amount_with_fee,
@ -3693,6 +3693,45 @@ struct TALER_EXCHANGEDB_Plugin
bool *conflict, bool *conflict,
bool *nonce_reuse); bool *nonce_reuse);
/**
* Locate the response for a age-withdraw request under a hash that uniquely
* identifies the age-withdraw operation. Used to ensure idempotency of the
* request.
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param reserve_pub public key of the reserve for which the age-withdraw request is made
* @param ach hash that uniquely identifies the age-withdraw operation
* @param[out] awc corresponding details of the previous age-withdraw request if an entry was found
* @return statement execution status
*/
enum GNUNET_DB_QueryStatus
(*get_age_withdraw_info)(void *cls,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_AgeWithdrawCommitmentHashP *ach,
struct TALER_EXCHANGEDB_AgeWithdrawCommitment *awc);
/**
* Perform an age-withdraw operation, checking for sufficient balance
* and possibly persisting the withdrawal details.
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
* @param commitment corresponding commitment for the age-withdraw
* @param now current time (rounded)
* @param[out] found set to true if the reserve was found
* @param[out] balance_ok set to true if the balance was sufficient
* @param[out] ruuid set to the reserve's UUID (reserves table row)
* @return query execution status
*/
enum GNUNET_DB_QueryStatus
(*do_age_withdraw)(
void *cls,
const struct TALER_EXCHANGEDB_AgeWithdrawCommitment *commitment,
struct GNUNET_TIME_Timestamp now,
bool *found,
bool *balance_ok,
uint64_t *ruuid);
/** /**
* Retrieve the details to a policy given by its hash_code * Retrieve the details to a policy given by its hash_code
* *
@ -4019,7 +4058,7 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinPublicInfo *coin,
uint64_t *known_coin_id, uint64_t *known_coin_id,
struct TALER_DenominationHashP *denom_pub_hash, struct TALER_DenominationHashP *denom_pub_hash,
struct TALER_AgeCommitmentHash *age_hash); struct TALER_AgeCommitmentHashP *age_hash);
/** /**
@ -6105,7 +6144,7 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_Amount *amount, struct TALER_Amount *amount,
struct TALER_DenominationHashP *h_denom_pub, struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac, struct TALER_AgeCommitmentHashP *phac,
struct TALER_CoinSpendSignatureP *coin_sig, struct TALER_CoinSpendSignatureP *coin_sig,
char **partner_url); char **partner_url);
@ -6648,6 +6687,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param is_active true to enable, false to set as inactive * @param is_active true to enable, false to set as inactive
* @param read_only true to set read-only access * @param read_only true to set read-only access
* @param last_change when was the change made effective * @param last_change when was the change made effective
* @param[out] previous_change when was the previous change made
* @return database transaction status * @return database transaction status
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
@ -6658,7 +6698,8 @@ struct TALER_EXCHANGEDB_Plugin
const char *decider_name, const char *decider_name,
bool is_active, bool is_active,
bool read_only, bool read_only,
struct GNUNET_TIME_Absolute last_change); struct GNUNET_TIME_Timestamp last_change,
struct GNUNET_TIME_Timestamp *previous_change);
/** /**
@ -6773,6 +6814,9 @@ struct TALER_EXCHANGEDB_Plugin
* @param justification human-readable text justifying the decision * @param justification human-readable text justifying the decision
* @param decider_pub public key of the staff member * @param decider_pub public key of the staff member
* @param decider_sig signature of the staff member * @param decider_sig signature of the staff member
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
* @param[out] last_date set to the previous decision time;
* the INSERT is not performed if @a last_date is not before @a decision_time
* @return database transaction status * @return database transaction status
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
@ -6781,10 +6825,12 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_PaytoHashP *h_payto, const struct TALER_PaytoHashP *h_payto,
const struct TALER_Amount *new_threshold, const struct TALER_Amount *new_threshold,
enum TALER_AmlDecisionState new_status, enum TALER_AmlDecisionState new_status,
struct GNUNET_TIME_Absolute decision_time, struct GNUNET_TIME_Timestamp decision_time,
const char *justification, const char *justification,
const struct TALER_AmlOfficerPublicKeyP *decider_pub, const struct TALER_AmlOfficerPublicKeyP *decider_pub,
const struct TALER_AmlOfficerSignatureP *decider_sig); const struct TALER_AmlOfficerSignatureP *decider_sig,
bool *invalid_officer,
struct GNUNET_TIME_Timestamp *last_date);
}; };

View File

@ -73,8 +73,12 @@ enum TALER_KYCLOGIC_KycTriggerEvent
/** /**
* Reserve is being closed by force. * Reserve is being closed by force.
*/ */
TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE = 4 TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE = 4,
/**
* Customer withdraws coins via age-withdraw.
*/
TALER_KYCLOGIC_KYC_TRIGGER_AGE_WITHDRAW = 5,
}; };

View File

@ -2958,7 +2958,7 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
op (deposit_fee_amount, const struct TALER_Amount) \ op (deposit_fee_amount, const struct TALER_Amount) \
op (age_commitment, const struct TALER_AgeCommitment) \ op (age_commitment, const struct TALER_AgeCommitment) \
op (age_commitment_proof, const struct TALER_AgeCommitmentProof) \ op (age_commitment_proof, const struct TALER_AgeCommitmentProof) \
op (h_age_commitment, const struct TALER_AgeCommitmentHash) \ op (h_age_commitment, const struct TALER_AgeCommitmentHashP) \
op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \ op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \
op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \
op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues) \ op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues) \

View File

@ -180,6 +180,7 @@ TALER_KYCLOGIC_kyc_trigger_from_string (const char *trigger_s,
enum TALER_KYCLOGIC_KycTriggerEvent out; enum TALER_KYCLOGIC_KycTriggerEvent out;
} map [] = { } map [] = {
{ "withdraw", TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW }, { "withdraw", TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW },
{ "age-withdraw", TALER_KYCLOGIC_KYC_TRIGGER_AGE_WITHDRAW },
{ "deposit", TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT }, { "deposit", TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT },
{ "merge", TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE }, { "merge", TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE },
{ "balance", TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE }, { "balance", TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE },
@ -208,6 +209,8 @@ TALER_KYCLOGIC_kyc_trigger2s (enum TALER_KYCLOGIC_KycTriggerEvent trigger)
{ {
case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW: case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW:
return "withdraw"; return "withdraw";
case TALER_KYCLOGIC_KYC_TRIGGER_AGE_WITHDRAW:
return "age-withdraw";
case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT: case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT:
return "deposit"; return "deposit";
case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE: case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE:

View File

@ -21,6 +21,7 @@ libtalerexchange_la_LDFLAGS = \
-version-info 5:0:0 \ -version-info 5:0:0 \
-no-undefined -no-undefined
libtalerexchange_la_SOURCES = \ libtalerexchange_la_SOURCES = \
exchange_api_add_aml_decision.c \
exchange_api_auditor_add_denomination.c \ exchange_api_auditor_add_denomination.c \
exchange_api_batch_deposit.c \ exchange_api_batch_deposit.c \
exchange_api_batch_withdraw.c \ exchange_api_batch_withdraw.c \
@ -37,6 +38,7 @@ libtalerexchange_la_SOURCES = \
exchange_api_kyc_proof.c \ exchange_api_kyc_proof.c \
exchange_api_kyc_wallet.c \ exchange_api_kyc_wallet.c \
exchange_api_link.c \ exchange_api_link.c \
exchange_api_management_add_partner.c \
exchange_api_management_auditor_disable.c \ exchange_api_management_auditor_disable.c \
exchange_api_management_auditor_enable.c \ exchange_api_management_auditor_enable.c \
exchange_api_management_drain_profits.c \ exchange_api_management_drain_profits.c \
@ -47,6 +49,7 @@ libtalerexchange_la_SOURCES = \
exchange_api_management_revoke_signing_key.c \ exchange_api_management_revoke_signing_key.c \
exchange_api_management_set_global_fee.c \ exchange_api_management_set_global_fee.c \
exchange_api_management_set_wire_fee.c \ exchange_api_management_set_wire_fee.c \
exchange_api_management_update_aml_officer.c \
exchange_api_management_wire_disable.c \ exchange_api_management_wire_disable.c \
exchange_api_management_wire_enable.c \ exchange_api_management_wire_enable.c \
exchange_api_melt.c \ exchange_api_melt.c \

View File

@ -136,7 +136,7 @@ TALER_EXCHANGE_add_aml_decision (
TALER_EXCHANGE_AddAmlDecisionCallback cb, TALER_EXCHANGE_AddAmlDecisionCallback cb,
void *cb_cls) void *cb_cls)
{ {
struct TALER_AmlOfficerPrivateKeyP officer_pub; struct TALER_AmlOfficerPublicKeyP officer_pub;
struct TALER_AmlOfficerSignatureP officer_sig; struct TALER_AmlOfficerSignatureP officer_sig;
struct TALER_EXCHANGE_AddAmlDecision *wh; struct TALER_EXCHANGE_AddAmlDecision *wh;
CURL *eh; CURL *eh;
@ -146,6 +146,7 @@ TALER_EXCHANGE_add_aml_decision (
&officer_pub.eddsa_pub); &officer_pub.eddsa_pub);
TALER_officer_aml_decision_sign (justification, TALER_officer_aml_decision_sign (justification,
decision_time, decision_time,
new_threshold,
h_payto, h_payto,
new_state, new_state,
officer_priv, officer_priv,
@ -166,7 +167,7 @@ TALER_EXCHANGE_add_aml_decision (
sizeof (opus)); sizeof (opus));
*end = '\0'; *end = '\0';
GNUNET_asprintf (&path, GNUNET_asprintf (&path,
"aml-decision/%s", "aml/%s/decision",
opus); opus);
wh->url = TALER_url_join (url, wh->url = TALER_url_join (url,
path, path,
@ -187,8 +188,8 @@ TALER_EXCHANGE_add_aml_decision (
&officer_sig), &officer_sig),
GNUNET_JSON_pack_data_auto ("h_payto", GNUNET_JSON_pack_data_auto ("h_payto",
h_payto), h_payto),
GNUNET_JSON_pack_data_uint64 ("state", GNUNET_JSON_pack_uint64 ("state",
(uint32_t) new_state), (uint32_t) new_state),
TALER_JSON_pack_amount ("new_threshold", TALER_JSON_pack_amount ("new_threshold",
new_threshold), new_threshold),
GNUNET_JSON_pack_timestamp ("decision_time", GNUNET_JSON_pack_timestamp ("decision_time",

View File

@ -51,7 +51,7 @@ struct CoinData
/** /**
* Age commitment for the coin. * Age commitment for the coin.
*/ */
const struct TALER_AgeCommitmentHash *ach; const struct TALER_AgeCommitmentHashP *ach;
/** /**
* blinding secret * blinding secret

View File

@ -850,7 +850,7 @@ help_deposit (struct CoinHistoryParseContext *pc,
struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_MerchantPublicKeyP merchant_pub;
struct GNUNET_TIME_Timestamp refund_deadline = {0}; struct GNUNET_TIME_Timestamp refund_deadline = {0};
struct TALER_CoinSpendSignatureP sig; struct TALER_CoinSpendSignatureP sig;
struct TALER_AgeCommitmentHash hac; struct TALER_AgeCommitmentHashP hac;
bool no_hac; bool no_hac;
struct TALER_Amount deposit_fee; struct TALER_Amount deposit_fee;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
@ -938,7 +938,7 @@ help_melt (struct CoinHistoryParseContext *pc,
{ {
struct TALER_CoinSpendSignatureP sig; struct TALER_CoinSpendSignatureP sig;
struct TALER_RefreshCommitmentP rc; struct TALER_RefreshCommitmentP rc;
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
bool no_hac; bool no_hac;
struct TALER_Amount melt_fee; struct TALER_Amount melt_fee;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
@ -1292,7 +1292,7 @@ help_purse_deposit (struct CoinHistoryParseContext *pc,
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
const char *exchange_base_url; const char *exchange_base_url;
bool refunded; bool refunded;
struct TALER_AgeCommitmentHash phac = { 0 }; struct TALER_AgeCommitmentHashP phac = { 0 };
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("purse_pub", GNUNET_JSON_spec_fixed_auto ("purse_pub",
&purse_pub), &purse_pub),
@ -1758,7 +1758,7 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
const char *exchange_url, const char *exchange_url,
const json_t *proof, const json_t *proof,
struct TALER_DenominationHashP *h_denom_pub, struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac, struct TALER_AgeCommitmentHashP *phac,
struct TALER_CoinSpendPublicKeyP *coin_pub, struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_CoinSpendSignatureP *coin_sig) struct TALER_CoinSpendSignatureP *coin_sig)
{ {

View File

@ -87,7 +87,7 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
const char *exchange_url, const char *exchange_url,
const json_t *proof, const json_t *proof,
struct TALER_DenominationHashP *h_denom_pub, struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac, struct TALER_AgeCommitmentHashP *phac,
struct TALER_CoinSpendPublicKeyP *coin_pub, struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_CoinSpendSignatureP *coin_sig); struct TALER_CoinSpendSignatureP *coin_sig);

View File

@ -149,7 +149,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
if (NULL != lh->age_commitment_proof) if (NULL != lh->age_commitment_proof)
{ {
lci->age_commitment_proof = GNUNET_new (struct TALER_AgeCommitmentProof); lci->age_commitment_proof = GNUNET_new (struct TALER_AgeCommitmentProof);
lci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash); lci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHashP);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_age_commitment_derive ( TALER_age_commitment_derive (

View File

@ -66,7 +66,7 @@ struct TALER_EXCHANGE_ManagementAddPartner
/** /**
* Function called when we're done processing the * Function called when we're done processing the
* HTTP POST /aml-decision/$OFFICER_PUB request. * HTTP POST /management/partners request.
* *
* @param cls the `struct TALER_EXCHANGE_ManagementAddPartner *` * @param cls the `struct TALER_EXCHANGE_ManagementAddPartner *`
* @param response_code HTTP response code, 0 on error * @param response_code HTTP response code, 0 on error
@ -145,25 +145,9 @@ TALER_EXCHANGE_management_add_partner (
wh->cb = cb; wh->cb = cb;
wh->cb_cls = cb_cls; wh->cb_cls = cb_cls;
wh->ctx = ctx; wh->ctx = ctx;
{ wh->url = TALER_url_join (url,
char *path; "management/partners",
char opus[sizeof (*partner_pub) * 2]; NULL);
char *end;
end = GNUNET_STRINGS_data_to_string (
partner_pub,
sizeof (*partner_pub),
opus,
sizeof (opus));
*end = '\0';
GNUNET_asprintf (&path,
"management/partners/%s",
opus);
wh->url = TALER_url_join (url,
path,
NULL);
GNUNET_free (path);
}
if (NULL == wh->url) if (NULL == wh->url)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@ -180,6 +164,8 @@ TALER_EXCHANGE_management_add_partner (
end_date), end_date),
GNUNET_JSON_pack_time_rel ("wad_frequency", GNUNET_JSON_pack_time_rel ("wad_frequency",
wad_frequency), wad_frequency),
GNUNET_JSON_pack_data_auto ("partner_pub",
&partner_pub),
GNUNET_JSON_pack_data_auto ("master_sig", GNUNET_JSON_pack_data_auto ("master_sig",
&master_sig), &master_sig),
TALER_JSON_pack_amount ("wad_fee", TALER_JSON_pack_amount ("wad_fee",

View File

@ -144,25 +144,9 @@ TALER_EXCHANGE_management_update_aml_officer (
wh->cb = cb; wh->cb = cb;
wh->cb_cls = cb_cls; wh->cb_cls = cb_cls;
wh->ctx = ctx; wh->ctx = ctx;
{ wh->url = TALER_url_join (url,
char *path; "management/aml-officers",
char opus[sizeof (*officer_pub) * 2]; NULL);
char *end;
end = GNUNET_STRINGS_data_to_string (
officer_pub,
sizeof (*officer_pub),
opus,
sizeof (opus));
*end = '\0';
GNUNET_asprintf (&path,
"management/aml-officers/%s",
opus);
wh->url = TALER_url_join (url,
path,
NULL);
GNUNET_free (path);
}
if (NULL == wh->url) if (NULL == wh->url)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@ -173,12 +157,14 @@ TALER_EXCHANGE_management_update_aml_officer (
body = GNUNET_JSON_PACK ( body = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("officer_name", GNUNET_JSON_pack_string ("officer_name",
officer_name), officer_name),
GNUNET_JSON_pack_data_auto ("officer_pub",
officer_pub),
GNUNET_JSON_pack_data_auto ("master_sig", GNUNET_JSON_pack_data_auto ("master_sig",
master_sig), master_sig),
GNUNET_JSON_pack_data_bool ("is_active", GNUNET_JSON_pack_bool ("is_active",
is_active), is_active),
GNUNET_JSON_pack_data_bool ("read_only", GNUNET_JSON_pack_bool ("read_only",
read_only), read_only),
GNUNET_JSON_pack_timestamp ("change_date", GNUNET_JSON_pack_timestamp ("change_date",
change_date)); change_date));
eh = TALER_EXCHANGE_curl_easy_get_ (wh->url); eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);

View File

@ -57,7 +57,7 @@ struct Deposit
/** /**
* Age restriction hash for the coin. * Age restriction hash for the coin.
*/ */
struct TALER_AgeCommitmentHash ahac; struct TALER_AgeCommitmentHashP ahac;
/** /**
* How much did we say the coin contributed. * How much did we say the coin contributed.
@ -381,7 +381,7 @@ handle_purse_create_deposit_finished (void *cls,
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub; struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac; struct TALER_AgeCommitmentHashP phac;
bool found = false; bool found = false;
if (GNUNET_OK != if (GNUNET_OK !=
@ -594,7 +594,7 @@ TALER_EXCHANGE_purse_create_with_deposit (
const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof; const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof;
struct Deposit *d = &pch->deposits[i]; struct Deposit *d = &pch->deposits[i];
json_t *jdeposit; json_t *jdeposit;
struct TALER_AgeCommitmentHash *aghp = NULL; struct TALER_AgeCommitmentHashP *aghp = NULL;
struct TALER_AgeAttestation attest; struct TALER_AgeAttestation attest;
struct TALER_AgeAttestation *attestp = NULL; struct TALER_AgeAttestation *attestp = NULL;

View File

@ -57,7 +57,7 @@ struct Coin
/** /**
* Age restriction hash for the coin. * Age restriction hash for the coin.
*/ */
struct TALER_AgeCommitmentHash ahac; struct TALER_AgeCommitmentHashP ahac;
/** /**
* How much did we say the coin contributed. * How much did we say the coin contributed.
@ -240,7 +240,7 @@ handle_purse_deposit_finished (void *cls,
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub; struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac; struct TALER_AgeCommitmentHashP phac;
bool found = false; bool found = false;
if (GNUNET_OK != if (GNUNET_OK !=
@ -513,7 +513,7 @@ TALER_EXCHANGE_purse_deposit (
const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof; const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof;
struct Coin *coin = &pch->coins[i]; struct Coin *coin = &pch->coins[i];
json_t *jdeposit; json_t *jdeposit;
struct TALER_AgeCommitmentHash *achp = NULL; struct TALER_AgeCommitmentHashP *achp = NULL;
struct TALER_AgeAttestation attest; struct TALER_AgeAttestation attest;
struct TALER_AgeAttestation *attestp = NULL; struct TALER_AgeAttestation *attestp = NULL;

View File

@ -168,7 +168,7 @@ TALER_EXCHANGE_get_melt_data_ (
union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i]; union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
struct TALER_PlanchetDetail pd; struct TALER_PlanchetDetail pd;
struct TALER_CoinPubHashP c_hash; struct TALER_CoinPubHashP c_hash;
struct TALER_AgeCommitmentHash *ach = NULL; struct TALER_AgeCommitmentHashP *ach = NULL;
TALER_transfer_secret_to_planchet_secret (&trans_sec, TALER_transfer_secret_to_planchet_secret (&trans_sec,
j, j,
@ -187,7 +187,7 @@ TALER_EXCHANGE_get_melt_data_ (
{ {
fcd->age_commitment_proof[i] = GNUNET_new (struct fcd->age_commitment_proof[i] = GNUNET_new (struct
TALER_AgeCommitmentProof); TALER_AgeCommitmentProof);
ach = GNUNET_new (struct TALER_AgeCommitmentHash); ach = GNUNET_new (struct TALER_AgeCommitmentHashP);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_age_commitment_derive ( TALER_age_commitment_derive (

View File

@ -57,7 +57,7 @@ struct MeltedCoin
* age commitment was set. * age commitment was set.
*/ */
const struct TALER_AgeCommitmentProof *age_commitment_proof; const struct TALER_AgeCommitmentProof *age_commitment_proof;
const struct TALER_AgeCommitmentHash *h_age_commitment; const struct TALER_AgeCommitmentHashP *h_age_commitment;
/** /**
* Timestamp indicating when coins of this denomination become invalid. * Timestamp indicating when coins of this denomination become invalid.

View File

@ -168,7 +168,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
if (NULL != rci->age_commitment_proof) if (NULL != rci->age_commitment_proof)
{ {
rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash); rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHashP);
TALER_age_commitment_hash ( TALER_age_commitment_hash (
&rci->age_commitment_proof->commitment, &rci->age_commitment_proof->commitment,
rci->h_age_commitment); rci->h_age_commitment);

View File

@ -234,7 +234,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
struct TALER_Amount deposit_fee; struct TALER_Amount deposit_fee;
struct TALER_MerchantWireHashP h_wire; struct TALER_MerchantWireHashP h_wire;
struct TALER_PrivateContractHashP h_contract_terms; struct TALER_PrivateContractHashP h_contract_terms;
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
bool no_hac; bool no_hac;
struct TALER_ExtensionPolicyHashP h_policy; struct TALER_ExtensionPolicyHashP h_policy;
bool no_h_policy; bool no_h_policy;

View File

@ -510,8 +510,8 @@ TALER_EXCHANGE_reserves_open (
{ {
const struct TALER_EXCHANGE_PurseDeposit *pd = &coin_payments[i]; const struct TALER_EXCHANGE_PurseDeposit *pd = &coin_payments[i];
const struct TALER_AgeCommitmentProof *acp = pd->age_commitment_proof; const struct TALER_AgeCommitmentProof *acp = pd->age_commitment_proof;
struct TALER_AgeCommitmentHash ahac; struct TALER_AgeCommitmentHashP ahac;
struct TALER_AgeCommitmentHash *achp = NULL; struct TALER_AgeCommitmentHashP *achp = NULL;
struct CoinData *cd = &roh->coins[i]; struct CoinData *cd = &roh->coins[i];
json_t *cp; json_t *cp;

View File

@ -91,7 +91,7 @@ struct TALER_EXCHANGE_WithdrawHandle
/** /**
* Hash of the age commitment for this coin, if applicable. Maybe NULL * Hash of the age commitment for this coin, if applicable. Maybe NULL
*/ */
const struct TALER_AgeCommitmentHash *ach; const struct TALER_AgeCommitmentHashP *ach;
/** /**
* Denomination key we are withdrawing. * Denomination key we are withdrawing.

View File

@ -82,7 +82,7 @@ struct CoinState
* its hash, respectivelly, NULL otherwise. * its hash, respectivelly, NULL otherwise.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof *age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHashP *h_age_commitment;
/** /**
* Reserve history entry that corresponds to this coin. * Reserve history entry that corresponds to this coin.
@ -484,12 +484,12 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
if (0 < age) if (0 < age)
{ {
struct TALER_AgeCommitmentProof *acp; struct TALER_AgeCommitmentProof *acp;
struct TALER_AgeCommitmentHash *hac; struct TALER_AgeCommitmentHashP *hac;
struct GNUNET_HashCode seed; struct GNUNET_HashCode seed;
struct TALER_AgeMask mask; struct TALER_AgeMask mask;
acp = GNUNET_new (struct TALER_AgeCommitmentProof); acp = GNUNET_new (struct TALER_AgeCommitmentProof);
hac = GNUNET_new (struct TALER_AgeCommitmentHash); hac = GNUNET_new (struct TALER_AgeCommitmentHashP);
mask = TALER_extensions_get_age_restriction_mask (); mask = TALER_extensions_get_age_restriction_mask ();
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&seed, &seed,

View File

@ -289,7 +289,7 @@ deposit_run (void *cls,
const struct TALER_CoinSpendPrivateKeyP *coin_priv; const struct TALER_CoinSpendPrivateKeyP *coin_priv;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL; const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
struct TALER_AgeCommitmentHash h_age_commitment = {0}; struct TALER_AgeCommitmentHashP h_age_commitment = {0};
const struct TALER_EXCHANGE_DenomPublicKey *denom_pub; const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
const struct TALER_DenominationSignature *denom_pub_sig; const struct TALER_DenominationSignature *denom_pub_sig;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;

View File

@ -245,7 +245,7 @@ insert_deposit_run (void *cls,
{ {
uint64_t known_coin_id; uint64_t known_coin_id;
struct TALER_DenominationHashP dph; struct TALER_DenominationHashP dph;
struct TALER_AgeCommitmentHash agh; struct TALER_AgeCommitmentHashP agh;
if ( (GNUNET_OK != if ( (GNUNET_OK !=
ids->dbc->plugin->start (ids->dbc->plugin->cls, ids->dbc->plugin->start (ids->dbc->plugin->cls,

View File

@ -75,7 +75,7 @@ struct TALER_TESTING_FreshCoinData
* applicable. * applicable.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof *age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHashP *h_age_commitment;
/** /**
* The blinding key (needed for recoup operations). * The blinding key (needed for recoup operations).
@ -1027,7 +1027,7 @@ melt_run (void *cls,
struct TALER_Amount melt_amount; struct TALER_Amount melt_amount;
struct TALER_Amount fresh_amount; struct TALER_Amount fresh_amount;
const struct TALER_AgeCommitmentProof *age_commitment_proof; const struct TALER_AgeCommitmentProof *age_commitment_proof;
const struct TALER_AgeCommitmentHash *h_age_commitment; const struct TALER_AgeCommitmentHashP *h_age_commitment;
const struct TALER_DenominationSignature *melt_sig; const struct TALER_DenominationSignature *melt_sig;
const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub; const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
const struct TALER_TESTING_Command *coin_command; const struct TALER_TESTING_Command *coin_command;

View File

@ -142,7 +142,7 @@ struct WithdrawState
* its hash, respectivelly, NULL otherwise. * its hash, respectivelly, NULL otherwise.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof *age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHashP *h_age_commitment;
/** /**
* Reserve history entry that corresponds to this operation. * Reserve history entry that corresponds to this operation.
@ -581,12 +581,12 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
if (0 < age) if (0 < age)
{ {
struct TALER_AgeCommitmentProof *acp; struct TALER_AgeCommitmentProof *acp;
struct TALER_AgeCommitmentHash *hac; struct TALER_AgeCommitmentHashP *hac;
struct GNUNET_HashCode seed; struct GNUNET_HashCode seed;
struct TALER_AgeMask mask; struct TALER_AgeMask mask;
acp = GNUNET_new (struct TALER_AgeCommitmentProof); acp = GNUNET_new (struct TALER_AgeCommitmentProof);
hac = GNUNET_new (struct TALER_AgeCommitmentHash); hac = GNUNET_new (struct TALER_AgeCommitmentHashP);
mask = TALER_extensions_get_age_restriction_mask (); mask = TALER_extensions_get_age_restriction_mask ();
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&seed, &seed,

View File

@ -27,7 +27,7 @@
void void
TALER_age_commitment_hash ( TALER_age_commitment_hash (
const struct TALER_AgeCommitment *commitment, const struct TALER_AgeCommitment *commitment,
struct TALER_AgeCommitmentHash *ahash) struct TALER_AgeCommitmentHashP *ahash)
{ {
struct GNUNET_HashContext *hash_context; struct GNUNET_HashContext *hash_context;
struct GNUNET_HashCode hash; struct GNUNET_HashCode hash;
@ -35,7 +35,7 @@ TALER_age_commitment_hash (
GNUNET_assert (NULL != ahash); GNUNET_assert (NULL != ahash);
if (NULL == commitment) if (NULL == commitment)
{ {
memset (ahash, 0, sizeof(struct TALER_AgeCommitmentHash)); memset (ahash, 0, sizeof(struct TALER_AgeCommitmentHashP));
return; return;
} }

View File

@ -29,7 +29,7 @@
/** /**
* Used in TALER_AgeCommitmentHash_isNullOrZero for comparison * Used in TALER_AgeCommitmentHash_isNullOrZero for comparison
*/ */
const struct TALER_AgeCommitmentHash TALER_ZeroAgeCommitmentHash = {0}; const struct TALER_AgeCommitmentHashP TALER_ZeroAgeCommitmentHash = {0};
/** /**
* Function called by libgcrypt on serious errors. * Function called by libgcrypt on serious errors.
@ -258,7 +258,7 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
const union TALER_DenominationBlindingKeyP *bks, const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
const struct TALER_AgeCommitmentHash *ach, const struct TALER_AgeCommitmentHashP *ach,
struct TALER_CoinPubHashP *c_hash, struct TALER_CoinPubHashP *c_hash,
struct TALER_PlanchetDetail *pd struct TALER_PlanchetDetail *pd
) )
@ -299,7 +299,7 @@ TALER_planchet_to_coin (
const struct TALER_BlindedDenominationSignature *blind_sig, const struct TALER_BlindedDenominationSignature *blind_sig,
const union TALER_DenominationBlindingKeyP *bks, const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
const struct TALER_AgeCommitmentHash *ach, const struct TALER_AgeCommitmentHashP *ach,
const struct TALER_CoinPubHashP *c_hash, const struct TALER_CoinPubHashP *c_hash,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_FreshCoin *coin) struct TALER_FreshCoin *coin)
@ -412,7 +412,7 @@ TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc,
void void
TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub, TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_AgeCommitmentHash *ach, const struct TALER_AgeCommitmentHashP *ach,
struct TALER_CoinPubHashP *coin_h) struct TALER_CoinPubHashP *coin_h)
{ {
if (TALER_AgeCommitmentHash_isNullOrZero (ach)) if (TALER_AgeCommitmentHash_isNullOrZero (ach))
@ -427,7 +427,7 @@ TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
/* Coin comes with age commitment. Take the hash of the age commitment /* Coin comes with age commitment. Take the hash of the age commitment
* into account */ * into account */
const size_t key_s = sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey); const size_t key_s = sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey);
const size_t age_s = sizeof(struct TALER_AgeCommitmentHash); const size_t age_s = sizeof(struct TALER_AgeCommitmentHashP);
char data[key_s + age_s]; char data[key_s + age_s];
GNUNET_memcpy (&data[0], GNUNET_memcpy (&data[0],

View File

@ -299,7 +299,7 @@ enum GNUNET_GenericReturnValue
TALER_denom_blind ( TALER_denom_blind (
const struct TALER_DenominationPublicKey *dk, const struct TALER_DenominationPublicKey *dk,
const union TALER_DenominationBlindingKeyP *coin_bks, const union TALER_DenominationBlindingKeyP *coin_bks,
const struct TALER_AgeCommitmentHash *ach, const struct TALER_AgeCommitmentHashP *ach,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_CoinPubHashP *c_hash, struct TALER_CoinPubHashP *c_hash,

View File

@ -359,7 +359,61 @@ TALER_exchange_online_melt_confirmation_verify (
} }
/* TODO:oec: add signature for age-withdraw and reveal */ GNUNET_NETWORK_STRUCT_BEGIN
/**
* @brief Format of the block signed by the Exchange in response to a
* successful "/reserves/$RESERVE_PUB/age-withdraw" request. Hereby the
* exchange affirms that the commitment along with the maximum age group and
* the amount were accepted. This also commits the exchange to a particular
* index to not be revealed during the reveal.
*/
struct TALER_AgeWithdrawConfirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_AGE_WITHDRAW. Signed by a
* `struct TALER_ExchangePublicKeyP` using EdDSA.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Commitment made in the /reserves/$RESERVE_PUB/age-withdraw.
*/
struct TALER_AgeWithdrawCommitmentHashP h_commitment 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;
};
GNUNET_NETWORK_STRUCT_END
enum TALER_ErrorCode
TALER_exchange_online_age_withdraw_confirmation_sign (
TALER_ExchangeSignCallback scb,
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
uint32_t noreveal_index,
struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig)
{
struct TALER_AgeWithdrawConfirmationPS confirm = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_AGE_WITHDRAW),
.purpose.size = htonl (sizeof (confirm)),
.h_commitment = *h_commitment,
.noreveal_index = htonl (noreveal_index)
};
return scb (&confirm.purpose,
pub,
sig);
}
/* TODO:oec: add signature for age-withdraw, age-reveal */
GNUNET_NETWORK_STRUCT_BEGIN GNUNET_NETWORK_STRUCT_BEGIN

View File

@ -124,12 +124,12 @@ test_planchets_rsa (uint8_t age)
struct TALER_BlindedDenominationSignature blind_sig; struct TALER_BlindedDenominationSignature blind_sig;
struct TALER_FreshCoin coin; struct TALER_FreshCoin coin;
struct TALER_CoinPubHashP c_hash; struct TALER_CoinPubHashP c_hash;
struct TALER_AgeCommitmentHash *ach = NULL; struct TALER_AgeCommitmentHashP *ach = NULL;
if (0 < age) if (0 < age)
{ {
struct TALER_AgeCommitmentProof acp; struct TALER_AgeCommitmentProof acp;
struct TALER_AgeCommitmentHash ah = {0}; struct TALER_AgeCommitmentHashP ah = {0};
struct GNUNET_HashCode seed; struct GNUNET_HashCode seed;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
@ -256,11 +256,11 @@ test_planchets_cs (uint8_t age)
struct TALER_BlindedDenominationSignature blind_sig; struct TALER_BlindedDenominationSignature blind_sig;
struct TALER_FreshCoin coin; struct TALER_FreshCoin coin;
struct TALER_ExchangeWithdrawValues alg_values; struct TALER_ExchangeWithdrawValues alg_values;
struct TALER_AgeCommitmentHash *ach = NULL; struct TALER_AgeCommitmentHashP *ach = NULL;
if (0 < age) if (0 < age)
{ {
struct TALER_AgeCommitmentHash ah = {0}; struct TALER_AgeCommitmentHashP ah = {0};
struct TALER_AgeCommitmentProof acp; struct TALER_AgeCommitmentProof acp;
struct GNUNET_HashCode seed; struct GNUNET_HashCode seed;

View File

@ -269,7 +269,7 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh)
bool success = false; bool success = false;
struct TALER_PlanchetMasterSecretP ps; struct TALER_PlanchetMasterSecretP ps;
struct TALER_ExchangeWithdrawValues alg_values; struct TALER_ExchangeWithdrawValues alg_values;
struct TALER_AgeCommitmentHash ach; struct TALER_AgeCommitmentHashP ach;
struct TALER_CoinPubHashP c_hash; struct TALER_CoinPubHashP c_hash;
struct TALER_CoinSpendPrivateKeyP coin_priv; struct TALER_CoinSpendPrivateKeyP coin_priv;
union TALER_DenominationBlindingKeyP bks; union TALER_DenominationBlindingKeyP bks;
@ -458,7 +458,7 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh,
bool success = false; bool success = false;
struct TALER_PlanchetMasterSecretP ps[batch_size]; struct TALER_PlanchetMasterSecretP ps[batch_size];
struct TALER_ExchangeWithdrawValues alg_values[batch_size]; struct TALER_ExchangeWithdrawValues alg_values[batch_size];
struct TALER_AgeCommitmentHash ach[batch_size]; struct TALER_AgeCommitmentHashP ach[batch_size];
struct TALER_CoinPubHashP c_hash[batch_size]; struct TALER_CoinPubHashP c_hash[batch_size];
struct TALER_CoinSpendPrivateKeyP coin_priv[batch_size]; struct TALER_CoinSpendPrivateKeyP coin_priv[batch_size];
union TALER_DenominationBlindingKeyP bks[batch_size]; union TALER_DenominationBlindingKeyP bks[batch_size];
@ -672,7 +672,7 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh,
struct GNUNET_TIME_Relative duration; struct GNUNET_TIME_Relative duration;
struct TALER_PlanchetMasterSecretP ps; struct TALER_PlanchetMasterSecretP ps;
struct TALER_CoinSpendPrivateKeyP coin_priv; struct TALER_CoinSpendPrivateKeyP coin_priv;
struct TALER_AgeCommitmentHash ach; struct TALER_AgeCommitmentHashP ach;
union TALER_DenominationBlindingKeyP bks; union TALER_DenominationBlindingKeyP bks;
struct TALER_ExchangeWithdrawValues alg_values; struct TALER_ExchangeWithdrawValues alg_values;

View File

@ -83,7 +83,7 @@ cp_to_j (
json_t *j_proof; json_t *j_proof;
json_t *j_pubs; json_t *j_pubs;
json_t *j_privs; json_t *j_privs;
struct TALER_AgeCommitmentHash hac = {0}; struct TALER_AgeCommitmentHashP hac = {0};
char buf[256] = {0}; char buf[256] = {0};
TALER_age_commitment_hash (&acp->commitment, &hac); TALER_age_commitment_hash (&acp->commitment, &hac);

View File

@ -46,7 +46,7 @@ struct TALER_DepositRequestPS
* Hash over the age commitment that went into the coin. Maybe all zero, if * Hash over the age commitment that went into the coin. Maybe all zero, if
* age commitment isn't applicable to the denomination. * age commitment isn't applicable to the denomination.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED; struct TALER_AgeCommitmentHashP h_age_commitment GNUNET_PACKED;
/** /**
* Hash over optional policy extension attributes shared with the exchange. * Hash over optional policy extension attributes shared with the exchange.
@ -119,7 +119,7 @@ TALER_wallet_deposit_sign (
const struct TALER_Amount *deposit_fee, const struct TALER_Amount *deposit_fee,
const struct TALER_MerchantWireHashP *h_wire, const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_ExtensionPolicyHashP *h_policy, const struct TALER_ExtensionPolicyHashP *h_policy,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct GNUNET_TIME_Timestamp wallet_timestamp, const struct GNUNET_TIME_Timestamp wallet_timestamp,
@ -159,7 +159,7 @@ TALER_wallet_deposit_verify (
const struct TALER_Amount *deposit_fee, const struct TALER_Amount *deposit_fee,
const struct TALER_MerchantWireHashP *h_wire, const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_ExtensionPolicyHashP *h_policy, const struct TALER_ExtensionPolicyHashP *h_policy,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
struct GNUNET_TIME_Timestamp wallet_timestamp, struct GNUNET_TIME_Timestamp wallet_timestamp,
@ -230,7 +230,7 @@ struct TALER_LinkDataPS
/** /**
* Hash of the age commitment, if applicable. Can be all zero * Hash of the age commitment, if applicable. Can be all zero
*/ */
struct TALER_AgeCommitmentHash h_age_commitment; struct TALER_AgeCommitmentHashP h_age_commitment;
/** /**
* Hash of the blinded new coin. * Hash of the blinded new coin.
@ -426,7 +426,7 @@ struct TALER_RefreshMeltCoinAffirmationPS
* the hash of the age commitment vector. It must be all zeroes if no age * the hash of the age commitment vector. It must be all zeroes if no age
* commitment was provided. * commitment was provided.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED; struct TALER_AgeCommitmentHashP h_age_commitment GNUNET_PACKED;
/** /**
* How much of the value of the coin should be melted? This amount * How much of the value of the coin should be melted? This amount
@ -458,7 +458,7 @@ TALER_wallet_melt_sign (
const struct TALER_Amount *melt_fee, const struct TALER_Amount *melt_fee,
const struct TALER_RefreshCommitmentP *rc, const struct TALER_RefreshCommitmentP *rc,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig) struct TALER_CoinSpendSignatureP *coin_sig)
{ {
@ -490,7 +490,7 @@ TALER_wallet_melt_verify (
const struct TALER_Amount *melt_fee, const struct TALER_Amount *melt_fee,
const struct TALER_RefreshCommitmentP *rc, const struct TALER_RefreshCommitmentP *rc,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig) const struct TALER_CoinSpendSignatureP *coin_sig)
{ {
@ -604,6 +604,92 @@ TALER_wallet_withdraw_verify (
} }
GNUNET_NETWORK_STRUCT_BEGIN
/**
* @brief Format used for to generate the signature on a request to
* age-withdraw from a reserve.
*/
struct TALER_AgeWithdrawRequestPS
{
/**
* Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW.
* Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash of the commitment of n*kappa coins
*/
struct TALER_AgeWithdrawCommitmentHashP h_commitment GNUNET_PACKED;
/**
* Value of the coin being exchanged (matching the denomination key)
* plus the transaction fee. We include this in what is being
* signed so that we can verify a reserve's remaining total balance
* without needing to access the respective denomination key
* information each time.
*/
struct TALER_AmountNBO amount_with_fee;
/**
* Maximum age group that the coins are going to be restricted to.
*/
uint32_t max_age_group;
};
GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_age_withdraw_sign (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
const struct TALER_Amount *amount_with_fee,
uint32_t max_age_group,
const struct TALER_ReservePrivateKeyP *reserve_priv,
struct TALER_ReserveSignatureP *reserve_sig)
{
struct TALER_AgeWithdrawRequestPS req = {
.purpose.size = htonl (sizeof (req)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
.h_commitment = *h_commitment,
.max_age_group = max_age_group
};
TALER_amount_hton (&req.amount_with_fee,
amount_with_fee);
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
&req,
&reserve_sig->eddsa_signature);
}
enum GNUNET_GenericReturnValue
TALER_wallet_age_withdraw_verify (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
const struct TALER_Amount *amount_with_fee,
uint32_t max_age_group,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig)
{
struct TALER_AgeWithdrawRequestPS awsrd = {
.purpose.size = htonl (sizeof (awsrd)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
.h_commitment = *h_commitment,
.max_age_group = max_age_group
};
TALER_amount_hton (&awsrd.amount_with_fee,
amount_with_fee);
return GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW,
&awsrd,
&reserve_sig->eddsa_signature,
&reserve_pub->eddsa_pub);
}
GNUNET_NETWORK_STRUCT_BEGIN GNUNET_NETWORK_STRUCT_BEGIN
@ -1021,7 +1107,7 @@ struct TALER_PurseDepositPS
* Hash over the age commitment that went into the coin. Maybe all zero, if * Hash over the age commitment that went into the coin. Maybe all zero, if
* age commitment isn't applicable to the denomination. * age commitment isn't applicable to the denomination.
*/ */
struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED; struct TALER_AgeCommitmentHashP h_age_commitment GNUNET_PACKED;
/** /**
* Purse to deposit funds into. * Purse to deposit funds into.
@ -1043,7 +1129,7 @@ TALER_wallet_purse_deposit_sign (
const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig) struct TALER_CoinSpendSignatureP *coin_sig)
{ {
@ -1072,7 +1158,7 @@ TALER_wallet_purse_deposit_verify (
const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_AgeCommitmentHashP *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig) const struct TALER_CoinSpendSignatureP *coin_sig)
{ {