summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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
commite3690a9eb44d5feb0a44dc995612a601aa95aacd (patch)
tree357b01c2a7eaece8ca896a8ee7fb54c2a5b2b501 /src
parent25abbe8bf6db4c2b2c2656e83b38e55cf2fa76c2 (diff)
downloadmerchant-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.c148
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;
}