donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit 391bf7472f8cd7e1a15e1b11c3c401f98fa80fe7
parent df2f3bc86ae466bb9a424c1b5478f46b663a3b20
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Tue,  5 Mar 2024 17:08:33 +0100

removed age restricted coins, work on /keys

Diffstat:
Msrc/donau/donau-httpd_keys.c | 300+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/json/json_helper.c | 20++------------------
Msrc/testing/coins-cs.conf | 61-------------------------------------------------------------
Msrc/testing/coins-rsa.conf | 66------------------------------------------------------------------
4 files changed, 235 insertions(+), 212 deletions(-)

diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -496,7 +496,7 @@ struct SignKeyCtx * respective JSON response. * * @param cls a `struct SignKeyCtx *` with the array to append keys to - * @param pid the exchange public key (in type disguise) + * @param pid the donau public key (in type disguise) * @param value a `struct SigningKey` * @return #GNUNET_OK (continue to iterate) */ @@ -604,10 +604,9 @@ insert_donation_unit_cb (void *cls, void *value) { struct KeysBuilderContext *kbc = cls; - struct HelperDonationUnit *helper_donation_unit = value; + struct HelperDonationUnit *hd = value; struct DH_DonationUnitKey *donation_unit; - // struct TALER_Amount *value; - // uint64_t validity_year; + uint64_t validity_year; donation_unit = GNUNET_CONTAINER_multihashmap_get ( kbc->ksh->donation_unit_map, @@ -618,18 +617,186 @@ insert_donation_unit_cb (void *cls, // return GNUNET_OK; /* this key already expired! */ GNUNET_assert ( - 0 == json_array_append_new (kbc->donation_units, GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("value", &value), - // GNUNET_JSON_pack_uint64 ( - // "year", validity_year), - GNUNET_JSON_pack_data_auto ( - "donation_unit_pub", - & - helper_donation_unit - ->donation_unit_pub) - // GNUNET_JSON_pack_string ("section_name", - // helper_donation_unit->section_name) - ))); + 0 == json_array_append_new ( + kbc->donation_units, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("donation_unit_pub", + &hd->donation_unit_pub), + GNUNET_JSON_pack_uint64 ("validity_year", + validity_year), + TALER_JSON_pack_amount ("value", + &value) + // GNUNET_JSON_pack_string ("section_name", + // hd->section_name) + ))); + return GNUNET_OK; +} + + +/** + * Initialize @a krd using the given values for @a signkeys, + * and @a denoms. + * + * @param[in,out] ksh key state handle we build @a krd for + * @param[in] denom_keys_hash hash over all the denomination keys in @a denoms + * @param last_cherry_pick_date timestamp to use + * @param[in,out] signkeys list of sign keys to return + * @param[in,out] grouped_donation_units list of grouped denominations to return + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +create_krd (struct DH_KeyStateHandle *ksh, + const struct GNUNET_HashCode *denom_keys_hash, + struct GNUNET_TIME_Timestamp last_cherry_pick_date, + // json_t *signkeys, + json_t *grouped_donation_units) +{ + struct KeysResponseData krd; + struct DONAU_DonauPublicKeyP donau_pub; + struct DONAU_DonauSignatureP donau_sig; + json_t *keys; + + + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + last_cherry_pick_date.abs_time)); + // GNUNET_assert (NULL != signkeys); + GNUNET_assert (NULL != grouped_donation_units); + GNUNET_assert (NULL != DH_currency); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Creating /keys at cherry pick date %s\n", + GNUNET_TIME_timestamp2s (last_cherry_pick_date)); + + // /* Sign hash over master signatures of all denomination keys until this time + // (in reverse order). */ + // { + // enum TALER_ErrorCode ec; +// +// if (TALER_EC_NONE != +// (ec = +// TALER_donau_online_key_set_sign ( +// &TEH_keys_donau_sign2_, +// ksh, +// last_cherry_pick_date, +// denom_keys_hash, +// &donau_pub, +// &donau_sig))) +// { +// GNUNET_log (GNUNET_ERROR_TYPE_WARNING, +// "Could not create key response data: cannot sign (%s)\n", +// TALER_ErrorCode_get_hint (ec)); +// return GNUNET_SYSERR; +// } +// } + + // { + // const struct SigningKey *sk; +// +// sk = GNUNET_CONTAINER_multipeermap_get ( +// ksh->signkey_map, +// (const struct GNUNET_PeerIdentity *) &donau_pub); +// ksh->signature_expires = GNUNET_TIME_timestamp_min (sk->meta.expire_sign, +// ksh->signature_expires); +// } + + keys = GNUNET_JSON_PACK ( + // GNUNET_JSON_pack_string ("version", + // DONAU_PROTOCOL_VERSION), + GNUNET_JSON_pack_string ("base_url", + DH_base_url), + GNUNET_JSON_pack_string ("currency", + DH_currency), + // GNUNET_JSON_pack_array_incref ("signkeys", + // signkeys), + GNUNET_JSON_pack_array_incref ("donation_units", + grouped_donation_units), + GNUNET_JSON_pack_data_auto ("donau_pub", + &donau_pub)); // , + // GNUNET_JSON_pack_data_auto ("donau_sig", + // &donau_sig)); + GNUNET_assert (NULL != keys); + + + { + char *keys_json; + void *keys_jsonz; + size_t keys_jsonz_size; + int comp; + char etag[sizeof (struct GNUNET_HashCode) * 2]; + + /* Convert /keys response to UTF8-String */ + keys_json = json_dumps (keys, + JSON_INDENT (2)); + json_decref (keys); + GNUNET_assert (NULL != keys_json); + + /* Keep copy for later compression... */ + keys_jsonz = GNUNET_strdup (keys_json); + keys_jsonz_size = strlen (keys_json); + + /* hash to compute etag */ + { + struct GNUNET_HashCode ehash; + char *end; + + GNUNET_CRYPTO_hash (keys_jsonz, + keys_jsonz_size, + &ehash); + end = GNUNET_STRINGS_data_to_string (&ehash, + sizeof (ehash), + etag, + sizeof (etag)); + *end = '\0'; + } + + /* Create uncompressed response */ + krd.response_uncompressed + = MHD_create_response_from_buffer (keys_jsonz_size, + keys_json, + MHD_RESPMEM_MUST_FREE); + GNUNET_assert (NULL != krd.response_uncompressed); + setup_general_response_headers (ksh, + krd.response_uncompressed); + GNUNET_break (MHD_YES == + MHD_add_response_header (krd.response_uncompressed, + MHD_HTTP_HEADER_ETAG, + etag)); + /* Also compute compressed version of /keys response */ + comp = TALER_MHD_body_compress (&keys_jsonz, + &keys_jsonz_size); + krd.response_compressed + = MHD_create_response_from_buffer (keys_jsonz_size, + keys_jsonz, + MHD_RESPMEM_MUST_FREE); + GNUNET_assert (NULL != krd.response_compressed); + /* If the response is actually compressed, set the + respective header. */ + GNUNET_assert ( (MHD_YES != comp) || + (MHD_YES == + MHD_add_response_header (krd.response_compressed, + MHD_HTTP_HEADER_CONTENT_ENCODING, + "deflate")) ); + setup_general_response_headers (ksh, + krd.response_compressed); + /* Set cache control headers: our response varies depending on these headers */ + GNUNET_break (MHD_YES == + MHD_add_response_header (krd.response_compressed, + MHD_HTTP_HEADER_VARY, + MHD_HTTP_HEADER_ACCEPT_ENCODING)); + /* Information is always public, revalidate after 1 day */ + GNUNET_break (MHD_YES == + MHD_add_response_header (krd.response_compressed, + MHD_HTTP_HEADER_CACHE_CONTROL, + "public,max-age=86400")); + GNUNET_break (MHD_YES == + MHD_add_response_header (krd.response_compressed, + MHD_HTTP_HEADER_ETAG, + etag)); + krd.etag = GNUNET_strdup (etag); + } + krd.cherry_pick_date = last_cherry_pick_date; + GNUNET_array_append (ksh->krd_array, + ksh->krd_array_length, + krd); return GNUNET_OK; } @@ -707,14 +874,14 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) &sctx); heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); { - // struct DonationUnitKeyCtx dkc = { - // .heap = heap, - // .min_dk_frequency = GNUNET_TIME_UNIT_FOREVER_REL, - // }; - // - // GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, - // &insert_donation_unit_cb, - // &dkc); + struct DonationUnitKeyCtx dkc = { + .heap = heap, + .min_dk_frequency = GNUNET_TIME_UNIT_FOREVER_REL, + }; + + GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, + &insert_donation_unit_cb, + &dkc); // ksh->rekey_frequency // = GNUNET_TIME_relative_min (dkc.min_dk_frequency, // sctx.min_sk_frequency); @@ -737,38 +904,34 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) /* heap = max heap, sorted by start time */ while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap))) { - // if (GNUNET_TIME_timestamp_cmp (last_cherry_pick_date, - // !=, - // dk->meta.start) && - // (! GNUNET_TIME_absolute_is_zero (last_cherry_pick_date.abs_time)) ) - // { - // /* - // * This is not the first entry in the heap (because last_cherry_pick_date != - // * GNUNET_TIME_UNIT_ZERO_TS) and the previous entry had a different - // * start time. Therefore, we create a new entry in ksh. - // */ - // struct GNUNET_HashCode hc; -// - // compute_msig_hash (&sig_ctx, - // &hc); - // if (GNUNET_OK != - // create_krd (ksh, - // &hc, - // last_cherry_pick_date, - // sctx.signkeys, - // recoup, - // grouped_donation_units)) - // { - // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - // "Failed to generate key response data for %s\n", - // GNUNET_TIME_timestamp2s (last_cherry_pick_date)); - // /* drain heap before destroying it */ - // while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap))) - // /* intentionally empty */; - // GNUNET_CONTAINER_heap_destroy (heap); - // goto CLEANUP; - // } - // } + if (! GNUNET_TIME_absolute_is_zero (last_cherry_pick_date.abs_time)) + { + /* + * This is not the first entry in the heap (because last_cherry_pick_date != + * GNUNET_TIME_UNIT_ZERO_TS) and the previous entry had a different + * start time. Therefore, we create a new entry in ksh. + */ + struct GNUNET_HashCode hc; + + // compute_msig_hash (&sig_ctx, + // &hc); + if (GNUNET_OK != + create_krd (ksh, + &hc, + last_cherry_pick_date, + // sctx.signkeys, + grouped_donation_units)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to generate key response data for %s\n", + GNUNET_TIME_timestamp2s (last_cherry_pick_date)); + /* drain heap before destroying it */ + while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap))) + /* intentionally empty */; + GNUNET_CONTAINER_heap_destroy (heap); + goto CLEANUP; + } + } // last_cherry_pick_date = dk->meta.start; @@ -926,7 +1089,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) ret = GNUNET_OK; -// CLEANUP: +CLEANUP: json_decref (grouped_donation_units); // json_decref (sctx.signkeys); return ret; @@ -1136,7 +1299,7 @@ free_donation_unit_cb (void *cls, * in the `esign_keys` map. * * @param cls the `struct HelperSignkey` - * @param pid unused, matches the exchange public key + * @param pid unused, matches the donau public key * @param value the `struct HelperSignkey` to release * @return #GNUNET_OK (continue to iterate) */ @@ -1402,7 +1565,7 @@ helper_cs_cb ( * zero if the key has been revoked or purged * @param validity_duration how long does the key remain available for signing; * zero if the key has been revoked or purged - * @param exchange_pub the public key itself, NULL if the key was revoked or purged + * @param donau_pub the public key itself, NULL if the key was revoked or purged * @param sm_pub public key of the security module, NULL if the key was revoked or purged * @param sm_sig signature from the security module, NULL if the key was revoked or purged * The signature was already verified against @a sm_pub. @@ -1509,7 +1672,7 @@ setup_key_helpers (struct HelperState *hs) /** - * Function called with information about the exchange's donation_unit keys. + * Function called with information about the donau's donation_unit keys. * * @param cls closure with a `struct TEH_KeyStateHandle *` * @param donation_unit_pub public key of the donation_unit @@ -1527,7 +1690,7 @@ donation_unit_info_cb ( struct DH_DonationUnitKey *dk; // // if (GNUNET_OK != -// TALER_exchange_offline_donation_unit_validity_verify ( +// TALER_donau_offline_donation_unit_validity_verify ( // h_donation_unit_pub, // meta->start, // meta->expire_withdraw, @@ -1539,7 +1702,7 @@ donation_unit_info_cb ( // master_sig)) // { // GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -// "Database has donation_unit with invalid signature. Skipping entry. Did the exchange offline public key change?\n"); +// "Database has donation_unit with invalid signature. Skipping entry. Did the donau offline public key change?\n"); // return; // } @@ -1700,13 +1863,13 @@ DH_keys_get_state () /** - * Function called on all of our current and future exchange signing keys + * Function called on all of our current and future donau signing keys * known to the helper process. Filters out those that are current * and adds the remaining signing keys (with their configuration * data) to the JSON array. * * @param cls the `struct FutureBuilderContext *` - * @param pid actually the exchange public key (type disguised) + * @param pid actually the donau public key (type disguised) * @param value a `struct HelperDonationUnit` * @return #GNUNET_OK (continue to iterate) */ @@ -1768,9 +1931,12 @@ DH_handler_keys (struct DH_RequestContext *rc, sync_key_helpers (ksh->helpers); if (NULL == ksh->keys_reply) { - struct KeysBuilderContext kbc = - { .ksh = ksh, .donation_units = json_array (), .signkeys = - json_array () }; + struct KeysBuilderContext kbc = { + .ksh = ksh, + .donation_units = json_array (), + .signkeys = json_array () + }; + if ( (GNUNET_is_zero (&donation_unit_rsa_sm_pub)) && (GNUNET_is_zero (&donation_unit_cs_sm_pub)) ) { diff --git a/src/json/json_helper.c b/src/json/json_helper.c @@ -36,14 +36,10 @@ static enum GNUNET_CRYPTO_BlindSignatureAlgorithm string_to_cipher (const char *cipher_s) { if ((0 == strcasecmp (cipher_s, - "RSA")) || - (0 == strcasecmp (cipher_s, - "RSA+age_restricted"))) + "RSA"))) return GNUNET_CRYPTO_BSA_RSA; if ((0 == strcasecmp (cipher_s, - "CS")) || - (0 == strcasecmp (cipher_s, - "CS+age_restricted"))) + "CS"))) return GNUNET_CRYPTO_BSA_CS; return GNUNET_CRYPTO_BSA_INVALID; } @@ -324,18 +320,6 @@ parse_denomination_group (void *cls, return GNUNET_SYSERR; } - /* age_mask and suffix must be consistent */ - has_age_restricted_suffix = - (NULL != strstr (cipher, "+age_restricted")); - if (has_age_restricted_suffix && age_mask_missing) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - if (age_mask_missing) - group->age_mask.bits = 0; - return GNUNET_OK; } diff --git a/src/testing/coins-cs.conf b/src/testing/coins-cs.conf @@ -55,64 +55,3 @@ fee_deposit = EUR:0.01 fee_refresh = EUR:0.03 fee_refund = EUR:0.01 CIPHER = CS - - -[coin_eur_ct_1_age_restricted] -value = EUR:0.01 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.00 -fee_deposit = EUR:0.00 -fee_refresh = EUR:0.01 -fee_refund = EUR:0.01 -age_restricted = YES -CIPHER = CS - -[coin_eur_ct_10_age_restricted] -value = EUR:0.10 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -age_restricted = YES -CIPHER = CS - -[coin_eur_1_age_restricted] -value = EUR:1 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -age_restricted = YES -CIPHER = CS - -[coin_eur_5_age_restricted] -value = EUR:5 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -age_restricted = YES -CIPHER = CS - -[coin_eur_10_age_restricted] -value = EUR:10 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -age_restricted = YES -CIPHER = CS diff --git a/src/testing/coins-rsa.conf b/src/testing/coins-rsa.conf @@ -61,68 +61,3 @@ fee_refresh = EUR:0.03 fee_refund = EUR:0.01 CIPHER = RSA rsa_keysize = 1024 - -[coin_eur_ct_1_age_restricted] -value = EUR:0.01 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.00 -fee_deposit = EUR:0.00 -fee_refresh = EUR:0.01 -fee_refund = EUR:0.01 -rsa_keysize = 1024 -age_restricted = YES -CIPHER = RSA - -[coin_eur_ct_10_age_restricted] -value = EUR:0.10 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -rsa_keysize = 1024 -age_restricted = YES -CIPHER = RSA - -[coin_eur_1_age_restricted] -value = EUR:1 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -rsa_keysize = 1024 -age_restricted = YES -CIPHER = RSA - -[coin_eur_5_age_restricted] -value = EUR:5 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -rsa_keysize = 1024 -age_restricted = YES -CIPHER = RSA - -[coin_eur_10_age_restricted] -value = EUR:10 -duration_withdraw = 7 days -duration_spend = 2 years -duration_legal = 3 years -fee_withdraw = EUR:0.01 -fee_deposit = EUR:0.01 -fee_refresh = EUR:0.03 -fee_refund = EUR:0.01 -rsa_keysize = 1024 -age_restricted = YES -CIPHER = RSA -\ No newline at end of file