diff options
author | Özgür Kesim <oec-taler@kesim.org> | 2022-06-29 13:36:06 +0200 |
---|---|---|
committer | Özgür Kesim <oec-taler@kesim.org> | 2022-06-29 14:43:16 +0200 |
commit | e3690a9eb44d5feb0a44dc995612a601aa95aacd (patch) | |
tree | 357b01c2a7eaece8ca896a8ee7fb54c2a5b2b501 /src | |
parent | 25abbe8bf6db4c2b2c2656e83b38e55cf2fa76c2 (diff) | |
download | merchant-e3690a9eb44d5feb0a44dc995612a601aa95aacd.tar.gz merchant-e3690a9eb44d5feb0a44dc995612a601aa95aacd.tar.bz2 merchant-e3690a9eb44d5feb0a44dc995612a601aa95aacd.zip |
use age commitment parser from libtalerexchange
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-pay.c | 148 |
1 files changed, 59 insertions, 89 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c index bbd74822..2e78c10d 100644 --- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c +++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -129,6 +129,9 @@ struct DepositConfirmation */ struct TALER_AgeAttestation minimum_age_sig; + /* true, if no field "minimum_age_sig" was found in the JSON blob */ + bool no_minimum_age_sig; + /** * If a minimum age was required (i. e. pc->minimum_age is large enough), * this is the age commitment (i. e. age mask and vector of EdDSA public @@ -136,7 +139,21 @@ struct DepositConfirmation * SHA256 hash of the mask and the vector of public keys was bound to the * key. */ - struct TALER_AgeCommitment *age_commitment; + struct TALER_AgeCommitment age_commitment; + + /* true, if no field "age_commitment" was found in the JSON blob */ + bool no_age_commitment; + + /** + * In the case that somebody pays with a coin that is age restricted, but the + * the contract did not ask for a minimum age, the merchant still needs the + * hash of the age commitment in order to a) verify the coin and b) deposit + * it. + */ + struct TALER_AgeCommitmentHash h_age_commitment; + + /* true, if no field "h_age_commitment" was found in the JSON blob */ + bool no_h_age_commitment; /** * Age mask in the denomination that defines the age groups. Only @@ -1069,7 +1086,6 @@ process_pay_with_exchange ( struct PayContext *pc = cls; struct TMH_HandlerContext *hc = pc->hc; const struct TALER_EXCHANGE_Keys *keys; - struct TALER_AgeCommitmentHash h_age_commitment = {0}; (void) payto_uri; pc->fo = NULL; @@ -1116,6 +1132,8 @@ process_pay_with_exchange ( enum TALER_ErrorCode ec; unsigned int http_status; bool age_verification_required = false; + struct TALER_AgeCommitmentHash ach = {0}; + struct TALER_AgeCommitmentHash *achp = NULL; if (NULL != dc->dh) continue; /* we were here before (can happen due to @@ -1199,15 +1217,15 @@ process_pay_with_exchange ( { unsigned int code = 0; - if (NULL == dc->age_commitment) + if (dc->no_age_commitment) { code = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_MISSING; goto AGE_FAIL; } - dc->age_commitment->mask = denom_details->key.age_mask; - if ((dc->age_commitment->num + 1) != - __builtin_popcount (dc->age_commitment->mask.bits)) + dc->age_commitment.mask = denom_details->key.age_mask; + if ((dc->age_commitment.num + 1) != + __builtin_popcount (dc->age_commitment.mask.bits)) { code = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_SIZE_MISMATCH; @@ -1216,7 +1234,7 @@ process_pay_with_exchange ( if (GNUNET_OK != TALER_age_commitment_verify ( - dc->age_commitment, + &dc->age_commitment, pc->minimum_age, &dc->minimum_age_sig)) code = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_VERIFICATION_FAILED; @@ -1236,8 +1254,10 @@ AGE_FAIL: /* Age restriction successfully verified! * Calculate the hash of the age commitment. */ - TALER_age_commitment_hash (dc->age_commitment, - &h_age_commitment); + TALER_age_commitment_hash (&dc->age_commitment, + &ach); + + achp = &ach; } dc->deposit_fee = denom_details->fees.deposit; @@ -1251,8 +1271,7 @@ AGE_FAIL: pc->wm->payto_uri, &pc->wm->wire_salt, &pc->h_contract_terms, - age_verification_required ? - &h_age_commitment: NULL, + achp, NULL, /* FIXME oec: extension json blob */ &dc->coin_pub, &dc->ub_sig, @@ -2042,11 +2061,12 @@ parse_pay (struct PayContext *pc) { unsigned int coins_index; json_t *coin; + json_array_foreach (coins, coins_index, coin) { struct DepositConfirmation *dc = &pc->dc[coins_index]; const char *exchange_url; - json_t *age_commitment = NULL; + bool no_minimum_age_sig; struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ("coin_sig", &dc->coin_sig), @@ -2061,14 +2081,22 @@ parse_pay (struct PayContext *pc) &dc->amount_with_fee), GNUNET_JSON_spec_string ("exchange_url", &exchange_url), + /* if a minimum age was required, the minimum_age_sig and + * age_commitment must be provided */ GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_fixed_auto ("minimum_age_sig", &dc->minimum_age_sig), - NULL), + &no_minimum_age_sig), + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_age_commitment ("age_commitment", + &dc->age_commitment), + &dc->no_age_commitment), + /* if minimum age was not required, but coin with age restriction set + * was used, h_age_commitment must be provided. */ GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("age_commitment", - &age_commitment), - NULL), + GNUNET_JSON_spec_fixed_auto ("h_age_commitment", + &dc->h_age_commitment), + &dc->no_h_age_commitment), GNUNET_JSON_spec_end () }; enum GNUNET_GenericReturnValue res; @@ -2119,12 +2147,21 @@ parse_pay (struct PayContext *pc) : GNUNET_SYSERR; } + // Check the consistency of the (potential) age restriction + // information. { - bool has_commitment = (NULL != age_commitment) && - json_is_array (age_commitment); - bool has_sig = ! GNUNET_is_zero_ (&dc->minimum_age_sig, - sizeof(dc->minimum_age_sig)); - if (has_sig != has_commitment) + char *error = NULL; + + if (0 < dc->pc->minimum_age && + dc->no_minimum_age_sig && + dc->no_age_commitment) + error = "required: 'mininum_age_sig' and 'age_commitment'"; + + if (! dc->no_age_commitment && + dc->no_h_age_commitment) + error = "only one allowed: 'age_commitment' vs. 'h_age_commitment'"; + + if (NULL != error) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); @@ -2133,69 +2170,11 @@ parse_pay (struct PayContext *pc) pc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, - "inconsistency: 'mininum_age_sig' vs. 'age_commitment'") + error) ) ? GNUNET_NO : GNUNET_SYSERR; } - - /* Parse the AgeCommitment, i. e. the public keys */ - if (has_commitment) - { - json_t *pk; - unsigned int idx; - size_t num = json_array_size (age_commitment); - - /* Sanity check the amount of AgeCommitment's public keys. The - * actual check will be performed once we now the denominations. */ - if (32 <= num) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return (MHD_YES == - TALER_MHD_reply_with_error (pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "'age_commitment' too large" - )) - ? GNUNET_NO - : GNUNET_SYSERR; - } - - dc->age_commitment = GNUNET_new (struct TALER_AgeCommitment); - dc->age_commitment->num = num; - dc->age_commitment->keys = - GNUNET_new_array (num, - struct TALER_AgeCommitmentPublicKeyP); - /* Note that dc->age_commitment.mask will be set later, based on - * the actual denomination. */ - - json_array_foreach (age_commitment, idx, pk) { - struct GNUNET_JSON_Specification pkspec[] = { - GNUNET_JSON_spec_fixed_auto ( - NULL, - &dc->age_commitment->keys[idx].pub), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (pk, - pkspec, - NULL, NULL)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return (MHD_YES == - TALER_MHD_reply_with_error ( - pc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "age_commitment")) - ? GNUNET_NO - : GNUNET_SYSERR; - } - } - } } } } @@ -2538,15 +2517,6 @@ check_contract (struct PayContext *pc) pc->wm = wm; } - if (0 < pc->minimum_age) - { - /* TODO oec: check - * 1. denomination are age restricted - * 2. consume their mask - * 3. valididate minimum age - */ - } - return GNUNET_OK; } |