From 4860164c524deda02ade61c7f7845e46f9f9b143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Sat, 8 Jan 2022 14:23:02 +0100 Subject: [PATCH] add age_restricted_denoms to /keys response --- src/exchange/taler-exchange-httpd.h | 3 + src/exchange/taler-exchange-httpd_keys.c | 97 +++++++++++++++++++++--- 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index dec62c3bb..4f04029e6 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -206,6 +206,9 @@ extern struct GNUNET_CURL_Context *TEH_curl_ctx; */ extern struct TALER_Extension **TEH_extensions; +#define TEH_extension_enabled(ext) (0 <= ext && TALER_Extension_Max > ext && \ + NULL != TEH_extensions[ext]->config) + /** * @brief Struct describing an URL and the handler for it. */ diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 57000e139..30bbe8ebb 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -744,7 +744,7 @@ load_age_mask (const char*section_name) { static const struct TALER_AgeMask null_mask = {0}; struct TALER_AgeMask age_mask = {0}; - struct TALER_Extension *age_ext = + const struct TALER_Extension *age_ext = TEH_extensions[TALER_Extension_AgeRestriction]; // Get the age mask from the extension, if configured @@ -1444,7 +1444,6 @@ struct DenomKeyCtx * valid denomination keys? */ struct GNUNET_TIME_Relative min_dk_frequency; - }; @@ -1607,6 +1606,7 @@ setup_general_response_headers (struct TEH_KeyStateHandle *ksh, * @param signkeys list of sign keys to return * @param recoup list of revoked keys to return * @param denoms list of denominations to return + * @param age_restricted_denoms list of age restricted denominations to return, can be NULL * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue @@ -1615,7 +1615,8 @@ create_krd (struct TEH_KeyStateHandle *ksh, struct GNUNET_TIME_Timestamp last_cpd, json_t *signkeys, json_t *recoup, - json_t *denoms) + json_t *denoms, + json_t *age_restricted_denoms) { struct KeysResponseData krd; struct TALER_ExchangePublicKeyP exchange_pub; @@ -1687,6 +1688,8 @@ create_krd (struct TEH_KeyStateHandle *ksh, GNUNET_JSON_pack_data_auto ("eddsa_sig", &exchange_sig)); GNUNET_assert (NULL != keys); + + // Set wallet limit if KYC is configured if ( (TEH_KYC_NONE != TEH_kyc_config.mode) && (GNUNET_OK == TALER_amount_is_valid (&TEH_kyc_config.wallet_balance_limit)) ) @@ -1700,6 +1703,40 @@ create_krd (struct TEH_KeyStateHandle *ksh, &TEH_kyc_config.wallet_balance_limit))); } + // Signal support for the age-restriction extension, if so configured, and + // add the array of age-restricted denominations. + if (TEH_extension_enabled (TALER_Extension_AgeRestriction) && + NULL != age_restricted_denoms) + { + struct TALER_AgeMask *mask; + json_t *config; + + mask = (struct + TALER_AgeMask *) TEH_extensions[TALER_Extension_AgeRestriction]-> + config; + config = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_bool ("critical", false), + GNUNET_JSON_pack_string ("version", "1"), + GNUNET_JSON_pack_string ("age_groups", TALER_age_mask_to_string (mask))); + GNUNET_assert (NULL != config); + GNUNET_assert ( + 0 == + json_object_set_new ( + keys, + "age_restriction", + config)); + + GNUNET_assert ( + 0 == + json_object_set_new ( + keys, + "age_restricted_denoms", + age_restricted_denoms)); + } + + // TODO: signal support and configuration for the P2P extension, once + // implemented. + { char *keys_json; void *keys_jsonz; @@ -1766,7 +1803,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) { json_t *recoup; struct SignKeyCtx sctx; - json_t *denoms; + json_t *denoms = NULL; + json_t *age_restricted_denoms = NULL; struct GNUNET_TIME_Timestamp last_cpd; struct GNUNET_CONTAINER_Heap *heap; struct GNUNET_HashContext *hash_context; @@ -1796,6 +1834,14 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) } denoms = json_array (); GNUNET_assert (NULL != denoms); + + // If age restriction is enabled, initialize the array of age restricted denoms. + if (TEH_extension_enabled (TALER_Extension_AgeRestriction)) + { + age_restricted_denoms = json_array (); + GNUNET_assert (NULL != age_restricted_denoms); + } + last_cpd = GNUNET_TIME_UNIT_ZERO_TS; hash_context = GNUNET_CRYPTO_hash_context_start (); { @@ -1820,7 +1866,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) last_cpd, sctx.signkeys, recoup, - denoms)) + denoms, + age_restricted_denoms)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to generate key response data for %s\n", @@ -1831,6 +1878,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) /* intentionally empty */; GNUNET_CONTAINER_heap_destroy (heap); json_decref (denoms); + if (NULL != age_restricted_denoms) + json_decref (age_restricted_denoms); json_decref (sctx.signkeys); json_decref (recoup); return GNUNET_SYSERR; @@ -1840,10 +1889,12 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) GNUNET_CRYPTO_hash_context_read (hash_context, &dk->h_denom_pub, sizeof (struct GNUNET_HashCode)); - GNUNET_assert ( - 0 == - json_array_append_new ( - denoms, + + { + json_t *denom; + json_t *array; + + denom = GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("master_sig", &dk->master_sig), @@ -1866,7 +1917,26 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) TALER_JSON_pack_amount ("fee_refresh", &dk->meta.fee_refresh), TALER_JSON_pack_amount ("fee_refund", - &dk->meta.fee_refund)))); + &dk->meta.fee_refund)); + + /* Put the denom into the correct array - denoms or age_restricted_denoms - + * depending on the settings and the properties of the denomination */ + if (NULL != age_restricted_denoms && + 0 != dk->meta.age_restrictions.mask) + { + array = age_restricted_denoms; + } + else + { + array = denoms; + } + + GNUNET_assert ( + 0 == + json_array_append_new ( + array, + denom)); + } } } GNUNET_CONTAINER_heap_destroy (heap); @@ -1882,12 +1952,15 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) last_cpd, sctx.signkeys, recoup, - denoms)) + denoms, + age_restricted_denoms)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to generate key response data for %s\n", GNUNET_TIME_timestamp2s (last_cpd)); json_decref (denoms); + if (NULL != age_restricted_denoms) + json_decref (age_restricted_denoms); json_decref (sctx.signkeys); json_decref (recoup); return GNUNET_SYSERR; @@ -1903,6 +1976,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) json_decref (sctx.signkeys); json_decref (recoup); json_decref (denoms); + if (NULL != age_restricted_denoms) + json_decref (age_restricted_denoms); return GNUNET_OK; }