donau

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

commit e17aef432003100f94b44b920d5254f652ef3387
parent 561f1ede9664df957f7849ad2d71063aaf1c1b08
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date:   Mon,  8 Apr 2024 00:54:04 +0200

[testing] finish keys test

Diffstat:
Msrc/include/donau_json_lib.h | 7++-----
Msrc/include/donau_service.h | 37+++++++++++++++++++++++++------------
Msrc/json/donau_json.c | 199+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/lib/donau_api_handle.c | 225+++++++++++++++++++++++++++----------------------------------------------------
Msrc/testing/test_donau_api.c | 10+++++-----
Msrc/testing/testing_api_cmd_get_donau.c | 78+++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/testing/testing_api_cmd_issue_receipts.c | 1+
7 files changed, 252 insertions(+), 305 deletions(-)

diff --git a/src/include/donau_json_lib.h b/src/include/donau_json_lib.h @@ -31,18 +31,15 @@ #include <taler/taler_json_lib.h> /** - * Generate a parser specification for a donation unit public key of a given - * cipher. + * Generate a parser specification for a donation unit public key. * * @param field name of the field - * @param cipher which cipher type to parse for * @param[out] pk key to fill * @return corresponding field spec */ struct GNUNET_JSON_Specification -DONAU_JSON_spec_donation_unit_pub_cipher ( +DONAU_JSON_spec_donation_unit_pub ( const char *field, - enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, struct DONAU_DonationUnitPublicKey *pk); diff --git a/src/include/donau_service.h b/src/include/donau_service.h @@ -45,9 +45,14 @@ struct DONAU_SigningPublicKeyAndValidity struct DONAU_DonauPublicKeyP key; /** - * Tax year this key is valid for. + * Start time of the validity period for this key. */ - uint32_t year; + struct GNUNET_TIME_Timestamp valid_from; + + /** + * The donau will sign messages with this key between @e start and this time. + */ + struct GNUNET_TIME_Timestamp expire_sign; }; @@ -69,7 +74,14 @@ struct DONAU_DonationUnitInformation /** * Year of validity */ - uint32_t year; + uint64_t year; + + /** + * Set to true if the private donation unit key has been + * lost by the donau and thus the key cannot be + * used for issuing receipts at this time. + */ + bool lost; }; @@ -520,15 +532,16 @@ typedef void */ struct DONAU_BatchIssueReceiptHandle * DONAU_charity_issue_receipt ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct DONAU_CharityPrivateKeyP *charity_priv, - const uint64_t charity_id, - const uint64_t year, - const unsigned int num_bkp, - const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static num_bkp], - DONAU_BatchIssueReceiptsCallback cb, - void *cb_cls); + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct DONAU_CharityPrivateKeyP *charity_priv, + const uint64_t charity_id, + const uint64_t year, + const unsigned int num_bkp, + const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static + num_bkp], + DONAU_BatchIssueReceiptsCallback cb, + void *cb_cls); /** * Cancel a batch issue receipt request. This function cannot be used diff --git a/src/json/donau_json.c b/src/json/donau_json.c @@ -25,6 +25,24 @@ #include <unistr.h> #include "donau_json_lib.h" +/** + * Convert string value to numeric cipher value. + * + * @param cipher_s input string + * @return numeric cipher value + */ +static enum GNUNET_CRYPTO_BlindSignatureAlgorithm +string_to_cipher (const char *cipher_s) +{ + if (0 == strcasecmp (cipher_s, + "RSA")) + return GNUNET_CRYPTO_BSA_RSA; + if (0 == strcasecmp (cipher_s, + "CS")) + return GNUNET_CRYPTO_BSA_CS; + return GNUNET_CRYPTO_BSA_INVALID; +} + /** * Parse given JSON object partially into a donation unit public key. @@ -37,21 +55,35 @@ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error */ static enum GNUNET_GenericReturnValue -parse_donation_unit_pub_cipher (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) +parse_donation_unit_pub (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) { struct DONAU_DonationUnitPublicKey *donation_unit_pub = spec->ptr; - enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher = - (enum GNUNET_CRYPTO_BlindSignatureAlgorithm) (long) cls; struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub; + const char *cipher; + struct GNUNET_JSON_Specification dspec[] = { + GNUNET_JSON_spec_string ("cipher", + &cipher), + GNUNET_JSON_spec_end () + }; const char *emsg; unsigned int eline; + if (GNUNET_OK != + GNUNET_JSON_parse (root, + dspec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + bsign_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); - bsign_pub->cipher = cipher; bsign_pub->rc = 1; - switch (cipher) + bsign_pub->cipher = string_to_cipher (cipher); + switch (bsign_pub->cipher) { case GNUNET_CRYPTO_BSA_INVALID: break; @@ -59,7 +91,7 @@ parse_donation_unit_pub_cipher (void *cls, { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_public_key ( - "rsa_pub", + "rsa_public_key", &bsign_pub->details.rsa_public_key), GNUNET_JSON_spec_end () }; @@ -80,7 +112,7 @@ parse_donation_unit_pub_cipher (void *cls, case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_fixed ("cs_pub", + GNUNET_JSON_spec_fixed ("cs_public_key", &bsign_pub->details.cs_public_key, sizeof (bsign_pub->details.cs_public_key)), GNUNET_JSON_spec_end () @@ -124,17 +156,13 @@ clean_donation_unit_pub (void *cls, struct GNUNET_JSON_Specification -DONAU_JSON_spec_donation_unit_pub_cipher (const char *field, - enum - GNUNET_CRYPTO_BlindSignatureAlgorithm - cipher, - struct DONAU_DonationUnitPublicKey *pk) +DONAU_JSON_spec_donation_unit_pub (const char *field, + struct DONAU_DonationUnitPublicKey *pk) { struct GNUNET_JSON_Specification ret = { - .parser = &parse_donation_unit_pub_cipher, + .parser = &parse_donation_unit_pub, .cleaner = &clean_donation_unit_pub, .field = field, - .cls = (void *) cipher, .ptr = pk }; @@ -142,85 +170,66 @@ DONAU_JSON_spec_donation_unit_pub_cipher (const char *field, } -/** - * Convert string value to numeric cipher value. - * - * @param cipher_s input string - * @return numeric cipher value - */ -static enum GNUNET_CRYPTO_BlindSignatureAlgorithm -string_to_cipher (const char *cipher_s) -{ - if (0 == strcasecmp (cipher_s, - "RSA")) - return GNUNET_CRYPTO_BSA_RSA; - if (0 == strcasecmp (cipher_s, - "CS")) - return GNUNET_CRYPTO_BSA_CS; - return GNUNET_CRYPTO_BSA_INVALID; -} - - -static enum GNUNET_GenericReturnValue -parse_donation_unit_group (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct DONAU_DonationUnitGroup *group = spec->ptr; - const char *cipher; - const char *currency = cls; - struct GNUNET_JSON_Specification gspec[] = { - GNUNET_JSON_spec_string ("cipher", - &cipher), - TALER_JSON_spec_amount ("value", - currency, - &group->value), - GNUNET_JSON_spec_end () - }; - const char *emsg; - unsigned int eline; - - if (GNUNET_OK != - GNUNET_JSON_parse (root, - gspec, - &emsg, - &eline)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to parse %s at %u: %s\n", - spec[eline].field, - eline, - emsg); - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - group->cipher = string_to_cipher (cipher); - if (GNUNET_CRYPTO_BSA_INVALID == group->cipher) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - return GNUNET_OK; -} - - -struct GNUNET_JSON_Specification -DONAU_JSON_spec_donation_unit_group (const char *name, - const char *currency, - struct DONAU_DonationUnitGroup *group) -{ - struct GNUNET_JSON_Specification ret = { - .cls = (void *) currency, - .parser = &parse_donation_unit_group, - .field = name, - .ptr = group, - .ptr_size = sizeof(*group) - }; - - return ret; -} +// static enum GNUNET_GenericReturnValue +// parse_donation_unit_group (void *cls, +// json_t *root, +// struct GNUNET_JSON_Specification *spec) +// { +// struct DONAU_DonationUnitGroup *group = spec->ptr; +// const char *cipher; +// const char *currency = cls; +// struct GNUNET_JSON_Specification gspec[] = { +// GNUNET_JSON_spec_string ("cipher", +// &cipher), +// TALER_JSON_spec_amount ("value", +// currency, +// &group->value), +// GNUNET_JSON_spec_end () +// }; +// const char *emsg; +// unsigned int eline; + +// if (GNUNET_OK != +// GNUNET_JSON_parse (root, +// gspec, +// &emsg, +// &eline)) +// { +// GNUNET_log (GNUNET_ERROR_TYPE_WARNING, +// "Failed to parse %s at %u: %s\n", +// spec[eline].field, +// eline, +// emsg); +// GNUNET_break_op (0); +// return GNUNET_SYSERR; +// } + +// group->cipher = string_to_cipher (cipher); +// if (GNUNET_CRYPTO_BSA_INVALID == group->cipher) +// { +// GNUNET_break_op (0); +// return GNUNET_SYSERR; +// } + +// return GNUNET_OK; +// } + + +// struct GNUNET_JSON_Specification +// DONAU_JSON_spec_donation_unit_group (const char *name, +// const char *currency, +// struct DONAU_DonationUnitGroup *group) +// { +// struct GNUNET_JSON_Specification ret = { +// .cls = (void *) currency, +// .parser = &parse_donation_unit_group, +// .field = name, +// .ptr = group, +// .ptr_size = sizeof(*group) +// }; + +// return ret; +// } /** diff --git a/src/lib/donau_api_handle.c b/src/lib/donau_api_handle.c @@ -137,8 +137,10 @@ parse_json_signkey (struct DONAU_SigningPublicKeyAndValidity *sign_key, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("key", &sign_key->key), - GNUNET_JSON_spec_uint32 ("year", - &sign_key->year), + GNUNET_JSON_spec_timestamp ("stamp_start", + &sign_key->valid_from), + GNUNET_JSON_spec_timestamp ("stamp_expire", + &sign_key->expire_sign), GNUNET_JSON_spec_end () }; @@ -155,34 +157,39 @@ parse_json_signkey (struct DONAU_SigningPublicKeyAndValidity *sign_key, /** - * Compare two donation unit keys. + * Parse a donau's donation unit key encoded in JSON. * - * @param donation_unit1 first donation unit key - * @param donation_unit2 second donation unit key - * @return 0 if the two keys are equal (not necessarily - * the same object), 1 otherwise. + * @param[out] du where to return the result + * @param donation_unit_obj json to parse + * @return #GNUNET_OK if all is fine, #GNUNET_SYSERR if @a donation_unit_obj + * is malformed. */ -static unsigned int -donation_units_cmp (const struct DONAU_DonationUnitInformation *donation_unit1, - const struct DONAU_DonationUnitInformation *donation_unit2) +static enum GNUNET_GenericReturnValue +parse_json_donation_unit (struct DONAU_DonationUnitInformation *du, + const json_t *donation_unit_obj) { - struct DONAU_DonationUnitInformation tmp1; - struct DONAU_DonationUnitInformation tmp2; - - if (0 != - DONAU_donation_unit_pub_cmp (&donation_unit1->key, - &donation_unit2->key)) - return 1; - tmp1 = *donation_unit1; - tmp2 = *donation_unit2; - memset (&tmp1.key, - 0, - sizeof (tmp1.key)); - memset (&tmp2.key, - 0, - sizeof (tmp2.key)); - return GNUNET_memcmp (&tmp1, - &tmp2); + struct GNUNET_JSON_Specification spec[] = { + DONAU_JSON_spec_donation_unit_pub ("donation_unit_pub", + &du->key), + GNUNET_JSON_spec_uint64 ("year", + &du->year), + GNUNET_JSON_spec_bool ("lost", + &du->lost), + TALER_JSON_spec_amount_any ("value", + &du->value), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (donation_unit_obj, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + + return GNUNET_OK; } @@ -202,7 +209,7 @@ decode_keys_json (const json_t *resp_obj, enum DONAU_VersionCompatibility *vc) { const json_t *sign_keys_array; - const json_t *donation_units_by_group; + const json_t *donation_units_array; if (JSON_OBJECT != json_typeof (resp_obj)) { @@ -265,14 +272,14 @@ decode_keys_json (const json_t *resp_obj, const char *currency; struct GNUNET_JSON_Specification mspec[] = { GNUNET_JSON_spec_array_const ( - "sign_keys", + "signkeys", &sign_keys_array), GNUNET_JSON_spec_string ( "currency", - &currency), // &key_data->currency instead? + &currency), GNUNET_JSON_spec_array_const ( - "donation_units_group", - &donation_units_by_group), + "donation_units", + &donation_units_array), GNUNET_JSON_spec_end () }; const char *emsg; @@ -290,20 +297,20 @@ decode_keys_json (const json_t *resp_obj, eline); EXITIF (1); } - { - struct GNUNET_JSON_Specification sspec[] = { // why separate sspec and mspec? - TALER_JSON_spec_currency_specification ( - "currency_specification", - currency, - &key_data->currency_specification), - GNUNET_JSON_spec_end () - }; - - EXITIF (GNUNET_OK != - GNUNET_JSON_parse (resp_obj, - sspec, - NULL, NULL)); - } +// { +// struct GNUNET_JSON_Specification sspec[] = { // why separate sspec and mspec? +// TALER_JSON_spec_currency_specification ( +// "currency_specification", +// currency, +// &key_data->currency_specification), +// GNUNET_JSON_spec_end () +// }; +// +// EXITIF (GNUNET_OK != +// GNUNET_JSON_parse (resp_obj, +// sspec, +// NULL, NULL)); +// } key_data->currency = GNUNET_strdup (currency); } @@ -328,102 +335,23 @@ decode_keys_json (const json_t *resp_obj, /* * Parse the donation unit keys - * - * The donation units are grouped by common values of - * {cipher, value}. */ + key_data->num_donation_unit_keys + = json_array_size (donation_units_array); + if (0 != key_data->num_donation_unit_keys) { - json_t *group_obj; - unsigned int group_idx; - - json_array_foreach (donation_units_by_group, - group_idx, group_obj) - { - /* First, parse { cipher, value} of the current - group. */ - struct DONAU_DonationUnitGroup group = {0}; // what must be given to be a part of a group? - const json_t *donation_unit_keys_array; - struct GNUNET_JSON_Specification group_spec[] = { - DONAU_JSON_spec_donation_unit_group (NULL, - key_data->currency, - &group), - GNUNET_JSON_spec_array_const ("donation_units", - &donation_unit_keys_array), - GNUNET_JSON_spec_end () - }; - json_t *donation_unit_key_obj; - unsigned int index; + json_t *donation_unit_obj; + size_t index; + key_data->donation_unit_keys + = GNUNET_new_array (key_data->num_donation_unit_keys, + struct DONAU_DonationUnitInformation); + json_array_foreach (donation_units_array, index, donation_unit_obj) { EXITIF (GNUNET_SYSERR == - GNUNET_JSON_parse (group_obj, - group_spec, - NULL, - NULL)); - - /* Now, parse the individual donation units */ - json_array_foreach (donation_unit_keys_array, - index, - donation_unit_key_obj) - { - /* Set the common fields from the group for this particular - donation unit. Required to make the validity check inside - parse_json_denomkey_partially pass */ - struct DONAU_DonationUnitInformation dk = { - .value = group.value - }; - bool found = false; - - struct GNUNET_JSON_Specification kspec[] = { - GNUNET_JSON_spec_uint32 ("year", &dk.year), - DONAU_JSON_spec_donation_unit_pub_cipher (NULL, - group.cipher, - &dk.key), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (donation_unit_key_obj, - kspec, - NULL, NULL)) - { - GNUNET_break_op (0); - EXITIF (1); - } - - for (unsigned int j = 0; - j<key_data->num_donation_unit_keys; - j++) - { - if (0 == donation_units_cmp (&dk, - &key_data->donation_unit_keys[j])) - { - found = true; - break; - } - } - - if (found) - { - TALER_LOG_DEBUG ("Skipping donation unit key: already know it\n"); - DONAU_donation_unit_pub_free (&dk.key); - continue; - } - - if (key_data->donation_unit_keys_size == - key_data->num_donation_unit_keys) - GNUNET_array_grow (key_data->donation_unit_keys, - key_data->donation_unit_keys_size, - key_data->donation_unit_keys_size * 2 + 2); - key_data->donation_unit_keys[key_data->num_donation_unit_keys++] = dk; - - TALER_LOG_DEBUG ( - "Adding donation unit key that is valid for the year %d\n", - dk.year); - - }; /* end of json_array_foreach over donation units */ - - } /* end of json_array_foreach over groups of donation units */ - } /* end of scope for group_ojb/group_idx */ + parse_json_donation_unit (&key_data->donation_unit_keys[index], + donation_unit_obj)); + } + } return GNUNET_OK; @@ -434,7 +362,7 @@ EXITIF_exit: /** - * Callback used when downloading the reply to a /keys request + * Callback used when downloading the reply to a /keys request * is complete. * * @param cls the `struct KeysRequest` @@ -590,9 +518,9 @@ DONAU_get_keys ( gkh->url = TALER_url_join (url, "keys", NULL); - // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - // "Requesting keys with URL `%s'.\n", - // gkh->url); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Requesting keys with URL `%s'.\n", + gkh->url); eh = DONAU_curl_easy_get_ (gkh->url); if (NULL == eh) { @@ -614,10 +542,6 @@ DONAU_get_keys ( // curl_easy_setopt (eh, // CURLOPT_HEADERFUNCTION, // &header_cb)); -// GNUNET_assert (CURLE_OK == -// curl_easy_setopt (eh, -// CURLOPT_HEADERDATA, -// gkh)); gkh->job = GNUNET_CURL_job_add_with_ct_json (ctx, eh, &keys_completed_cb, @@ -635,7 +559,7 @@ DONAU_get_keys_cancel ( GNUNET_CURL_job_cancel (gkh->job); gkh->job = NULL; } - //DONAU_keys_decref (gkh->prev_keys); + // DONAU_keys_decref (gkh->prev_keys); GNUNET_free (gkh->donau_url); GNUNET_free (gkh->url); GNUNET_free (gkh); @@ -840,6 +764,7 @@ add_grp (void *cls, } +// FIXME json_t * DONAU_keys_to_json (const struct DONAU_Keys *kd) { @@ -857,8 +782,10 @@ DONAU_keys_to_json (const struct DONAU_Keys *kd) signkey = GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("key", &sk->key), - GNUNET_JSON_pack_uint64 ("year", - sk->year)); + GNUNET_JSON_pack_timestamp ("stamp_start", + sk->valid_from), + GNUNET_JSON_pack_timestamp ("stamp_expire", + sk->expire_sign)); GNUNET_assert (NULL != signkey); GNUNET_assert (0 == json_array_append_new (signkeys, diff --git a/src/testing/test_donau_api.c b/src/testing/test_donau_api.c @@ -91,11 +91,11 @@ run (void *cls, TALER_TESTING_cmd_charities_get ("get-charities", &bearer, MHD_HTTP_OK), - TALER_TESTING_cmd_issue_receipts ("issue-receipts", - "post-charity", - 2024, - 3, // number of budi key pairs - MHD_HTTP_CREATED), +// TALER_TESTING_cmd_issue_receipts ("issue-receipts", +// "post-charity", +// 2024, +// 3, // number of budi key pairs +// MHD_HTTP_CREATED), TALER_TESTING_cmd_charity_delete ("delete-charity", "post-charity", // cmd trait reference &bearer, diff --git a/src/testing/testing_api_cmd_get_donau.c b/src/testing/testing_api_cmd_get_donau.c @@ -75,36 +75,35 @@ cert_cb (void *cls, struct DONAU_Keys *keys) { struct GetDonauState *ges = cls; - // const struct DONAU_HttpResponse *hr = &kr->hr; + const struct DONAU_HttpResponse *hr = &kr->hr; struct TALER_TESTING_Interpreter *is = ges->is; ges->donau = NULL; ges->keys = keys; -// switch (hr->http_status) -// { -// case MHD_HTTP_OK: -// if (ges->wait_for_keys) -// { -// ges->wait_for_keys = false; -// TALER_TESTING_interpreter_next (is); -// return; -// } -// return; -// default: -// GNUNET_break (0); -// GNUNET_log (GNUNET_ERROR_TYPE_WARNING, -// "/keys responded with HTTP status %u\n", -// hr->http_status); -// if (ges->wait_for_keys) -// { -// ges->wait_for_keys = false; -// TALER_TESTING_interpreter_fail (is); -// return; -// } -// return; -// } - - TALER_TESTING_interpreter_next (is); // to delete... only temporary + switch (hr->http_status) + { + case MHD_HTTP_OK: + if (ges->wait_for_keys) + { + ges->wait_for_keys = false; + TALER_TESTING_interpreter_next (is); + return; + } + return; + default: + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "/keys responded with HTTP status %u\n", + hr->http_status); + if (ges->wait_for_keys) + { + ges->wait_for_keys = false; + TALER_TESTING_interpreter_fail (is); + return; + } + return; + } + return; } @@ -132,19 +131,19 @@ get_donau_run (void *cls, } ges->is = is; - // ges->donau - // = DONAU_get_keys (TALER_TESTING_interpreter_get_context (is), - // ges->donau_url, - // &cert_cb, - // ges); - // if (NULL == ges->donau) - // { - // GNUNET_break (0); - // TALER_TESTING_interpreter_fail (is); - // return; - // } - // if (! ges->wait_for_keys) - TALER_TESTING_interpreter_next (is); + ges->donau + = DONAU_get_keys (TALER_TESTING_interpreter_get_context (is), + ges->donau_url, + &cert_cb, + ges); + if (NULL == ges->donau) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (! ges->wait_for_keys) + TALER_TESTING_interpreter_next (is); } @@ -192,6 +191,7 @@ get_donau_traits (void *cls, struct TALER_TESTING_Trait traits[] = { TALER_TESTING_make_trait_donau_url (ges->donau_url), + TALER_TESTING_make_trait_donau_keys (ges->keys), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_issue_receipts.c b/src/testing/testing_api_cmd_issue_receipts.c @@ -161,6 +161,7 @@ status_run (void *cls, { struct GNUNET_CRYPTO_RsaBlindedMessage *rp; struct DONAU_BlindedUniqueDonationIdentifier *bp; + // &ss->bkps[cnt].h_donation_unit_pub.hash = bp = &ss->bkps[cnt].blinded_udi; bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); bp->blinded_message->cipher = GNUNET_CRYPTO_BSA_RSA;