donau

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

commit 3a038f23f69d8c80de38df37905cad9510afa3fa
parent ec58ff7406578940de826747dd3b14414b7b2825
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date:   Tue, 12 Mar 2024 09:18:35 +0100

Merge remote-tracking branch 'refs/remotes/origin/master'

Diffstat:
Msrc/donau/donau-httpd.h | 5+++++
Msrc/donau/donau-httpd_keys.c | 145++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc/donaudb/Makefile.am | 1+
Msrc/donaudb/pg_insert_signing_key.c | 2+-
Asrc/donaudb/pg_iterate_active_signing_keys.c | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/donaudb/pg_iterate_active_signing_keys.h | 39+++++++++++++++++++++++++++++++++++++++
Msrc/donaudb/pg_lookup_signing_key.c | 2+-
Msrc/donaudb/plugin_donaudb_postgres.c | 3+++
Msrc/include/donaudb_plugin.h | 18++++++++++++++++--
9 files changed, 288 insertions(+), 61 deletions(-)

diff --git a/src/donau/donau-httpd.h b/src/donau/donau-httpd.h @@ -73,6 +73,11 @@ extern char *DH_currency; extern char *DH_domain; /** + * Protocol version. + */ +extern char *DONAU_PROTOCOL_VERSION; + +/** * Our (externally visible) base URL. */ extern char *DH_base_url; diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -649,7 +649,7 @@ 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 *signkeys, json_t *grouped_donation_units) { struct KeysResponseData krd; @@ -660,7 +660,7 @@ create_krd (struct DH_KeyStateHandle *ksh, // GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( // last_cherry_pick_date.abs_time)); - // GNUNET_assert (NULL != signkeys); + GNUNET_assert (NULL != signkeys); GNUNET_assert (NULL != grouped_donation_units); GNUNET_assert (NULL != DH_currency); GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -669,49 +669,49 @@ create_krd (struct DH_KeyStateHandle *ksh, // /* 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); -// } + // 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 ("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 ("signkeys", + signkeys), GNUNET_JSON_pack_array_incref ("donation_units", - grouped_donation_units)); // , - // GNUNET_JSON_pack_data_auto ("donau_pub", - // &donau_pub)); // , + 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); @@ -919,7 +919,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) create_krd (ksh, &hc, last_cherry_pick_date, - // sctx.signkeys, + sctx.signkeys, grouped_donation_units)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -1069,7 +1069,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) create_krd (ksh, &hc, last_cherry_pick_date, - // sctx.signkeys, + sctx.signkeys, grouped_donation_units)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -1091,7 +1091,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) CLEANUP: json_decref (grouped_donation_units); - // json_decref (sctx.signkeys); + json_decref (sctx.signkeys); return ret; } @@ -1736,6 +1736,37 @@ donation_unit_info_cb ( /** + * Function called with information about the donau's online signing keys. + * + * @param cls closure with a `struct DH_KeyStateHandle *` + * @param donau_pub the public key + * @param meta meta data information about the denomination type (expirations) + * @param master_sig master signature affirming the validity of this denomination + */ +static void +iterate_active_signing_keys_cb ( + void *cls, + const struct DONAU_DonauPublicKeyP *donau_pub, + const struct DONAUDB_SignkeyMetaData *meta) +{ + struct DH_KeyStateHandle *ksh = cls; + struct SigningKey *sk; + struct GNUNET_PeerIdentity pid; + + sk = GNUNET_new (struct SigningKey); + sk->donau_pub = *donau_pub; + sk->meta = *meta; + pid.public_key = donau_pub->eddsa_pub; + GNUNET_assert ( + GNUNET_OK == + GNUNET_CONTAINER_multipeermap_put (ksh->signkey_map, + &pid, + sk, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); +} + + +/** * Create a key state. * * @param[in] hs helper state to (re)use, NULL if not available @@ -1787,17 +1818,17 @@ build_key_state (struct HelperState *hs) true); return NULL; } - /* NOTE: ONLY fetches non-revoked AND master-signed signkeys! */ -// qs = DH_plugin->iterate_active_signkeys (DH_plugin->cls, -// &signkey_info_cb, -// ksh); - // if (qs < 0) - // { - // GNUNET_break (0); - // destroy_key_state (ksh, - // true); - // return NULL; - // } + /* NOTE: ONLY fetches active signkeys! */ + qs = DH_plugin->iterate_active_signing_keys (DH_plugin->cls, + &iterate_active_signing_keys_cb, + ksh); + if (qs < 0) + { + GNUNET_break (0); + destroy_key_state (ksh, + true); + return NULL; + } if (GNUNET_OK != finish_keys_response (ksh)) { GNUNET_log ( @@ -1901,10 +1932,10 @@ add_signkey_cb (void *cls, &hsk->donau_pub), // GNUNET_JSON_pack_timestamp ("stamp_end", // legal_end), - GNUNET_JSON_pack_data_auto ( - "year", &hsk->year) - // GNUNET_JSON_pack_data_auto ("signkey_secmod_sig", - // &hsk->sm_sig) + GNUNET_JSON_pack_data_auto ("year", + &hsk->year) // , + // GNUNET_JSON_pack_data_auto ("signkey_secmod_sig", + // &hsk->sm_sig) ))); return GNUNET_OK; } @@ -1962,8 +1993,8 @@ DH_handler_keys (struct DH_RequestContext *rc, GNUNET_CONTAINER_multipeermap_iterate (ksh->helpers->esign_keys, &add_signkey_cb, &kbc); reply = GNUNET_JSON_PACK ( - // GNUNET_JSON_pack_string ("version", - // DONAU_PROTOCOL_VERSION), + GNUNET_JSON_pack_string ("version", + DONAU_PROTOCOL_VERSION), GNUNET_JSON_pack_string ("domain", DH_domain), GNUNET_JSON_pack_string ("base_url", diff --git a/src/donaudb/Makefile.am b/src/donaudb/Makefile.am @@ -80,6 +80,7 @@ libtaler_plugin_donaudb_postgres_la_SOURCES = \ pg_start_read_only.h pg_start_read_only.c \ pg_insert_signing_key.c pg_insert_signing_key.h \ pg_lookup_signing_key.h pg_lookup_signing_key.c \ + pg_iterate_active_signing_keys.c pg_iterate_active_signing_keys.h \ pg_insert_donation_unit.c pg_insert_donation_unit.h \ pg_iterate_donation_units.c pg_iterate_donation_units.h \ pg_get_history.h pg_get_history.c \ diff --git a/src/donaudb/pg_insert_signing_key.c b/src/donaudb/pg_insert_signing_key.c @@ -34,7 +34,7 @@ DH_PG_insert_signing_key ( struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam iparams[] = { GNUNET_PQ_query_param_auto_from_type (donau_pub), - GNUNET_PQ_query_param_timestamp (&meta->start), + GNUNET_PQ_query_param_timestamp (&meta->valid_from), GNUNET_PQ_query_param_timestamp (&meta->expire_sign), GNUNET_PQ_query_param_timestamp (&meta->expire_legal), GNUNET_PQ_query_param_end diff --git a/src/donaudb/pg_iterate_active_signing_keys.c b/src/donaudb/pg_iterate_active_signing_keys.c @@ -0,0 +1,134 @@ +/* + This file is part of TALER + 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file donaudb/pg_iterate_active_signing_keys.c + * @brief Implementation of the iterate_active_signing_keys function for Postgres + * @author Christian Grothoff + */ +#include <taler/platform.h> +#include <taler/taler_error_codes.h> +#include <taler/taler_dbevents.h> +#include <taler/taler_pq_lib.h> +#include "pg_iterate_active_signing_keys.h" +#include "pg_helper.h" + +/** + * Closure for #signkeys_cb_helper(). + */ +struct IterateActiveSigningKeysContext +{ + /** + * Function to call per result. + */ + DONAUDB_IterateActiveSigningKeysCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Flag set to #GNUNET_OK as long as everything is fine. + */ + enum GNUNET_GenericReturnValue status; + +}; + +/** + * Invoke the callback for each result. + * + * @param cls a `struct MissingWireContext *` + * @param result SQL result + * @param num_results number of rows in @a result + */ +static void +signkeys_cb_helper (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct IterateActiveSigningKeysContext *ctx = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + struct DONAU_DonauPublicKeyP donau_pub; + struct DONAUDB_SignkeyMetaData *meta; + + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("donau_pub", + &donau_pub), + GNUNET_PQ_result_spec_timestamp ("valid_from", + &meta->valid_from), + GNUNET_PQ_result_spec_timestamp ("expire_sign", + &meta->expire_sign), + GNUNET_PQ_result_spec_timestamp ("expire_legal", + &meta->expire_legal), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ctx->status = GNUNET_SYSERR; + return; + } + ctx->cb (ctx->cb_cls, + &donau_pub, + &meta); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +DH_PG_iterate_active_signing_keys (void *cls, + DONAUDB_IterateActiveSigningKeysCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_TIME_Absolute now = {0}; + struct IterateActiveSigningKeysContext ctx = { + .cb = cb, + .cb_cls = cb_cls, + .status = GNUNET_OK + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "lookup_signing_key", + "SELECT" + " donau_pub" + ",valid_from" + ",expire_sign" + ",expire_legal" + " FROM donau_sign_keys dsk" + " WHERE" + " expire_sign > $1"); + qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, + "iterate_active_signing_keys", + params, + &signkeys_cb_helper, + &ctx); + if (GNUNET_OK != ctx.status) + return GNUNET_DB_STATUS_HARD_ERROR; + return qs; +} diff --git a/src/donaudb/pg_iterate_active_signing_keys.h b/src/donaudb/pg_iterate_active_signing_keys.h @@ -0,0 +1,39 @@ +/* + This file is part of TALER + Copyright (C) 2022 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file donaudb/pg_iterate_active_signing_keys.h + * @brief implementation of the iterate_active_signing_keys function for Postgres + * @author Johannes Casaburi + */ +#ifndef PG_ITERATE_ACTIVE_SIGNING_KEYS_H +#define PG_ITERATE_ACTIVE_SIGNING_KEYS_H + +#include "donaudb_plugin.h" + +/** + * Obtain information about the enabled wire accounts of the exchange. + * + * @param cls closure + * @param cb function to call on each account + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +DH_PG_iterate_active_signing_keys (void *cls, + DONAUDB_IterateActiveSigningKeysCallback cb, + void *cb_cls); + +#endif diff --git a/src/donaudb/pg_lookup_signing_key.c b/src/donaudb/pg_lookup_signing_key.c @@ -39,7 +39,7 @@ DH_PG_lookup_signing_key ( }; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_timestamp ("valid_from", - &meta->start), + &meta->valid_from), GNUNET_PQ_result_spec_timestamp ("expire_sign", &meta->expire_sign), GNUNET_PQ_result_spec_timestamp ("expire_legal", diff --git a/src/donaudb/plugin_donaudb_postgres.c b/src/donaudb/plugin_donaudb_postgres.c @@ -56,6 +56,7 @@ #include "pg_insert_issued_receipt.h" #include "pg_insert_submitted_receipt.h" #include "pg_insert_signing_key.h" +#include "pg_iterate_active_signing_keys.h" #include "pg_lookup_signing_key.h" #include "pg_lookup_charity.h" #include "pg_get_charities.h" @@ -253,6 +254,8 @@ libtaler_plugin_donaudb_postgres_init (void *cls) = &DH_PG_insert_signing_key; plugin->lookup_signing_key = &DH_PG_lookup_signing_key; + plugin->iterate_active_signing_keys + = &DH_PG_iterate_active_signing_keys; plugin->lookup_charity = &DH_PG_lookup_charity; plugin->insert_charity diff --git a/src/include/donaudb_plugin.h b/src/include/donaudb_plugin.h @@ -34,7 +34,7 @@ struct DONAUDB_SignkeyMetaData /** * Start time of the validity period for this key. */ - struct GNUNET_TIME_Timestamp start; + struct GNUNET_TIME_Timestamp valid_from; /** * The donau will sign messages with this key between @e start and this time. @@ -118,7 +118,7 @@ struct DONAUDB_DonationUnitKey * @param meta meta data information about the signing type (expirations) */ typedef void -(*DONAUDB_ActiveSignkeysCallback)( +(*DONAUDB_IterateActiveSigningKeysCallback)( void *cls, const struct DONAU_DonauPublicKeyP *donau_pub, struct DONAUDB_SignkeyMetaData *meta); @@ -535,6 +535,20 @@ struct DONAUDB_Plugin const struct DONAU_DonauPublicKeyP *donau_pub, struct DONAUDB_SignkeyMetaData *meta); + /** + * Iterate donau signing keys. + * + * @param cls closure + * @param cb callback to invoke on each match + * @param cb_cls closure for @a cb + * @return database transaction status + */ + enum GNUNET_DB_QueryStatus + (*iterate_active_signing_keys)( + void *cls, + DONAUDB_IterateActiveSigningKeysCallback cb, + void *cb_cls); + }; #endif