donau

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

commit 3b6d3d4f61c633945c293f7b3e7b0a51d796ec94
parent 13151cdcda66d31efbee8ea51d9cd8e674d9f7ca
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Wed, 10 Apr 2024 12:54:10 +0200

added blind batch sign

Diffstat:
Msrc/donau/donau-httpd_keys.c | 289++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/donau/donau-httpd_keys.h | 45++++++++++++++++++++++++++++-----------------
Msrc/donau/donau-httpd_post-batch-issue.c | 25+++++++++++++++----------
3 files changed, 225 insertions(+), 134 deletions(-)

diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -669,7 +669,7 @@ helper_rsa_cb ( const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { - struct DH_DonationUnitKey *hd; + struct DH_DonationUnitKey *du; struct TALER_Amount value; enum GNUNET_DB_QueryStatus qs; @@ -693,40 +693,40 @@ helper_rsa_cb ( section_name, GNUNET_STRINGS_relative_time_to_string (validity_duration, false)); - hd = GNUNET_CONTAINER_multihashmap_get (du_keys, + du = GNUNET_CONTAINER_multihashmap_get (du_keys, &h_rsa->hash); - if (NULL != hd) + if (NULL != du) { /* only update 'lost' status */ - hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); + du->lost = GNUNET_TIME_relative_is_zero (validity_duration); return; } GNUNET_assert (NULL != sm_pub); check_donation_unit_rsa_sm_pub (sm_pub); - hd = GNUNET_new (struct DH_DonationUnitKey); - hd->h_donation_unit_pub.hash = h_rsa->hash; - hd->donation_unit_pub.bsign_pub_key + du = GNUNET_new (struct DH_DonationUnitKey); + du->h_donation_unit_pub.hash = h_rsa->hash; + du->donation_unit_pub.bsign_pub_key = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); - hd->validity_year = GNUNET_TIME_time_to_year (start_time.abs_time); - hd->value = value; - hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); + du->validity_year = GNUNET_TIME_time_to_year (start_time.abs_time); + du->value = value; + du->lost = GNUNET_TIME_relative_is_zero (validity_duration); GNUNET_assert ( GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( du_keys, - &hd->h_donation_unit_pub.hash, - hd, + &du->h_donation_unit_pub.hash, + du, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); qs = DH_plugin->insert_donation_unit ( DH_plugin->cls, - &hd->h_donation_unit_pub, - &hd->donation_unit_pub, - hd->validity_year, - &hd->value); + &du->h_donation_unit_pub, + &du->donation_unit_pub, + du->validity_year, + &du->value); if (qs < 0) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -768,7 +768,7 @@ helper_cs_cb ( const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { - struct DH_DonationUnitKey *hd; + struct DH_DonationUnitKey *du; struct TALER_Amount value; enum GNUNET_DB_QueryStatus qs; @@ -793,38 +793,38 @@ helper_cs_cb ( section_name, GNUNET_STRINGS_relative_time_to_string (validity_duration, false)); - hd = GNUNET_CONTAINER_multihashmap_get (du_keys, + du = GNUNET_CONTAINER_multihashmap_get (du_keys, &h_cs->hash); - if (NULL != hd) + if (NULL != du) { /* should be just an update (revocation!), so update existing entry */ - hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); + du->lost = GNUNET_TIME_relative_is_zero (validity_duration); return; } GNUNET_assert (NULL != sm_pub); check_donation_unit_cs_sm_pub (sm_pub); - hd = GNUNET_new (struct DH_DonationUnitKey); - hd->h_donation_unit_pub.hash = h_cs->hash; - hd->donation_unit_pub.bsign_pub_key + du = GNUNET_new (struct DH_DonationUnitKey); + du->h_donation_unit_pub.hash = h_cs->hash; + du->donation_unit_pub.bsign_pub_key = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); - hd->validity_year = GNUNET_TIME_time_to_year (start_time.abs_time); - hd->value = value; - hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); + du->validity_year = GNUNET_TIME_time_to_year (start_time.abs_time); + du->value = value; + du->lost = GNUNET_TIME_relative_is_zero (validity_duration); GNUNET_assert ( GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( du_keys, - &hd->h_donation_unit_pub.hash, - hd, + &du->h_donation_unit_pub.hash, + du, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); qs = DH_plugin->insert_donation_unit ( DH_plugin->cls, - &hd->h_donation_unit_pub, - &hd->donation_unit_pub, - hd->validity_year, - &hd->value); + &du->h_donation_unit_pub, + &du->donation_unit_pub, + du->validity_year, + &du->value); if (qs < 0) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1009,33 +1009,33 @@ donation_unit_info_cb ( uint64_t validity_year, struct TALER_Amount *value) { - struct DH_DonationUnitKey *hd; + struct DH_DonationUnitKey *du; GNUNET_assert (GNUNET_CRYPTO_BSA_INVALID != donation_unit_pub->bsign_pub_key->cipher); - hd = GNUNET_CONTAINER_multihashmap_get (du_keys, + du = GNUNET_CONTAINER_multihashmap_get (du_keys, &h_donation_unit_pub->hash); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got %s key from database\n", - NULL == hd ? "unknown" : "known"); - if (NULL != hd) + NULL == du ? "unknown" : "known"); + if (NULL != du) { /* we already know this, nothing to do */ return GNUNET_OK; } - hd = GNUNET_new (struct DH_DonationUnitKey); - hd->h_donation_unit_pub = *h_donation_unit_pub; - DONAU_donation_unit_pub_deep_copy (&hd->donation_unit_pub, + du = GNUNET_new (struct DH_DonationUnitKey); + du->h_donation_unit_pub = *h_donation_unit_pub; + DONAU_donation_unit_pub_deep_copy (&du->donation_unit_pub, donation_unit_pub); - hd->validity_year = validity_year; - hd->value = *value; - hd->lost = true; /* no private key known, that can only come from the helper! */ + du->validity_year = validity_year; + du->value = *value; + du->lost = true; /* no private key known, that can only come from the helper! */ GNUNET_assert ( GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (du_keys, - &hd->h_donation_unit_pub.hash, - hd, + &du->h_donation_unit_pub.hash, + du, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) ); return GNUNET_OK; @@ -1287,83 +1287,158 @@ DH_keys_donau_sign_ ( } -#if DEAD -/** - * Callback used to set headers in a response. - * - * @param cls closure - * @param[in,out] resp response to modify - */ -typedef void -(*DH_RESPONSE_SetHeaders) (void *cls, - struct MHD_Response *resp); - -// STATIC? needed? -MHD_RESULT -DH_RESPONSE_reply_not_modified (struct MHD_Connection *connection, - const char *etags, - DH_RESPONSE_SetHeaders cb, - void *cb_cls) +enum TALER_ErrorCode +DH_keys_denomination_batch_sign ( + unsigned int csds_length, + const struct DH_BlindSignData csds[static csds_length], + struct DONAU_BlindedDonationUnitSignature bss[static csds_length]) { - MHD_RESULT ret; - struct MHD_Response *resp; + struct DH_KeyStateHandle *ksh; + struct DH_DonationUnitKey *du; + struct TALER_CRYPTO_RsaSignRequest rsrs[csds_length]; + struct TALER_CRYPTO_CsSignRequest csrs[csds_length]; + struct DONAU_BlindedDonationUnitSignature rs[csds_length]; + struct DONAU_BlindedDonationUnitSignature cs[csds_length]; + unsigned int rsrs_pos = 0; + unsigned int csrs_pos = 0; + enum TALER_ErrorCode ec; - resp = MHD_create_response_from_buffer (0, - NULL, - MHD_RESPMEM_PERSISTENT); - cb (cb_cls, resp); - GNUNET_break ( - MHD_YES == MHD_add_response_header (resp, MHD_HTTP_HEADER_ETAG, etags)); - ret = MHD_queue_response (connection, - MHD_HTTP_NOT_MODIFIED, - resp); - GNUNET_break (MHD_YES == ret); - MHD_destroy_response (resp); - return ret; -} + ksh = DH_keys_get_state (); + if (NULL == ksh) + // FIXME change error code + return TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING; + for (unsigned int i = 0; i<csds_length; i++) + { + const struct DONAU_DonationUnitHashP *h_du_pub = csds[i].h_du_pub; + const struct DONAU_BlindedUniqueDonationIdentifier *budi = csds[i].budi; + + du = GNUNET_CONTAINER_multihashmap_get (du_keys, + &h_du_pub->hash); + if (NULL == du) + // FIXME change error code + return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; + if (budi->blinded_message->cipher != + du->donation_unit_pub.bsign_pub_key->cipher) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + switch (du->donation_unit_pub.bsign_pub_key->cipher) + { + case GNUNET_CRYPTO_BSA_RSA: + rsrs[rsrs_pos].h_rsa = &du->h_donation_unit_pub.hash; + rsrs[rsrs_pos].msg + = budi->blinded_message->details.rsa_blinded_message.blinded_msg; + rsrs[rsrs_pos].msg_size + = budi->blinded_message->details.rsa_blinded_message.blinded_msg_size; + rsrs_pos++; + break; + case GNUNET_CRYPTO_BSA_CS: + csrs[csrs_pos].h_cs = &du->h_donation_unit_pub.hash; + csrs[csrs_pos].blinded_planchet + = &budi->blinded_message->details.cs_blinded_message; + csrs_pos++; + break; + default: + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } + } + if ( (0 != csrs_pos) && + (0 != rsrs_pos) ) + { + memset (rs, + 0, + sizeof (rs)); + memset (cs, + 0, + sizeof (cs)); + } + ec = TALER_EC_NONE; + if (0 != csrs_pos) + { + ec = TALER_CRYPTO_helper_cs_batch_sign ( + csdh, + csrs_pos, + csrs, + false, // for_melt + (0 == rsrs_pos) ? bss : cs); + if (TALER_EC_NONE != ec) + { + for (unsigned int i = 0; i<csrs_pos; i++) + { + if (NULL != cs[i].blinded_sig) + { + GNUNET_CRYPTO_blinded_sig_decref (cs[i].blinded_sig); + cs[i].blinded_sig = NULL; + } + } + return ec; + } + // TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_CS] += csrs_pos; + } + if (0 != rsrs_pos) + { + ec = TALER_CRYPTO_helper_rsa_batch_sign ( + rsadh, + rsrs_pos, + rsrs, + (0 == csrs_pos) ? bss : rs); + if (TALER_EC_NONE != ec) + { + for (unsigned int i = 0; i<csrs_pos; i++) + { + if (NULL != cs[i].blinded_sig) + { + GNUNET_CRYPTO_blinded_sig_decref (cs[i].blinded_sig); + cs[i].blinded_sig = NULL; + } + } + for (unsigned int i = 0; i<rsrs_pos; i++) + { + if (NULL != rs[i].blinded_sig) + { + GNUNET_CRYPTO_blinded_sig_decref (rs[i].blinded_sig); + rs[i].blinded_sig = NULL; + } + } + return ec; + } + // TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_RSA] += rsrs_pos; + } -#endif + if ( (0 != csrs_pos) && + (0 != rsrs_pos) ) + { + rsrs_pos = 0; + csrs_pos = 0; + for (unsigned int i = 0; i<csds_length; i++) + { + const struct DONAU_BlindedUniqueDonationIdentifier *budi = csds[i].budi; + + switch (budi->blinded_message->cipher) + { + case GNUNET_CRYPTO_BSA_RSA: + bss[i] = rs[rsrs_pos++]; + break; + case GNUNET_CRYPTO_BSA_CS: + bss[i] = cs[csrs_pos++]; + break; + default: + GNUNET_assert (0); + } + } + } + return TALER_EC_NONE; +} struct DH_DonationUnitKey * DH_keys_donation_unit_by_hash ( - const struct DONAU_DonationUnitHashP *h_du_pub, - struct MHD_Connection *conn, - MHD_RESULT *mret) + const struct DONAU_DonationUnitHashP *h_du_pub) { struct DH_DonationUnitKey *dk; - dk = GNUNET_CONTAINER_multihashmap_get (du_keys, &h_du_pub->hash); - if (NULL == dk) - { - if (NULL == conn) - return NULL; - *mret = TALER_MHD_reply_with_error (conn, - MHD_HTTP_NOT_FOUND, - TALER_EC_DONAU_GENERIC_KEYS_MISSING, - NULL); - return NULL; - } return dk; } -enum GNUNET_GenericReturnValue -DONAU_donation_unit_sign_blinded (struct DONAU_BlindedDonationUnitSignature *du_sig, - const struct DONAU_DonationUnitHashP *h_pub, - const struct DONAU_BlindedUniqueDonationIdentifier *budi) -{ - // FIXME: get private key from the hash of the public key... - const struct DONAU_DonationUnitPrivateKey *du_priv = {0}; - du_sig->blinded_sig - = GNUNET_CRYPTO_blind_sign (du_priv->bsign_priv_key, - /*for_melt ? "rm" :*/ "rw", - budi->blinded_message); - if (NULL == du_sig->blinded_sig) - return GNUNET_SYSERR; - return GNUNET_OK; -} - /* end of donau-httpd_keys.c */ diff --git a/src/donau/donau-httpd_keys.h b/src/donau/donau-httpd_keys.h @@ -66,6 +66,22 @@ struct DH_DonationUnitKey }; /** + * Information needed to create a blind signature. + */ +struct DH_BlindSignData +{ + /** + * Hash of key to sign with. + */ + const struct DONAU_DonationUnitHashP *h_du_pub; + + /** + * Blinded planchet to sign over. + */ + const struct DONAU_BlindedDonationUnitSignature *budi; +}; + +/** * Sign the message in @a purpose with the exchange's signing key. * * The @a purpose data is the beginning of the data of which the signature is @@ -144,10 +160,7 @@ DH_handler_keys (struct DH_RequestContext *rc, */ struct DH_DonationUnitKey * DH_keys_donation_unit_by_hash ( - const struct DONAU_DonationUnitHashP *h_du_pub, - struct MHD_Connection *conn, - MHD_RESULT *mret); - + const struct DONAU_DonationUnitHashP *h_du_pub); /** * Initialize keys subsystem. @@ -163,22 +176,20 @@ DH_keys_init (void); void DH_keys_finished (void); - /** - * Create blinded signature. + * Request to sign @a csds. * - * @param[out] du_sig where to write the signature - * @param h_pub private key to use for signing - * @param budi the unique identifier already blinded - * @return #GNUNET_OK on success + * @param csds array with data to blindly sign (and keys to sign with) + * @param csds_length length of @a csds array + * @param for_melt true if this is for a melt operation + * @param[out] bss array set to the blind signature on success; must be of length @a csds_length + * @return #TALER_EC_NONE on success */ -enum GNUNET_GenericReturnValue -DONAU_donation_unit_sign_blinded (struct - DONAU_BlindedDonationUnitSignature *du_sig, - const struct - DONAU_DonationUnitHashP *h_pub, - const struct - DONAU_BlindedUniqueDonationIdentifier *budi); +enum TALER_ErrorCode +DH_keys_donatn_batch_sign ( + unsigned int csds_length, + const struct DONAU_DonationUnitHashP csds[static csds_length], + struct DONAU_BlindedDonationUnitSignature bss[static csds_length]); #endif diff --git a/src/donau/donau-httpd_post-batch-issue.c b/src/donau/donau-httpd_post-batch-issue.c @@ -310,21 +310,23 @@ start: MHD_RESULT mret; struct DH_DonationUnitKey *dk; // FIXME always public key not found - if (NULL == (dk = DH_keys_donation_unit_by_hash (&irc.bkp[i].h_donation_unit_pub, - rc->connection, - &mret))) - return mret; - if (GNUNET_OK != TALER_check_currency(receipts_sum.currency)) - GNUNET_memcpy(receipts_sum.currency, dk->value.currency, sizeof(char) * TALER_CURRENCY_LEN); + // if (NULL == (dk = DH_keys_donation_unit_by_hash (&irc.bkp[i].h_donation_unit_pub, + // rc->connection, + // &mret))) + // return mret; + if (GNUNET_OK != TALER_check_currency (receipts_sum.currency)) + GNUNET_memcpy (receipts_sum.currency, dk->value.currency, sizeof(char) + * TALER_CURRENCY_LEN); GNUNET_assert (0 <= TALER_amount_add (&receipts_sum, &receipts_sum, - &dk->value)); + &dk->value)); } struct TALER_Amount new_receipts_to_date; TALER_amount_add (&new_receipts_to_date, &receipts_sum, &charity_meta.receipts_to_date); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "new_receipts_to_date: %lu, receipts_sum: %lu, charity_max_per_year: %lu\n", - new_receipts_to_date.value, receipts_sum.value, charity_meta.max_per_year.value); + new_receipts_to_date.value, receipts_sum.value, charity_meta. + max_per_year.value); // new_receipts_to_date has to be smaller or equal as max_per_year if (0 > TALER_amount_cmp (&new_receipts_to_date, &charity_meta.max_per_year)) return TALER_MHD_reply_with_error (rc->connection, @@ -340,11 +342,14 @@ start: for (size_t i = 0; i < num_bkp; i++) { // FIXME private key is missing - //const struct DONAU_DonationUnitPrivateKey du_priv; + // const struct DONAU_DonationUnitPrivateKey du_priv; const struct DONAU_BlindedUniqueDonationIdentifier budi = irc.bkp[i]. blinded_udi; struct DONAU_BlindedDonationUnitSignature *du_sig = &du_sigs[i]; - if (GNUNET_SYSERR == DONAU_donation_unit_sign_blinded (du_sig, &irc.bkp[i].h_donation_unit_pub, & + if (GNUNET_SYSERR == DONAU_donation_unit_sign_blinded (du_sig, &irc.bkp[i] + . + h_donation_unit_pub, + & budi)) { GNUNET_break (0);