From 8bdf6ab19df70c16d335ecf82f2c3b2117eeb70e Mon Sep 17 00:00:00 2001 From: Özgür Kesim Date: Wed, 16 Feb 2022 22:01:05 +0100 Subject: [age restriction] progress 14/n - withdraw and deposit Age restriction support for - withdraw is done and tested - deposit is done and tested TODOs: - melt/refresh/reveal - link ------ Added functions - TALER_age_restriction_commit - TALER_age_commitment_derive - TALER_age_commitment_hash - TALER_age_restriction_commitment_free_inside - Hash of age commitment passed around API boundaries Exchangedb adjustments for denominations - all prepared statements re: denominations now handle age_mask - signature parameters adjusted Hash and signature verification of /keys adjusted - Hashes of (normal) denominations and age-restricted denominations are calculated seperately - The hash of the age-restricted ones will then be added to the other hash - The total hash is signed/verified Tests for withdraw with age restriction added - TALER_EXCHANGE_DenomPublickey now carries age_mask - TALER_TESTING_cmd_withdraw_amount* takes age parameter - TALER_TESTING_find_pk takes boolean age_restricted - WithdrawState carries age_commitment and its hash - withdraw_run derives new age commitment, if applicable - Added age parameter to testing (13 as example) Various Fixes and changes - Fixes of post handler for /management/extensions - Fixes for offline tool extensions signing - Slight refactoring of extensions - Age restriction extension simplified - config is now global to extension - added global TEH_age_restriction_enabled and TEH_age_mask in taler-exchange-httpd - helper functions and macros introduced --- .../taler-exchange-httpd_refreshes_reveal.c | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/exchange/taler-exchange-httpd_refreshes_reveal.c') diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 0d8f7bf9..1f0782aa 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -281,6 +281,7 @@ check_commitment (struct RevealContext *rctx, alg_value, &bks, &coin_priv, + NULL, /* FIXME-Oec, struct TALER_AgeCommitmentHash * */ &c_hash, &pd)); if (TALER_DENOMINATION_CS == dk->cipher) @@ -380,6 +381,7 @@ check_commitment (struct RevealContext *rctx, * @param rctx context for the operation, partially built at this time * @param link_sigs_json link signatures in JSON format * @param new_denoms_h_json requests for fresh coins to be created + * @param old_age_commitment_json age commitment that went into the withdrawal, maybe NULL * @param coin_evs envelopes of gamma-selected coins to be signed * @return MHD result code */ @@ -388,6 +390,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, struct RevealContext *rctx, const json_t *link_sigs_json, const json_t *new_denoms_h_json, + const json_t *old_age_commitment_json, const json_t *coin_evs) { unsigned int num_fresh_coins = json_array_size (new_denoms_h_json); @@ -412,6 +415,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, NULL); } + /* Parse denomination key hashes */ for (unsigned int i = 0; igamma_tp, &rrcs[i].coin_envelope_hash, &rctx->melt.session.coin.coin_pub, + NULL, // TODO-oec: calculate the correct h_age_commitment &rrcs[i].orig_coin_link_sig)) { GNUNET_break_op (0); @@ -592,6 +599,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, goto cleanup; } } + rctx->dks = dks; rctx->rcds = rcds; rctx->rrcs = rrcs; @@ -604,6 +612,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating %u signatures\n", (unsigned int) rctx->num_fresh_coins); + /* create fresh coin signatures */ for (unsigned int i = 0; inum_fresh_coins; i++) { @@ -622,8 +631,10 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, goto cleanup; } } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signatures ready, starting DB interaction\n"); + /* Persist operation result in DB */ { enum GNUNET_DB_QueryStatus qs; @@ -678,11 +689,18 @@ cleanup: * revealed information is valid then returns the signed refreshed * coins. * + * If the denomination has age restriction support, the array of EDDSA public + * keys, one for each age group that was activated during the withdrawal + * by the parent/ward, must be provided in old_age_commitment. The hash of + * this array must be the same as the h_age_commitment of the persisted reveal + * request. + * * @param connection the MHD connection to handle * @param rctx context for the operation, partially built at this time * @param tp_json private transfer keys in JSON format * @param link_sigs_json link signatures in JSON format * @param new_denoms_h_json requests for fresh coins to be created + * @param old_age_commitment_json array of EDDSA public keys in JSON, used for age restriction, maybe NULL * @param coin_evs envelopes of gamma-selected coins to be signed * @return MHD result code */ @@ -692,6 +710,7 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection, const json_t *tp_json, const json_t *link_sigs_json, const json_t *new_denoms_h_json, + const json_t *old_age_commitment_json, const json_t *coin_evs) { unsigned int num_fresh_coins = json_array_size (new_denoms_h_json); @@ -727,6 +746,19 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection, "new_denoms/link_sigs"); } + /* Sanity check of age commitment: If it was provided, it _must_ be an array + * of the size the # of age groups */ + if (NULL != old_age_commitment_json + && TALER_extensions_age_restriction_num_groups () != + json_array_size (old_age_commitment_json)) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_COMMITMENT_INVALID, + "old_age_commitment"); + } + /* Parse transfer private keys array */ for (unsigned int i = 0; i