commit a97ac260ec5196ba730455e0e4d966ae2940523c
parent 767755a57b1b58653ebd6522fe4f380e49019471
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date: Tue, 5 Mar 2024 23:17:51 +0100
Merge remote-tracking branch 'refs/remotes/origin/master'
Diffstat:
10 files changed, 613 insertions(+), 332 deletions(-)
diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c
@@ -327,7 +327,7 @@ struct DH_KeyStateHandle
* Mapping from donation unit keys to donation unit key issue struct.
* Used to lookup the key by hash.
*/
- struct GNUNET_CONTAINER_MultiHashMap *donation_unit_key_map;
+ struct GNUNET_CONTAINER_MultiHashMap *donation_unit_map;
/**
* Map from `struct DONAU_DonauPublicKey` to `struct SigningKey`
@@ -376,12 +376,6 @@ struct DH_KeyStateHandle
*/
struct GNUNET_TIME_Timestamp signature_expires;
- /**
- * True if #finish_keys_response() was not yet run and this key state
- * is only suitable for the /management/keys API.
- */
- bool management_only;
-
};
/**
@@ -433,17 +427,17 @@ struct HelperState
/**
* Handle for the donation_unit/RSA helper.
*/
- struct TALER_CRYPTO_RsaDenominationHelper*rsadh;
+ struct TALER_CRYPTO_RsaDonationUnitHelper*rsadh;
/**
* Handle for the donation_unit/CS helper.
*/
- struct TALER_CRYPTO_CsDenominationHelper*csdh;
+ struct TALER_CRYPTO_CsDonationUnitHelper*csdh;
/**
* Map from H(donation_unit_pub) to `struct HelperDonationUnit` entries.
*/
- struct GNUNET_CONTAINER_MultiHashMap *donation_unit_keys;
+ struct GNUNET_CONTAINER_MultiHashMap *donation_unit;
/**
* Map from H(rsa_pub) to `struct HelperDonationUnit` entries.
@@ -502,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)
*/
@@ -571,6 +565,289 @@ setup_general_response_headers (void *cls,
/**
+ * Closure for #insert_donation_unit_cb and #add_signkey_cb.
+ */
+struct KeysBuilderContext
+{
+ /**
+ * Our key state.
+ */
+ struct DH_KeyStateHandle *ksh;
+
+ /**
+ * Array of donation unit keys.
+ */
+ json_t *donation_units;
+
+ /**
+ * Array of signing keys.
+ */
+ json_t *signkeys;
+
+};
+
+
+/**
+ * Function called on all of our current and future donation unit keys
+ * known to the helper process. Filters out those that are current
+ * and adds the remaining donation unit keys (with their configuration
+ * data) to the JSON array.
+ *
+ * @param cls the `struct FutureBuilderContext *`
+ * @param h_donation_unit_pub hash of the donation unit public key
+ * @param value a `struct HelperDonationUnit`
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static enum GNUNET_GenericReturnValue
+insert_donation_unit_cb (void *cls,
+ const struct GNUNET_HashCode *h_donation_unit_pub,
+ void *value)
+{
+ struct KeysBuilderContext *kbc = cls;
+ struct HelperDonationUnit *hd = value;
+ struct DH_DonationUnitKey *donation_unit;
+ uint64_t validity_year;
+
+ donation_unit = GNUNET_CONTAINER_multihashmap_get (
+ kbc->ksh->donation_unit_map,
+ h_donation_unit_pub);
+ if (NULL != donation_unit)
+ return GNUNET_OK; /* skip: this key is already active! */
+ // if (GNUNET_TIME_relative_is_zero (hd->validity_duration))
+ // return GNUNET_OK; /* this key already expired! */
+
+ GNUNET_assert (
+ 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;
+}
+
+
+/**
+ *GroupData is the value we store for each group meta-data */
+struct GroupData
+{
+ /**
+ * The json blob with the group meta-data and list of denominations
+ */
+ json_t *json;
+
+ /**
+ * List of denominations for the group,
+ * included in @e json, do not free separately!
+ */
+ json_t *list;
+
+ /**
+ * Offset of the group in the final array.
+ */
+ unsigned int group_off;
+
+};
+
+
+/**
+ * Helper function called to clean up the group data
+ * in the denominations_by_group below.
+ *
+ * @param cls unused
+ * @param key unused
+ * @param value a `struct GroupData` to free
+ * @return #GNUNET_OK
+ */
+static int
+free_group (void *cls,
+ const struct GNUNET_HashCode *key,
+ void *value)
+{
+ struct GroupData *gd = value;
+
+ (void) cls;
+ (void) key;
+ GNUNET_free (gd);
+ return GNUNET_OK;
+}
+
+
+/**
* Update the "/keys" responses in @a ksh, computing the detailed replies.
*
* This function is to recompute all (including cherry-picked) responses we
@@ -583,34 +860,30 @@ static enum GNUNET_GenericReturnValue
finish_keys_response (struct DH_KeyStateHandle *ksh)
{
enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
- json_t *recoup;
struct SignKeyCtx sctx;
json_t *grouped_donation_units = NULL;
struct GNUNET_TIME_Timestamp last_cherry_pick_date;
struct GNUNET_CONTAINER_Heap *heap;
struct GNUNET_HashContext *hash_context = NULL;
- struct GNUNET_HashCode grouped_hash_xor = {0};
sctx.signkeys = json_array ();
GNUNET_assert (NULL != sctx.signkeys);
sctx.min_sk_frequency = GNUNET_TIME_UNIT_FOREVER_REL;
GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, &add_sign_key_cb,
&sctx);
- recoup = json_array ();
- GNUNET_assert (NULL != recoup);
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_key_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);
+ // = GNUNET_TIME_relative_min (dkc.min_dk_frequency,
+ // sctx.min_sk_frequency);
}
hash_context = GNUNET_CRYPTO_hash_context_start ();
@@ -620,27 +893,188 @@ finish_keys_response (struct DH_KeyStateHandle *ksh)
last_cherry_pick_date = GNUNET_TIME_UNIT_ZERO_TS;
+ {
+ struct DH_DonationUnitKey *dk;
+ struct GNUNET_CONTAINER_MultiHashMap *donation_units_by_group;
+
+ donation_units_by_group =
+ GNUNET_CONTAINER_multihashmap_create (1024,
+ GNUNET_NO /* NO, because keys are only on the stack */);
+ /* heap = max heap, sorted by start time */
+ while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap)))
+ {
+ 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;
+
+ /*
+ * Group the donation_units by {cipher, value, fees, age_mask}.
+ *
+ * For each group we save the group meta-data and the list of
+ * donation_units in this group as a json-blob in the multihashmap
+ * donation_units_by_group.
+ */
+ {
+ struct GroupData *group;
+ json_t *entry;
+ struct GNUNET_HashCode key;
+ struct DONAU_DonationUnitGroup meta = {
+ .cipher = dk->donation_unit_pub.bsign_pub_key->cipher,
+ .value = dk->value,
+ };
+
+ /* Search the group/JSON-blob for the key */
+ DONAU_donation_unit_group_get_key (&meta,
+ &key);
+ group = GNUNET_CONTAINER_multihashmap_get (
+ donation_units_by_group,
+ &key);
+ if (NULL == group)
+ {
+ /* There is no group for this meta-data yet, so we create a new group */
+ const char *cipher;
+
+ group = GNUNET_new (struct GroupData);
+
+ /* Create a new array for the donation_units in this group */
+ group->list = json_array ();
+ GNUNET_assert (NULL != group->list);
+ group->json = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("cipher",
+ cipher),
+ GNUNET_JSON_pack_array_steal ("donation_units",
+ group->list),
+ TALER_JSON_pack_amount ("value",
+ &meta.value));
+ GNUNET_assert (NULL != group->json);
+
+ group->group_off
+ = json_array_size (grouped_donation_units);
+ GNUNET_assert (0 ==
+ json_array_append_new (
+ grouped_donation_units,
+ group->json));
+ GNUNET_assert (
+ GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_put (donation_units_by_group,
+ &key,
+ group,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ }
+
+ /* Now that we have found/created the right group, add the
+ denomination to the list */
+ {
+ struct HelperDonationUnit *hd;
+ struct GNUNET_JSON_PackSpec key_spec;
+ bool private_key_lost;
+
+ hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->donation_unit,
+ &dk->h_donation_unit_pub.hash);
+ private_key_lost
+ = (NULL == hd) ||
+ GNUNET_TIME_absolute_is_past (
+ GNUNET_TIME_absolute_add (
+ hd->start_time.abs_time,
+ hd->validity_duration));
+ switch (meta.cipher)
+ {
+ case GNUNET_CRYPTO_BSA_RSA:
+ key_spec =
+ GNUNET_JSON_pack_rsa_public_key (
+ "rsa_pub",
+ dk->donation_unit_pub.bsign_pub_key->details.rsa_public_key);
+ break;
+ case GNUNET_CRYPTO_BSA_CS:
+ key_spec =
+ GNUNET_JSON_pack_data_varsize (
+ "cs_pub",
+ &dk->donation_unit_pub.bsign_pub_key->details.cs_public_key,
+ sizeof (dk->donation_unit_pub.bsign_pub_key->details.
+ cs_public_key));
+ break;
+ default:
+ GNUNET_assert (false);
+ }
+
+ entry = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_allow_null (
+ private_key_lost
+ ? GNUNET_JSON_pack_bool ("lost",
+ true)
+ : GNUNET_JSON_pack_string ("dummy",
+ NULL)),
+ key_spec
+ );
+ GNUNET_assert (NULL != entry);
+ }
+
+ /* Build up the running hash of all master signatures of the
+ donation_units */
+ // append_signature (&sig_ctx,
+ // group->group_off,
+ // (unsigned int) json_array_size (group->list),
+ // &dk->master_sig);
+ /* Finally, add the denomination to the list of donation_units in this
+ group */
+ GNUNET_assert (json_is_array (group->list));
+ GNUNET_assert (0 ==
+ json_array_append_new (group->list,
+ entry));
+ }
+ } /* loop over heap ends */
+
+ GNUNET_CONTAINER_multihashmap_iterate (donation_units_by_group,
+ &free_group,
+ NULL);
+ GNUNET_CONTAINER_multihashmap_destroy (donation_units_by_group);
+ }
+
GNUNET_CONTAINER_heap_destroy (heap);
if (! GNUNET_TIME_absolute_is_zero (last_cherry_pick_date.abs_time))
{
struct GNUNET_HashCode hc;
GNUNET_CRYPTO_hash_context_finish (hash_context, &hc);
- // if (GNUNET_OK !=
- // create_krd (ksh,
- // &hc,
- // last_cherry_pick_date,
- // sctx.signkeys,
- // recoup,
- // grouped_donation_units,
- // &grouped_hash_xor))
- // {
- // GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- // "Failed to generate key response data for %s\n",
- // GNUNET_TIME_timestamp2s (last_cherry_pick_date));
- // goto CLEANUP;
- // }
- ksh->management_only = false;
+ 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));
+ goto CLEANUP;
+ }
}
else
{
@@ -653,10 +1087,9 @@ finish_keys_response (struct DH_KeyStateHandle *ksh)
ret = GNUNET_OK;
-// CLEANUP:
+CLEANUP:
json_decref (grouped_donation_units);
- json_decref (sctx.signkeys);
- json_decref (recoup);
+ // json_decref (sctx.signkeys);
return ret;
}
@@ -836,7 +1269,7 @@ check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub)
/**
* Helper function for #destroy_key_helpers to free all entries
- * in the `donation_unit_keys` map.
+ * in the `donation_unit` map.
*
* @param cls the `struct HelperDonationUnit`
* @param h_donation_unit_pub hash of the donation unit public key
@@ -864,7 +1297,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)
*/
@@ -891,15 +1324,15 @@ free_esign_cb (void *cls,
static void
destroy_key_helpers (struct HelperState *hs)
{
- // GNUNET_CONTAINER_multihashmap_iterate (hs->donation_unit_keys,
+ // GNUNET_CONTAINER_multihashmap_iterate (hs->donation_unit,
// &free_donation_unit_cb,
// hs);
// GNUNET_CONTAINER_multihashmap_destroy (hs->rsa_keys);
// hs->rsa_keys = NULL;
// GNUNET_CONTAINER_multihashmap_destroy (hs->cs_keys);
// hs->cs_keys = NULL;
- // GNUNET_CONTAINER_multihashmap_destroy (hs->donation_unit_keys);
- // hs->donation_unit_keys = NULL;
+ // GNUNET_CONTAINER_multihashmap_destroy (hs->donation_unit);
+ // hs->donation_unit = NULL;
// GNUNET_CONTAINER_multipeermap_iterate (hs->esign_keys,
// &free_esign_cb,
// hs);
@@ -944,9 +1377,9 @@ destroy_key_state (struct DH_KeyStateHandle *ksh,
// gf);
// GNUNET_free (gf);
// }
- GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_key_map,
+ GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map,
&clear_donation_unit_cb, ksh);
- GNUNET_CONTAINER_multihashmap_destroy (ksh->donation_unit_key_map);
+ GNUNET_CONTAINER_multihashmap_destroy (ksh->donation_unit_map);
GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, &clear_signkey_cb,
ksh);
GNUNET_CONTAINER_multipeermap_destroy (ksh->signkey_map);
@@ -974,13 +1407,13 @@ destroy_key_state (struct DH_KeyStateHandle *ksh,
* being revoked, in that case with an @a end_time of zero.
*
* @param cls closure with the `struct HelperState *`
- * @param section_name name of the denomination type in the configuration;
+ * @param section_name name of the donation_unit type in the configuration;
* NULL if the key has been revoked or purged
* @param start_time when does the key become available for signing;
* 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 h_rsa hash of the @a denom_pub that is available (or was purged)
+ * @param h_rsa hash of the @a donation_unit_pub that is available (or was purged)
* @param bs_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
@@ -1001,7 +1434,7 @@ helper_rsa_cb (
struct HelperDonationUnit *hd;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "RSA helper announces key %s for denomination type %s with validity %s\n",
+ "RSA helper announces key %s for donation_unit type %s with validity %s\n",
GNUNET_h2s (&h_rsa->hash),
section_name,
GNUNET_STRINGS_relative_time_to_string (validity_duration,
@@ -1032,7 +1465,7 @@ helper_rsa_cb (
// GNUNET_assert (
// GNUNET_OK ==
// GNUNET_CONTAINER_multihashmap_put (
-// hs->donation_unit_keys,
+// hs->donation_unit,
// &hd->h_donation_unit_pub,
// hd,
// GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@@ -1106,7 +1539,7 @@ helper_cs_cb (
// GNUNET_assert (
// GNUNET_OK ==
// GNUNET_CONTAINER_multihashmap_put (
-// hs->donation_unit_keys,
+// hs->donation_unit,
// &hd->h_donation_unit_pub.hash,
// hd,
// GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@@ -1130,7 +1563,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.
@@ -1193,7 +1626,7 @@ helper_esign_cb (
static enum GNUNET_GenericReturnValue
setup_key_helpers (struct HelperState *hs)
{
- hs->donation_unit_keys
+ hs->donation_unit
= GNUNET_CONTAINER_multihashmap_create (1024,
GNUNET_YES);
hs->rsa_keys
@@ -1237,6 +1670,70 @@ setup_key_helpers (struct HelperState *hs)
/**
+ * 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
+ * @param h_donation_unit_pub hash of @a donation_unit_pub
+ */
+static void
+donation_unit_info_cb (
+ void *cls,
+ const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
+ const struct DONAU_DonationUnitHashP *h_donation_unit_pub,
+ uint64_t validity_year,
+ struct TALER_Amount *value)
+{
+ struct DH_KeyStateHandle *ksh = cls;
+ struct DH_DonationUnitKey *dk;
+//
+// if (GNUNET_OK !=
+// TALER_donau_offline_donation_unit_validity_verify (
+// h_donation_unit_pub,
+// meta->start,
+// meta->expire_withdraw,
+// meta->expire_deposit,
+// meta->expire_legal,
+// &meta->value,
+// &meta->fees,
+// &TEH_master_public_key,
+// master_sig))
+// {
+// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+// "Database has donation_unit with invalid signature. Skipping entry. Did the donau offline public key change?\n");
+// return;
+// }
+
+ // GNUNET_assert (GNUNET_CRYPTO_BSA_INVALID !=
+ // donation_unit_pub->bsign_pub_key->cipher);
+
+ // if (GNUNET_TIME_absolute_is_zero (meta->start.abs_time) ||
+ // GNUNET_TIME_absolute_is_zero (meta->expire_withdraw.abs_time) ||
+ // GNUNET_TIME_absolute_is_zero (meta->expire_deposit.abs_time) ||
+ // GNUNET_TIME_absolute_is_zero (meta->expire_legal.abs_time) )
+ // {
+ // GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ // "Database contains invalid donation_unit key %s\n",
+ // GNUNET_h2s (&h_donation_unit_pub->hash));
+ // return;
+ // }
+ dk = GNUNET_new (struct DH_DonationUnitKey);
+ DONAU_donation_unit_pub_deep_copy (&dk->donation_unit_pub,
+ donation_unit_pub);
+ dk->h_donation_unit_pub = *h_donation_unit_pub;
+ dk->validity_year = validity_year;
+ dk->value = *value;
+
+ GNUNET_assert (
+ GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_put (ksh->donation_unit_map,
+ &dk->h_donation_unit_pub.hash,
+ dk,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+}
+
+
+/**
* Create a key state.
*
* @param[in] hs helper state to (re)use, NULL if not available
@@ -1268,26 +1765,26 @@ build_key_state (struct HelperState *hs)
{
ksh->helpers = hs;
}
- ksh->donation_unit_key_map = GNUNET_CONTAINER_multihashmap_create (1024,
- true);
+ ksh->donation_unit_map = GNUNET_CONTAINER_multihashmap_create (1024,
+ true);
ksh->signkey_map = GNUNET_CONTAINER_multipeermap_create (32,
- false /* MUST be false! */
- );
+ false /* MUST be false! */);
+
/* NOTE: fetches master-signed signkeys, but ALSO those that were revoked! */
GNUNET_break (GNUNET_OK ==
DH_plugin->preflight (DH_plugin->cls));
-// qs = DH_plugin->iterate_donation_units (DH_plugin->cls,
-// &donation_unit_info_cb,
-// ksh);
- // if (qs < 0)
- // {
- // GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
- // GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
- // destroy_key_state (ksh,
- // true);
- // return NULL;
- // }
+ qs = DH_plugin->iterate_donation_units (DH_plugin->cls,
+ &donation_unit_info_cb,
+ ksh);
+ if (qs < 0)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
+ destroy_key_state (ksh,
+ true);
+ return NULL;
+ }
/* NOTE: ONLY fetches non-revoked AND master-signed signkeys! */
// qs = DH_plugin->iterate_active_signkeys (DH_plugin->cls,
// &signkey_info_cb,
@@ -1364,82 +1861,13 @@ DH_keys_get_state ()
/**
- * Closure for #insert_donation_unit_cb and #add_signkey_cb.
- */
-struct KeysBuilderContext
-{
- /**
- * Our key state.
- */
- struct DH_KeyStateHandle *ksh;
-
- /**
- * Array of donation unit keys.
- */
- json_t *donation_units;
-
- /**
- * Array of signing keys.
- */
- json_t *signkeys;
-
-};
-
-/**
- * Function called on all of our current and future donation unit keys
- * known to the helper process. Filters out those that are current
- * and adds the remaining donation unit keys (with their configuration
- * data) to the JSON array.
- *
- * @param cls the `struct FutureBuilderContext *`
- * @param h_donation_unit_pub hash of the donation unit public key
- * @param value a `struct HelperDonationUnit`
- * @return #GNUNET_OK (continue to iterate)
- */
-static enum GNUNET_GenericReturnValue
-insert_donation_unitkey_cb (void *cls,
- const struct GNUNET_HashCode *h_donation_unit_pub,
- void *value)
-{
- struct KeysBuilderContext *kbc = cls;
- struct HelperDonationUnit *helper_donation_unit = value;
- struct DH_DonationUnitKey *donation_unit_key;
- // struct TALER_Amount *value;
- // uint64_t validity_year;
-
- donation_unit_key = GNUNET_CONTAINER_multihashmap_get (
- kbc->ksh->donation_unit_key_map,
- h_donation_unit_pub);
- if (NULL != donation_unit_key)
- return GNUNET_OK; /* skip: this key is already active! */
- // if (GNUNET_TIME_relative_is_zero (hd->validity_duration))
- // 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)
- )));
- return GNUNET_OK;
-}
-
-
-/**
- * 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)
*/
@@ -1501,9 +1929,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)) )
{
@@ -1523,8 +1954,9 @@ DH_handler_keys (struct DH_RequestContext *rc,
GNUNET_assert (NULL != kbc.donation_units);
GNUNET_assert (NULL != kbc.signkeys);
GNUNET_assert (NULL != DH_currency);
- GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers->donation_unit_keys,
- &insert_donation_unitkey_cb, &kbc);
+ // GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers->donation_unit,
+ // &insert_donation_unit_cb,
+ // &kbc);
GNUNET_CONTAINER_multipeermap_iterate (ksh->helpers->esign_keys,
&add_signkey_cb, &kbc);
reply = GNUNET_JSON_PACK (
diff --git a/src/donau/donau-httpd_keys.h b/src/donau/donau-httpd_keys.h
@@ -39,26 +39,26 @@ struct DH_DonationUnitKey
{
/**
+ * Hash code of the donation unit public key.
+ */
+ struct DONAU_DonationUnitHashP h_donation_unit_pub;
+
+ /**
* Decoded donation unit public key (the hash of it is in
* @e issue, but we sometimes need the full public key as well).
*/
struct DONAU_DonationUnitPublicKey donation_unit_pub;
/**
- * Hash code of the donation unit public key.
+ * The validity year.
*/
- struct DONAU_DonationUnitHashP h_donation_unit_pub;
+ uint64_t validity_year;
/**
* Value that the donation unit represents.
*/
struct TALER_Amount value;
- /**
- * The validity year.
- */
- uint64_t validity_year;
-
};
/**
diff --git a/src/donaudb/0002-donation_units.sql b/src/donaudb/0002-donation_units.sql
@@ -1,6 +1,6 @@
--
-- This file is part of TALER
--- Copyright (C) 2023 Taler Systems SA
+-- Copyright (C) 2024 Taler Systems SA
--
-- TALER is free software; you can redistribute it and/or modify it under the
-- terms of the GNU General Public License as published by the Free Software
diff --git a/src/donaudb/pg_insert_donation_unit.c b/src/donaudb/pg_insert_donation_unit.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
+ Copyright (C) 2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -31,8 +31,8 @@ DH_PG_insert_donation_unit (
void *cls,
const struct DONAU_DonationUnitHashP *h_donation_unit_pub,
const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
- struct TALER_Amount *value,
- uint64_t validity_year)
+ uint64_t validity_year,
+ struct TALER_Amount *value)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam iparams[] = {
diff --git a/src/donaudb/pg_insert_donation_unit.h b/src/donaudb/pg_insert_donation_unit.h
@@ -40,7 +40,7 @@ DH_PG_insert_donation_unit (
void *cls,
const struct DONAU_DonationUnitHashP *h_donation_unit_pub,
const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
- struct TALER_Amount *value,
- uint64_t validity_year);
+ uint64_t validity_year,
+ struct TALER_Amount *value);
#endif
diff --git a/src/include/donaudb_plugin.h b/src/include/donaudb_plugin.h
@@ -447,10 +447,10 @@ struct DONAUDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_donation_unit)(
void *cls,
- const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
const struct DONAU_DonationUnitHashP *h_donation_unit_pub,
- struct TALER_Amount value,
- uint64_t validity_year);
+ const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
+ uint64_t validity_year,
+ struct TALER_Amount *value);
/**
* Insert history entry of a charity
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
diff --git a/src/util/donau_crypto.c b/src/util/donau_crypto.c
@@ -43,7 +43,6 @@ struct DonationUnitGroupP
GNUNET_NETWORK_STRUCT_END
-
void
DONAU_donation_unit_group_get_key (
const struct DONAU_DonationUnitGroup *dg,
@@ -60,9 +59,12 @@ DONAU_donation_unit_group_get_key (
key);
}
+
int
-DONAU_donation_unit_pub_cmp (const struct DONAU_DonationUnitPublicKey *donation_unit1,
- const struct DONAU_DonationUnitPublicKey *donation_unit2)
+DONAU_donation_unit_pub_cmp (const struct
+ DONAU_DonationUnitPublicKey *donation_unit1,
+ const struct
+ DONAU_DonationUnitPublicKey *donation_unit2)
{
if (donation_unit1->bsign_pub_key->cipher !=
donation_unit2->bsign_pub_key->cipher)
@@ -72,16 +74,23 @@ DONAU_donation_unit_pub_cmp (const struct DONAU_DonationUnitPublicKey *donation_
donation_unit2->bsign_pub_key);
}
+
void
-DONAU_donation_unit_pub_deep_copy (struct DONAU_DonationUnitPublicKey *donation_unit_dst,
- const struct DONAU_DonationUnitPublicKey *donation_unit_src)
+DONAU_donation_unit_pub_deep_copy (struct
+ DONAU_DonationUnitPublicKey *
+ donation_unit_dst,
+ const struct
+ DONAU_DonationUnitPublicKey *
+ donation_unit_src)
{
donation_unit_dst->bsign_pub_key
= GNUNET_CRYPTO_bsign_pub_incref (donation_unit_src->bsign_pub_key);
}
+
void
-DONAU_donation_unit_pub_free (struct DONAU_DonationUnitPublicKey *donation_unit_pub)
+DONAU_donation_unit_pub_free (struct
+ DONAU_DonationUnitPublicKey *donation_unit_pub)
{
if (NULL != donation_unit_pub->bsign_pub_key)
{
@@ -89,19 +98,3 @@ DONAU_donation_unit_pub_free (struct DONAU_DonationUnitPublicKey *donation_unit_
donation_unit_pub->bsign_pub_key = NULL;
}
}
-
-void
-DONAU_donatin_unit_group_get_key (
- const struct DONAU_DonationUnitGroup *dg,
- struct GNUNET_HashCode *key)
-{
- struct DonationUnitGroupP dgp = {
- .cipher = htonl (dg->cipher)
- };
-
- TALER_amount_hton (&dgp.value,
- &dg->value);
- GNUNET_CRYPTO_hash (&dgp,
- sizeof (dgp),
- key);
-}
-\ No newline at end of file