donau

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

commit 7130aee6b2c600c47fcaf18eda83eb180b89d2a8
parent 6d0ca3689831975872db2220b01790e297551aa5
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date:   Wed, 13 Mar 2024 20:16:46 +0100

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

Diffstat:
Msrc/donau/donau-httpd_config.h | 2+-
Msrc/donau/donau-httpd_keys.c | 227+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/include/donau_crypto_lib.h | 12++++++++++++
3 files changed, 147 insertions(+), 94 deletions(-)

diff --git a/src/donau/donau-httpd_config.h b/src/donau/donau-httpd_config.h @@ -41,7 +41,7 @@ * * Returned via both /config and /keys endpoints. */ -#define DONAU_PROTOCOL_VERSION "17:0:0" +#define DONAU_PROTOCOL_VERSION "0:0:0" /** diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -253,22 +253,33 @@ struct HelperDonationUnit }; + /** - * Information about a signing key on offer by the sign helper. + * Information about a signing key on offer by the esign helper. */ struct HelperSignkey { /** * When will the helper start to use this key for signing? */ - // struct GNUNET_TIME_Timestamp start_time; - int year; + struct GNUNET_TIME_Timestamp start_time; + + /** + * For how long will the helper allow signing? 0 if + * the key was revoked or purged. + */ + struct GNUNET_TIME_Relative validity_duration; /** * The public key. */ struct DONAU_DonauPublicKeyP donau_pub; + /** + * Signature over this key from the security module's key. + */ + struct TALER_SecurityModuleSignatureP sm_sig; + }; /** @@ -427,12 +438,12 @@ struct HelperState /** * Handle for the donation_unit/RSA helper. */ - struct DONAU_CRYPTO_RsaDonationUnitHelper*rsadh; + struct TALER_CRYPTO_RsaDenominationHelper *rsadh; /** * Handle for the donation_unit/CS helper. */ - struct TALER_CRYPTO_CsDonationUnitHelper*csdh; + struct TALER_CRYPTO_CsDenominationHelper *csdh; /** * Map from H(donation_unit_pub) to `struct HelperDonationUnit` entries. @@ -509,31 +520,27 @@ add_sign_key_cb (void *cls, struct SigningKey *sk = value; (void) pid; - // if (GNUNET_TIME_absolute_is_future (sk->meta.expire_sign.abs_time)) - // { - // ctx->min_sk_frequency = - // GNUNET_TIME_relative_min (ctx->min_sk_frequency, - // GNUNET_TIME_absolute_get_difference ( - // sk->meta.start.abs_time, - // sk->meta.expire_sign.abs_time)); - // } - GNUNET_assert (0 == json_array_append_new (ctx->signkeys, GNUNET_JSON_PACK ( - GNUNET_JSON_pack_timestamp ( - "stamp_start", - sk-> - meta.valid_from), - GNUNET_JSON_pack_timestamp ( - "stamp_expire", - sk-> - meta.expire_sign), - GNUNET_JSON_pack_timestamp ( - "stamp_end", - sk-> - meta.expire_legal), - GNUNET_JSON_pack_data_auto ( - "key", - &sk-> - donau_pub)))); + if (GNUNET_TIME_absolute_is_future (sk->meta.expire_sign.abs_time)) + { + ctx->min_sk_frequency = + GNUNET_TIME_relative_min (ctx->min_sk_frequency, + GNUNET_TIME_absolute_get_difference ( + sk->meta.valid_from.abs_time, + sk->meta.expire_sign.abs_time)); + } + GNUNET_assert ( + 0 == + json_array_append_new ( + ctx->signkeys, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_timestamp ("stamp_start", + sk->meta.valid_from), + GNUNET_JSON_pack_timestamp ("stamp_expire", + sk->meta.expire_sign), + // GNUNET_JSON_pack_timestamp ("stamp_end", + // sk->meta.expire_legal), + GNUNET_JSON_pack_data_auto ("key", + &sk->donau_pub)))); return GNUNET_OK; } @@ -600,13 +607,13 @@ struct KeysBuilderContext * data) to the JSON array. * * @param cls the `struct FutureBuilderContext *` - * @param h_donation_unit_pub hash of the donation unit public key + * @param h_du_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, + const struct GNUNET_HashCode *h_du_pub, void *value) { struct KeysBuilderContext *kbc = cls; @@ -615,7 +622,7 @@ insert_donation_unit_cb (void *cls, du = GNUNET_CONTAINER_multihashmap_get ( kbc->ksh->donation_unit_map, - h_donation_unit_pub); + h_du_pub); if (NULL != du) return GNUNET_OK; /* skip: this key is already active! */ // if (GNUNET_TIME_relative_is_zero (hd->validity_duration)) @@ -628,11 +635,11 @@ insert_donation_unit_cb (void *cls, GNUNET_JSON_pack_data_auto ("donation_unit_pub", &hd->donation_unit_pub), // GNUNET_JSON_pack_uint64 ("validity_year", - // du->validity_year), + // du->validity_year), // TALER_JSON_pack_amount ("value", // &du->value), - GNUNET_JSON_pack_data_auto ("donation_unit_secmod_sig", - &hd->sm_sig), + // GNUNET_JSON_pack_data_auto ("donation_unit_secmod_sig", + // &hd->sm_sig), GNUNET_JSON_pack_string ("section_name", hd->section_name) ))); @@ -645,7 +652,7 @@ insert_donation_unit_cb (void *cls, * 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[in] h_donation_unit_pub 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 @@ -653,14 +660,14 @@ insert_donation_unit_cb (void *cls, */ static enum GNUNET_GenericReturnValue create_krd (struct DH_KeyStateHandle *ksh, - const struct GNUNET_HashCode *denom_keys_hash, + const struct GNUNET_HashCode *h_du_pub, 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; + // struct DONAU_DonauSignatureP donau_sig; json_t *keys; @@ -684,7 +691,7 @@ create_krd (struct DH_KeyStateHandle *ksh, // &TEH_keys_donau_sign2_, // ksh, // last_cherry_pick_date, - // denom_keys_hash, + // h_donation_unit_pub, // &donau_pub, // &donau_sig))) // { @@ -698,9 +705,10 @@ create_krd (struct DH_KeyStateHandle *ksh, { const struct SigningKey *sk; - sk = GNUNET_CONTAINER_multipeermap_get ( - ksh->signkey_map, - (const struct GNUNET_PeerIdentity *) &donau_pub); + 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); } @@ -876,8 +884,20 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) 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, + + GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, + &add_sign_key_cb, &sctx); + + if (0 == json_array_size (sctx.signkeys)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "No online signing keys available. Refusing to generate /keys response.\n") + ; + ret = GNUNET_NO; + goto CLEANUP; + } + heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); { struct DonationUnitKeyCtx dkc = { @@ -906,7 +926,8 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) donation_units_by_group = GNUNET_CONTAINER_multihashmap_create (1024, - GNUNET_NO /* NO, because keys are only on the stack */); + 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))) { @@ -939,7 +960,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) } } - // last_cherry_pick_date = dk->meta.start; + // last_cherry_pick_date = dk->meta.validity_year; /* * Group the donation_units by {cipher, value, fees, age_mask}. @@ -968,6 +989,18 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) /* There is no group for this meta-data yet, so we create a new group */ const char *cipher; + switch (meta.cipher) + { + case GNUNET_CRYPTO_BSA_RSA: + cipher = "RSA"; + break; + case GNUNET_CRYPTO_BSA_CS: + cipher = "CS"; + break; + default: + GNUNET_assert (false); + } + group = GNUNET_new (struct GroupData); /* Create a new array for the donation_units in this group */ @@ -993,7 +1026,8 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) GNUNET_CONTAINER_multihashmap_put (donation_units_by_group, &key, group, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) + ); } /* Now that we have found/created the right group, add the @@ -1004,7 +1038,8 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) bool private_key_lost; hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->donation_unit, - &dk->h_donation_unit_pub.hash); + &dk->h_donation_unit_pub.hash) + ; private_key_lost = (NULL == hd) || GNUNET_TIME_absolute_is_past ( @@ -1097,7 +1132,8 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) CLEANUP: json_decref (grouped_donation_units); - json_decref (sctx.signkeys); + if (NULL != sctx.signkeys) + json_decref (sctx.signkeys); return ret; } @@ -1112,14 +1148,14 @@ CLEANUP: */ static enum GNUNET_GenericReturnValue clear_donation_unit_cb (void *cls, - const struct GNUNET_HashCode *h_donation_unit_pub, + const struct GNUNET_HashCode *h_du_pub, void *value) { struct DH_DonationUnitKey *dk = value; (void) cls; - (void) h_donation_unit_pub; - // TALER_donation_unit_pub_free (&dk->donation_unit_pub); + (void) h_du_pub; + DONAU_donation_unit_pub_free (&dk->donation_unit_pub); GNUNET_free (dk); return GNUNET_OK; } @@ -1218,7 +1254,8 @@ check_donation_unit_rsa_sm_pub (const struct if (! GNUNET_is_zero (&donation_unit_rsa_sm_pub)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Our RSA security module changed its key. This must not happen.\n"); + "Our RSA security module changed its key. This must not happen.\n") + ; GNUNET_assert (0); } donation_unit_rsa_sm_pub = *sm_pub; /* TOFU ;-) */ @@ -1243,7 +1280,8 @@ check_donation_unit_cs_sm_pub (const struct if (! GNUNET_is_zero (&donation_unit_cs_sm_pub)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Our CS security module changed its key. This must not happen.\n"); + "Our CS security module changed its key. This must not happen.\n") + ; GNUNET_assert (0); } donation_unit_cs_sm_pub = *sm_pub; /* TOFU ;-) */ @@ -1267,7 +1305,8 @@ check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) if (! GNUNET_is_zero (&esign_sm_pub)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Our EdDSA security module changed its key. This must not happen.\n"); + "Our EdDSA security module changed its key. This must not happen.\n") + ; GNUNET_assert (0); } esign_sm_pub = *sm_pub; /* TOFU ;-) */ @@ -1286,7 +1325,8 @@ check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) */ static enum GNUNET_GenericReturnValue free_donation_unit_cb (void *cls, - const struct GNUNET_HashCode *h_donation_unit_pub, + const struct DONAU_DonationUnitHashP *h_donation_unit_pub + , void *value) { struct HelperDonationUnit *hd = value; @@ -1375,26 +1415,15 @@ static void destroy_key_state (struct DH_KeyStateHandle *ksh, bool free_helper) { - // struct DH_GlobalFee *gf; - clear_response_cache (ksh); - // while (NULL != (gf = ksh->gf_head)) - // { - // GNUNET_CONTAINER_DLL_remove (ksh->gf_head, - // ksh->gf_tail, - // gf); - // GNUNET_free (gf); - // } + GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, &clear_donation_unit_cb, ksh); 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); - // json_decref (ksh->auditors); - // ksh->auditors = NULL; - // json_decref (ksh->global_fees); - // ksh->global_fees = NULL; + if (free_helper) { destroy_key_helpers (ksh->helpers); @@ -1474,7 +1503,7 @@ helper_rsa_cb ( GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( hs->donation_unit, - &hd->h_donation_unit_pub, + &hd->h_donation_unit_pub.hash, hd, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); GNUNET_assert ( @@ -1737,7 +1766,8 @@ donation_unit_info_cb ( GNUNET_CONTAINER_multihashmap_put (ksh->donation_unit_map, &dk->h_donation_unit_pub.hash, dk, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) + ); } @@ -1752,7 +1782,7 @@ static void iterate_active_signing_keys_cb ( void *cls, const struct DONAU_DonauPublicKeyP *donau_pub, - const struct DONAUDB_SignkeyMetaData *meta) + struct DONAUDB_SignkeyMetaData *meta) { struct DH_KeyStateHandle *ksh = cls; struct SigningKey *sk; @@ -1767,7 +1797,8 @@ iterate_active_signing_keys_cb ( GNUNET_CONTAINER_multipeermap_put (ksh->signkey_map, &pid, sk, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) + ); } @@ -1806,7 +1837,8 @@ build_key_state (struct HelperState *hs) 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 == @@ -1838,7 +1870,8 @@ build_key_state (struct HelperState *hs) { GNUNET_log ( GNUNET_ERROR_TYPE_WARNING, - "Could not finish /keys response (likely no signing keys available yet)\n"); + "Could not finish /keys response (likely no signing keys available yet)\n") + ; destroy_key_state (ksh, true); return NULL; @@ -1917,31 +1950,39 @@ add_signkey_cb (void *cls, struct KeysBuilderContext *kbc = cls; struct HelperSignkey *hsk = value; struct SigningKey *sk; - // struct GNUNET_TIME_Timestamp stamp_expire; + + struct GNUNET_TIME_Timestamp stamp_expire; // struct GNUNET_TIME_Timestamp legal_end; - sk = GNUNET_CONTAINER_multipeermap_get (kbc->ksh->signkey_map, pid); - if (NULL != sk) - return GNUNET_OK; /* skip: this key is already active */ + // sk = GNUNET_CONTAINER_multipeermap_get (kbc->ksh->signkey_map, pid); + // if (NULL != sk) + // return GNUNET_OK; /* skip: this key is already active */ + // if (GNUNET_TIME_relative_is_zero (hsk->validity_duration)) // return GNUNET_OK; /* this key already expired! */ - // stamp_expire = GNUNET_TIME_absolute_to_timestamp ( - // GNUNET_TIME_absolute_add (hsk->start_time.abs_time, - // hsk->validity_duration)); + + stamp_expire = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (hsk->start_time.abs_time, + hsk->validity_duration)); + // legal_end = GNUNET_TIME_absolute_to_timestamp ( // GNUNET_TIME_absolute_add (stamp_expire.abs_time, // signkey_legal_duration)); - GNUNET_assert ( - 0 == json_array_append_new (kbc->signkeys, GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("key", - &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_assert (0 == + json_array_append_new ( + kbc->signkeys, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("key", + &hsk->donau_pub), + GNUNET_JSON_pack_timestamp ("stamp_start", + hsk->start_time), + GNUNET_JSON_pack_timestamp ("stamp_expire", + stamp_expire), + // GNUNET_JSON_pack_timestamp ("stamp_end", + // legal_end), + GNUNET_JSON_pack_data_auto ("signkey_secmod_sig", + &hsk->sm_sig)))); return GNUNET_OK; } diff --git a/src/include/donau_crypto_lib.h b/src/include/donau_crypto_lib.h @@ -157,6 +157,18 @@ DONAU_donation_unit_pub_free (struct DONAU_DonationUnitPublicKey *donation_unit_pub); /** + * Compute the hash of the given @a donation_unit_pub. + * + * @param donation_unit_pub public key to hash + * @param[out] donation_unit_hash resulting hash value + */ +void +DONAU_donation_unit_pub_hash (const struct + DONAU_DonationUnitPublicKey *donation_unit_pub, + struct DONAU_DonationUnitHashP *donation_unit_hash + ); + +/** * Hash used to represent a Donation Receipt */ struct DONAU_DonationReceiptHashP