first steps towards age restriction support for coin refresh
This commit is contained in:
parent
8684a9bfea
commit
2b85559c06
@ -1227,6 +1227,7 @@ static int
|
||||
refresh_session_cb (void *cls,
|
||||
uint64_t rowid,
|
||||
const struct TALER_DenominationPublicKey *denom_pub,
|
||||
const struct TALER_AgeHash *h_age_commitment,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||
const struct TALER_Amount *amount_with_fee,
|
||||
@ -1289,6 +1290,7 @@ refresh_session_cb (void *cls,
|
||||
&fee_refresh,
|
||||
rc,
|
||||
&h_denom_pub,
|
||||
h_age_commitment,
|
||||
coin_pub,
|
||||
coin_sig))
|
||||
{
|
||||
|
@ -278,6 +278,7 @@ check_melt_valid (struct MHD_Connection *connection,
|
||||
&mret);
|
||||
if (NULL == dk)
|
||||
return mret;
|
||||
|
||||
if (GNUNET_TIME_absolute_is_past (dk->meta.expire_legal.abs_time))
|
||||
{
|
||||
/* Way too late now, even zombies have expired */
|
||||
@ -287,6 +288,7 @@ check_melt_valid (struct MHD_Connection *connection,
|
||||
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
|
||||
"MELT");
|
||||
}
|
||||
|
||||
if (GNUNET_TIME_absolute_is_future (dk->meta.start.abs_time))
|
||||
{
|
||||
/* This denomination is not yet valid */
|
||||
@ -299,6 +301,7 @@ check_melt_valid (struct MHD_Connection *connection,
|
||||
|
||||
rmc->coin_refresh_fee = dk->meta.fee_refresh;
|
||||
rmc->coin_value = dk->meta.value;
|
||||
|
||||
/* sanity-check that "total melt amount > melt fee" */
|
||||
if (0 <
|
||||
TALER_amount_cmp (&rmc->coin_refresh_fee,
|
||||
@ -328,6 +331,7 @@ check_melt_valid (struct MHD_Connection *connection,
|
||||
&rmc->coin_refresh_fee,
|
||||
&rmc->refresh_session.rc,
|
||||
&rmc->refresh_session.coin.denom_pub_hash,
|
||||
&rmc->refresh_session.coin.age_commitment_hash,
|
||||
&rmc->refresh_session.coin.coin_pub,
|
||||
&rmc->refresh_session.coin_sig))
|
||||
{
|
||||
@ -403,6 +407,9 @@ TEH_handler_melt (struct MHD_Connection *connection,
|
||||
&rmc.refresh_session.coin.denom_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
|
||||
&rmc.refresh_session.coin.denom_pub_hash),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_fixed_auto ("age_commitment_hash",
|
||||
&rmc.refresh_session.coin.age_commitment_hash)),
|
||||
GNUNET_JSON_spec_fixed_auto ("confirm_sig",
|
||||
&rmc.refresh_session.coin_sig),
|
||||
TALER_JSON_spec_amount ("value_with_fee",
|
||||
|
@ -122,6 +122,7 @@ TEH_RESPONSE_compile_transaction_history (
|
||||
{
|
||||
const struct TALER_EXCHANGEDB_MeltListEntry *melt =
|
||||
pos->details.melt;
|
||||
const struct TALER_AgeHash *phac = NULL;
|
||||
|
||||
#if ENABLE_SANITY_CHECKS
|
||||
if (GNUNET_OK !=
|
||||
@ -129,6 +130,7 @@ TEH_RESPONSE_compile_transaction_history (
|
||||
&melt->melt_fee,
|
||||
&melt->rc,
|
||||
&melt->h_denom_pub,
|
||||
&melt->h_age_commitment,
|
||||
coin_pub,
|
||||
&melt->coin_sig))
|
||||
{
|
||||
@ -137,6 +139,12 @@ TEH_RESPONSE_compile_transaction_history (
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Age restriction is optional. We communicate a NULL value to
|
||||
* JSON_PACK below */
|
||||
if (! TALER_AgeHash_isZero (&melt->h_age_commitment))
|
||||
phac = &melt->h_age_commitment;
|
||||
|
||||
if (0 !=
|
||||
json_array_append_new (
|
||||
history,
|
||||
@ -151,6 +159,9 @@ TEH_RESPONSE_compile_transaction_history (
|
||||
&melt->rc),
|
||||
GNUNET_JSON_pack_data_auto ("h_denom_pub",
|
||||
&melt->h_denom_pub),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
GNUNET_JSON_pack_data_auto ("h_age_commitment",
|
||||
phac)),
|
||||
GNUNET_JSON_pack_data_auto ("coin_sig",
|
||||
&melt->coin_sig))))
|
||||
{
|
||||
|
@ -342,6 +342,7 @@ CREATE TABLE IF NOT EXISTS refresh_commitments
|
||||
(melt_serial_id BIGSERIAL -- UNIQUE
|
||||
,rc BYTEA PRIMARY KEY CHECK (LENGTH(rc)=64)
|
||||
,old_coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
|
||||
,h_age_commitment BYTEA CHECK(LENGTH(h_age_commitment)=32)
|
||||
,old_coin_sig BYTEA NOT NULL CHECK(LENGTH(old_coin_sig)=64)
|
||||
,amount_with_fee_val INT8 NOT NULL
|
||||
,amount_with_fee_frac INT4 NOT NULL
|
||||
@ -356,6 +357,8 @@ COMMENT ON COLUMN refresh_commitments.rc
|
||||
IS 'Commitment made by the client, hash over the various client inputs in the cut-and-choose protocol';
|
||||
COMMENT ON COLUMN refresh_commitments.old_coin_pub
|
||||
IS 'Coin being melted in the refresh process.';
|
||||
COMMENT ON COLUMN refresh_commitments.h_age_commitment
|
||||
IS '(optional) age commitment that was involved in the minting process of the coin, may be NULL.';
|
||||
CREATE TABLE IF NOT EXISTS refresh_commitments_default
|
||||
PARTITION OF refresh_commitments
|
||||
FOR VALUES WITH (MODULUS 1, REMAINDER 0);
|
||||
|
@ -848,6 +848,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
"SELECT"
|
||||
" denom.denom_pub"
|
||||
",kc.coin_pub AS old_coin_pub"
|
||||
",h_age_commitment"
|
||||
",old_coin_sig"
|
||||
",amount_with_fee_val"
|
||||
",amount_with_fee_frac"
|
||||
@ -8202,6 +8203,8 @@ refreshs_serial_helper_cb (void *cls,
|
||||
struct TALER_DenominationPublicKey denom_pub;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
struct TALER_AgeHash h_age_commitment;
|
||||
bool ac_isnull;
|
||||
struct TALER_Amount amount_with_fee;
|
||||
uint32_t noreveal_index;
|
||||
uint64_t rowid;
|
||||
@ -8209,6 +8212,10 @@ refreshs_serial_helper_cb (void *cls,
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
||||
&denom_pub),
|
||||
GNUNET_PQ_result_spec_allow_null (
|
||||
GNUNET_PQ_result_spec_auto_from_type ("h_age_commitment",
|
||||
&h_age_commitment),
|
||||
&ac_isnull),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
|
||||
&coin_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
|
||||
@ -8234,9 +8241,11 @@ refreshs_serial_helper_cb (void *cls,
|
||||
rsc->status = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = rsc->cb (rsc->cb_cls,
|
||||
rowid,
|
||||
&denom_pub,
|
||||
ac_isnull ? NULL : &h_age_commitment,
|
||||
&coin_pub,
|
||||
&coin_sig,
|
||||
&amount_with_fee,
|
||||
|
@ -459,6 +459,7 @@ static unsigned int auditor_row_cnt;
|
||||
* @param cls closure
|
||||
* @param rowid unique serial ID for the refresh session in our DB
|
||||
* @param denom_pub denomination of the @a coin_pub
|
||||
* @param h_age_commitment hash of age commitment that went into the minting, may be NULL
|
||||
* @param coin_pub public key of the coin
|
||||
* @param coin_sig signature from the coin
|
||||
* @param amount_with_fee amount that was deposited including fee
|
||||
@ -471,6 +472,7 @@ static enum GNUNET_GenericReturnValue
|
||||
audit_refresh_session_cb (void *cls,
|
||||
uint64_t rowid,
|
||||
const struct TALER_DenominationPublicKey *denom_pub,
|
||||
const struct TALER_AgeHash *h_age_commitment,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||
const struct TALER_Amount *amount_with_fee,
|
||||
|
@ -311,6 +311,9 @@ struct TALER_AgeHash
|
||||
struct GNUNET_ShortHashCode shash;
|
||||
};
|
||||
|
||||
bool
|
||||
TALER_AgeHash_isZero (
|
||||
const struct TALER_AgeHash *hash);
|
||||
|
||||
/**
|
||||
* @brief Type of public keys for Taler coins. The same key material is used
|
||||
@ -712,7 +715,8 @@ struct TALER_CoinPublicInfo
|
||||
struct TALER_DenominationHash denom_pub_hash;
|
||||
|
||||
/**
|
||||
* Hash of the age commitment.
|
||||
* Hash of the age commitment. If no age commitment was provided, it must be
|
||||
* set to all zeroes.
|
||||
*/
|
||||
struct TALER_AgeHash age_commitment_hash;
|
||||
|
||||
@ -1763,6 +1767,7 @@ TALER_wallet_melt_sign (
|
||||
* @param melt_fee the melt fee we expect to pay
|
||||
* @param rc refresh session we are committed to
|
||||
* @param h_denom_pub hash of the coin denomination's public key
|
||||
* @param h_age_commitment hash of the age commitment (may be NULL)
|
||||
* @param coin_pub coin’s public key
|
||||
* @param coin_sig the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_MELT
|
||||
* @return #GNUNET_OK if the signature is valid
|
||||
@ -1773,6 +1778,7 @@ TALER_wallet_melt_verify (
|
||||
const struct TALER_Amount *melt_fee,
|
||||
const struct TALER_RefreshCommitmentP *rc,
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const struct TALER_AgeHash *h_age_commitment,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
@ -1305,6 +1305,12 @@ struct TALER_EXCHANGEDB_MeltListEntry
|
||||
*/
|
||||
struct TALER_DenominationHash h_denom_pub;
|
||||
|
||||
/**
|
||||
* Hash of the age commitment used to sign the coin. May be all zeroes if no
|
||||
* age restriction applies.
|
||||
*/
|
||||
struct TALER_AgeHash h_age_commitment;
|
||||
|
||||
/**
|
||||
* How much value is being melted? This amount includes the fees,
|
||||
* so the final amount contributed to the melt is this value minus
|
||||
@ -1585,6 +1591,7 @@ typedef enum GNUNET_GenericReturnValue
|
||||
* @param cls closure
|
||||
* @param rowid unique serial ID for the refresh session in our DB
|
||||
* @param denom_pub denomination public key of @a coin_pub
|
||||
* @param h_age_commitment age commitment that went into the signing of the coin, may be NULL
|
||||
* @param coin_pub public key of the coin
|
||||
* @param coin_sig signature from the coin
|
||||
* @param amount_with_fee amount that was deposited including fee
|
||||
@ -1597,6 +1604,7 @@ typedef enum GNUNET_GenericReturnValue
|
||||
void *cls,
|
||||
uint64_t rowid,
|
||||
const struct TALER_DenominationPublicKey *denom_pub,
|
||||
const struct TALER_AgeHash *h_age_commitment,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||
const struct TALER_Amount *amount_with_fee,
|
||||
|
@ -711,6 +711,13 @@ struct TALER_RefreshMeltCoinAffirmationPS
|
||||
*/
|
||||
struct TALER_DenominationHash h_denom_pub GNUNET_PACKED;
|
||||
|
||||
/**
|
||||
* If age commitment was provided during the withdrawal of the coin, this is
|
||||
* the hash of the age commitment vector. It must be all zeroes if no age
|
||||
* commitment was provided.
|
||||
*/
|
||||
struct TALER_AgeHash h_age_commitment GNUNET_PACKED;
|
||||
|
||||
/**
|
||||
* How much of the value of the coin should be melted? This amount
|
||||
* includes the fees, so the final amount contributed to the melt is
|
||||
|
@ -548,6 +548,7 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
{
|
||||
struct TALER_CoinSpendSignatureP sig;
|
||||
struct TALER_RefreshCommitmentP rc;
|
||||
struct TALER_AgeHash h_age_commitment = {0};
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_sig",
|
||||
&sig),
|
||||
@ -555,6 +556,9 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
&rc),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
|
||||
h_denom_pub),
|
||||
GNUNET_JSON_spec_mark_optional (
|
||||
GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
|
||||
&h_age_commitment)),
|
||||
TALER_JSON_spec_amount_any ("melt_fee",
|
||||
&fee),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -568,6 +572,7 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
if (NULL != dk)
|
||||
{
|
||||
/* check that melt fee matches our expectations from /keys! */
|
||||
@ -582,11 +587,14 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_melt_verify (&amount,
|
||||
&fee,
|
||||
&rc,
|
||||
h_denom_pub,
|
||||
TALER_AgeHash_isZero (&h_age_commitment) ?
|
||||
NULL : &h_age_commitment,
|
||||
coin_pub,
|
||||
&sig))
|
||||
{
|
||||
|
@ -352,4 +352,13 @@ TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TALER_AgeHash_isZero (
|
||||
const struct TALER_AgeHash *hash)
|
||||
{
|
||||
static struct TALER_AgeHash zeroAgeHash = {0};
|
||||
return (0 == memcmp (hash, &zeroAgeHash, sizeof(struct TALER_AgeHash)));
|
||||
}
|
||||
|
||||
|
||||
/* end of crypto.c */
|
||||
|
@ -267,6 +267,7 @@ TALER_wallet_melt_verify (
|
||||
const struct TALER_Amount *melt_fee,
|
||||
const struct TALER_RefreshCommitmentP *rc,
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const struct TALER_AgeHash *h_age_commitment,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
{
|
||||
@ -274,9 +275,13 @@ TALER_wallet_melt_verify (
|
||||
.purpose.size = htonl (sizeof (melt)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
|
||||
.rc = *rc,
|
||||
.h_denom_pub = *h_denom_pub
|
||||
.h_denom_pub = *h_denom_pub,
|
||||
};
|
||||
|
||||
memset (&melt.h_age_commitment, 0, sizeof(struct TALER_AgeHash));
|
||||
if (NULL != h_age_commitment)
|
||||
melt.h_age_commitment = *h_age_commitment;
|
||||
|
||||
TALER_amount_hton (&melt.amount_with_fee,
|
||||
amount_with_fee);
|
||||
TALER_amount_hton (&melt.melt_fee,
|
||||
|
Loading…
Reference in New Issue
Block a user