merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit b63af4a1ddb829714189b34f56d0582f4a9ee54f
parent ce731ccc4d9bfae7178f6f993757940de4ac022d
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Mon, 14 Apr 2025 18:40:49 +0200

homework for Bohdan

Diffstat:
Msrc/include/taler_merchant_service.h | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/testing/test_merchant_api.c | 63+++++++++++++++++++++++++++++++++------------------------------
Msrc/testing/testing_api_cmd_pay_order.c | 409+++++++++++++++++++++++++++++++++++++++++--------------------------------------
3 files changed, 382 insertions(+), 227 deletions(-)

diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h @@ -3566,6 +3566,143 @@ TALER_MERCHANT_order_pay ( TALER_MERCHANT_OrderPayCallback pay_cb, void *pay_cb_cls); +/* application *before* including this header should do: */ +#define TALER_MERCHANT_ORDER_PAY_CALLBACK_CLOSURE_TYPE struct PayState + + +#ifndef TALER_MERCHANT_ORDER_PAY_CALLBACK_CLOSURE_TYPE +#define TALER_MERCHANT_ORDER_PAY_CALLBACK_CLOSURE_TYPE void +#endif + +struct TALER_MERCHANT_OrderPayHandle * +TALER_MERCHANT_order_pay_create ( + struct GNUNET_CURL_Context *ctx, + TALER_MERCHANT_OrderPayCallback pay_cb, + TALER_MERCHANT_ORDER_PAY_CALLBACK_CLOSURE_TYPE *pay_cb_cls) +{ + ph->body = json_object (); // json_t * +} + + +struct TALER_MERCHANT_OrderPayOption +{ + enum TALER_MERCHANT_OrderPayOptionType + { + TALER_MERCHANT_OrderPayOptionType_END = 0, + TALER_MERCHANT_OrderPayOptionType_MERCHANT_URL, + TALER_MERCHANT_OrderPayOptionType_SESSION_ID, + TALER_MERCHANT_OrderPayOptionType_H_CONTRACT, + TALER_MERCHANT_OrderPayOptionType_XXX, + } ot; + + union + { + const char *merchant_url; + const char *session_id; + const struct TALER_PrivateContractHashP *h_contract; + int choice_index; + struct TALER_Amount amount; + struct TALER_Amount max_fee; + struct TALER_MerchantPublicKeyP merchant_pub; + struct GNUNET_TIME_Timestamp timestamp; + struct GNUNET_TIME_Timestamp refund_deadline; + struct GNUNET_TIME_Timestamp pay_deadline; + struct TALER_MerchantWireHashP h_wire; + const char *order_id; + struct + { + unsigned int num_coins; + const struct TALER_MERCHANT_PayCoin *coins; + } coins; + struct + { + unsigned int num_tokens; + const struct TALER_MERCHANT_UseToken *tokens; + } input_tokens; + struct + { + unsigned int num_output_tokens, + const struct TALER_MERCHANT_OutputToken *output_tokens; + } output_tokens; + } details; +}; + +enum TALER_MERCHANT_OrderPayOptionErrorCode +TALER_MERCHANT_order_pay_set_options ( + struct TALER_MERCHANT_OrderPayHandle *ph, + struct TALER_MERCHANT_OrderPayOption options[], + size_t max_options); + +{ + for (i-- not 0 - terminateor && i < max_options; i++) + switch (options[i].type) + case ... + GNUNET_assert (0 == + json_object_set_new (ph->body, + "field", + json_string ("foo"))); + return OK; + case ... + GNUNET_assert (0 == + json_object_set_new (ph->body, + "field", + json_bool (true))); + + return OK; + case ... + GNUNET_assert (0 == + json_object_set_new (ph->body, + "wire_hash", + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto (NULL, + &options[i + ].details. + h_wire)))) + return OK; +} + +} +return ERROR_UNKNOWN_OPTION; +} + +#define TALER_MERCHANT_ORDER_PAY_OPTION_TERMINATE() \ + (const struct TALER_MERCHANT_OrderPayOption) { \ + .ot = TALER_MERCHANT_OrderPayOptionType_END \ + } + + +#define TALER_MERCHANT_ORDER_PAY_OPTION_SESSION_ID(session_id) \ + (const struct TALER_MERCHANT_OrderPayOption) { \ + .ot = TALER_MERCHANT_OrderPayOptionType_SESSION_ID, \ + .details.session_id = session_id \ + } + +#define TALER_MERCHANT_ORDER_PAY_SET_OPTIONS(ph,...) \ + MHD_NOWARN_COMPOUND_LITERALS_ \ + TALER_MERCHANT_order_pay_set_options ( \ + daemon, \ + ((const struct TALER_MERCHANT_OrderPayHandle[]) \ + {__VA_ARGS__, TALER_MERCHANT_ORDER_PAY_OPTION_TERMINATE ()}), \ + MHD_OPTIONS_ARRAY_MAX_SIZE) \ + +enum TALER_MERCHANT_OrderPayOptionErrorCode +TALER_MERCHANT_order_pay_start (struct TALER_MERCHANT_OrderPayHandle *ph); + +#if APP +{ + struct TALER_MERCHANT_OrderPayHandle *ph; + + ph = TALER_MERCHANT_order_pay_create (struct GNUNET_CURL_Context *ctx, + TALER_MERCHANT_OrderPayCallback pay_cb, + pay_cb_cls); + + GNUNET_assert (OK == + TALER_MERCHANT_ORDER_PAY_SET_OPTIONS ( + ph, + TALER_MERCHANT_ORDER_PAY_OPTION_SESSION_ID ("session"))); + pay_start (ph); +} +#endif /** * Cancel a POST /orders/$ID/pay request. Note that if you cancel a request diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c @@ -1826,11 +1826,13 @@ run (void *cls, }; struct TALER_TESTING_Command donau[] = { - //FIXME: PREPARE THE DONAU to work with us - //1. Add the charity to the donau - TALER_TESTING_cmd_get_donau ("get-donau", + // FIXME: PREPARE THE DONAU to work with us + // 1. Add the charity to the donau + TALER_TESTING_cmd_set_var ( + "donau", + TALER_TESTING_cmd_get_donau ("get-donau", cred.cfg, - true), + true)), TALER_TESTING_cmd_charity_post ("post-charity", "example", "example.com", @@ -1839,17 +1841,18 @@ run (void *cls, 2025, // current year &bearer, MHD_HTTP_CREATED), - TALER_TESTING_cmd_merchant_post_donau_instance( + TALER_TESTING_cmd_merchant_post_donau_instance ( "post-donau-instance", merchant_url, MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_sleep("In this time donaukeyupdate must fetch the keys from the donau", 1), - TALER_TESTING_cmd_merchant_get_donau_instances( + TALER_TESTING_cmd_sleep ( + "In this time donaukeyupdate must fetch the keys from the donau", 1), + TALER_TESTING_cmd_merchant_get_donau_instances ( "get-donau-instance", merchant_url, 1, MHD_HTTP_OK), - //FIXME_2: Add check for the donau charity instance info being corrected + // FIXME_2: Add check for the donau charity instance info being corrected // with info from the donau TALER_TESTING_cmd_merchant_post_orders_donau ( "create-donau-order", @@ -1861,15 +1864,15 @@ run (void *cls, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:10.0"), - //FIXME: Most probably we need to merge the functionality of the - //TALER_TESTING_cmd_merchant_pay_order and TALER_TESTING_cmd_issue_receipts from DONAU - //Most probably we only need to copy the part of creation of the BUDIs - TALER_TESTING_cmd_merchant_delete_donau_instance( + // FIXME: Most probably we need to merge the functionality of the + // TALER_TESTING_cmd_merchant_pay_order and TALER_TESTING_cmd_issue_receipts from DONAU + // Most probably we only need to copy the part of creation of the BUDIs + TALER_TESTING_cmd_merchant_delete_donau_instance ( "delete-donau-instance", merchant_url, 1, MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_get_donau_instances( + TALER_TESTING_cmd_merchant_get_donau_instances ( "get-donau-instances-after-delete", merchant_url, 0, @@ -1885,21 +1888,21 @@ run (void *cls, cred.cfg, "exchange-account-exchange"), #ifdef HAVE_DONAU_DONAU_SERVICE_H - TALER_TESTING_cmd_system_start ( - "start-taler", - config_file, - "-emaDZ", - "-u", "exchange-account-exchange", - "-r", "merchant-exchange-test", - NULL), + TALER_TESTING_cmd_system_start ( + "start-taler", + config_file, + "-emaDZ", + "-u", "exchange-account-exchange", + "-r", "merchant-exchange-test", + NULL), #else - TALER_TESTING_cmd_system_start ( - "start-taler", - config_file, - "-ema", - "-u", "exchange-account-exchange", - "-r", "merchant-exchange-test", - NULL), + TALER_TESTING_cmd_system_start ( + "start-taler", + config_file, + "-ema", + "-u", "exchange-account-exchange", + "-r", "merchant-exchange-test", + NULL), #endif TALER_TESTING_cmd_get_exchange ( "get-exchange", @@ -2214,9 +2217,9 @@ run (void *cls, TALER_TESTING_cmd_batch ("tokens", tokens), #ifdef HAVE_DONAU_DONAU_SERVICE_H - //TALER_TESTING_cmd_sleep("dream", 30), - TALER_TESTING_cmd_batch ("donau", - donau), + // TALER_TESTING_cmd_sleep("dream", 30), + TALER_TESTING_cmd_batch ("donau", + donau), #endif /** * End the suite. diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c @@ -139,10 +139,11 @@ struct MerchantDonauPayData }; -//FIXME: One thing left is to receive the BUDIsKP +// FIXME: One thing left is to receive the BUDIsKP static enum GNUNET_GenericReturnValue -prepare_donau_data(struct TALER_TESTING_Interpreter *is, - struct MerchantDonauPayData *ss){ +prepare_donau_data (struct TALER_TESTING_Interpreter *is, + struct MerchantDonauPayData *ss) +{ /* Get charity id and the charity private key from trait */ { @@ -150,7 +151,6 @@ prepare_donau_data(struct TALER_TESTING_Interpreter *is, const unsigned long long *charity_id; const struct DONAU_CharityPrivateKeyP *charity_priv; - charity_post_cmd = TALER_TESTING_interpreter_lookup_command (is, ss-> charity_reference); @@ -172,11 +172,12 @@ prepare_donau_data(struct TALER_TESTING_Interpreter *is, const struct TALER_TESTING_Command *keys_cmd; struct DONAU_Keys *keys; - keys_cmd = TALER_TESTING_interpreter_lookup_command (is, - "get-donau"); + keys_cmd = TALER_TESTING_interpreter_get_command (is, + "donau"); if (GNUNET_OK != - TALER_TESTING_get_trait_donau_keys (keys_cmd, &keys)) + TALER_TESTING_get_trait_donau_keys (keys_cmd, + &keys)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -186,18 +187,22 @@ prepare_donau_data(struct TALER_TESTING_Interpreter *is, /* Get BUDIsKP */ { - //FIXME: Define me pleeeease - ss->bkps = - GNUNET_new_array (ss->num_bkps, struct - DONAU_BlindedUniqueDonorIdentifierKeyPair); - ss->blinding_secrets = - GNUNET_new_array (ss->num_bkps, union GNUNET_CRYPTO_BlindingSecretP); - ss->receipts = - GNUNET_new_array (ss->num_bkps, struct DONAU_DonationReceipt); - ss->alg_values = - GNUNET_new_array (ss->num_bkps, const struct DONAU_BatchIssueValues *); - ss->h_udis = - GNUNET_new_array (ss->num_bkps, struct DONAU_UniqueDonorIdentifierHashP); + // FIXME: Define me pleeeease + ss->bkps + = GNUNET_new_array (ss->num_bkps, + struct DONAU_BlindedUniqueDonorIdentifierKeyPair); + ss->blinding_secrets + = GNUNET_new_array (ss->num_bkps, + union GNUNET_CRYPTO_BlindingSecretP); + ss->receipts + = GNUNET_new_array (ss->num_bkps, + struct DONAU_DonationReceipt); + ss->alg_values + = GNUNET_new_array (ss->num_bkps, + const struct DONAU_BatchIssueValues *); + ss->h_udis + = GNUNET_new_array (ss->num_bkps, + struct DONAU_UniqueDonorIdentifierHashP); for (size_t cnt = 0; cnt < ss->num_bkps; cnt++) @@ -213,6 +218,7 @@ prepare_donau_data(struct TALER_TESTING_Interpreter *is, struct DONAU_BlindedUniqueDonorIdentifier *blinded_udi = &ss->bkps[cnt].blinded_udi; struct DONAU_UniqueDonorIdentifierHashP *udi_hash = &ss->h_udis[cnt]; + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, &ps, sizeof (ps)); @@ -239,7 +245,7 @@ prepare_donau_data(struct TALER_TESTING_Interpreter *is, ss->alg_values[cnt] = alg_values; break; case GNUNET_CRYPTO_BSA_CS: - //FUCK THIS CS CASE + // FUCK THIS CS CASE // struct CSR_Data *csr_data = GNUNET_new (struct CSR_Data); // TALER_cs_withdraw_nonce_derive ( // FIXME: write new method // (struct TALER_PlanchetMasterSecretP *) &ps, @@ -264,8 +270,8 @@ prepare_donau_data(struct TALER_TESTING_Interpreter *is, GNUNET_break (0); } } - //What to do with the next thing from donau - //if (0 == ss->cs_pending) + // What to do with the next thing from donau + // if (0 == ss->cs_pending) // phase_two (ss); } @@ -372,12 +378,12 @@ struct PayState */ int choice_index; - #ifdef HAVE_DONAU_DONAU_SERVICE_H +#ifdef HAVE_DONAU_DONAU_SERVICE_H /** * Donau data, if required. */ struct MerchantDonauPayData donau_data; - #endif /* HAVE_DONAU_DONAU_SERVICE_H */ +#endif /* HAVE_DONAU_DONAU_SERVICE_H */ }; @@ -1021,129 +1027,131 @@ pay_run (void *cls, if (0 == strcmp ("tax-receipt", kind)) { - const json_t *donau_urls; - - // For test, we care only about the presence of it - struct GNUNET_JSON_Specification donauspec[] = { - GNUNET_JSON_spec_array_const ("donau_urls", - &donau_urls), - - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (output, - donauspec, - &ierror_name, - &ierror_line)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Parser failed on %s:%u for input `%s'\n", - ierror_name, - ierror_line, - json_dumps (output, - JSON_INDENT (2))); - TALER_TESTING_FAIL (is); - } + const json_t *donau_urls; + + // For test, we care only about the presence of it + struct GNUNET_JSON_Specification donauspec[] = { + GNUNET_JSON_spec_array_const ("donau_urls", + &donau_urls), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (output, + donauspec, + &ierror_name, + &ierror_line)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Parser failed on %s:%u for input `%s'\n", + ierror_name, + ierror_line, + json_dumps (output, + JSON_INDENT (2))); + TALER_TESTING_FAIL (is); + } - #ifdef HAVE_DONAU_DONAU_SERVICE_H - // FIXME: I suspect we want to call function here that will get the stuff for the donau_data - - #else /* HAVE_DONAU_DONAU_SERVICE_H */ - //Theoretically we have thought about paying without donau_url being selected, so could proceed... - // or maybe not - #endif /* HAVE_DONAU_DONAU_SERVICE_H */ +#ifdef HAVE_DONAU_DONAU_SERVICE_H + // FIXME: I suspect we want to call function here that will get the stuff for the donau_data +#else /* HAVE_DONAU_DONAU_SERVICE_H */ + // Theoretically we have thought about paying without donau_url being selected, so could proceed... + // or maybe not +#endif /* HAVE_DONAU_DONAU_SERVICE_H */ } if (0 == strcmp ("token", kind)) { - struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_string ("token_family_slug", - &slug), - GNUNET_JSON_spec_uint32 ("key_index", - &key_index), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint32 ("count", - &count), - NULL), - GNUNET_JSON_spec_end () - }; + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_string ("token_family_slug", + &slug), + GNUNET_JSON_spec_uint32 ("key_index", + &key_index), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint32 ("count", + &count), + NULL), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (output, + ispec, + &ierror_name, + &ierror_line)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Parser failed on %s:%u for input `%s'\n", + ierror_name, + ierror_line, + json_dumps (output, + JSON_INDENT (2))); + TALER_TESTING_FAIL (is); + } + + if (0 != strcmp ("token", kind)) + { + continue; + } + + GNUNET_array_grow (ps->issued_tokens, + ps->num_issued_tokens, + ps->num_issued_tokens + count); + + for (unsigned int k = 0; k < count; k++) + { + struct TALER_MERCHANT_PrivateTokenDetails *details = + &ps->issued_tokens[ps->num_issued_tokens - count + k]; if (GNUNET_OK != - GNUNET_JSON_parse (output, - ispec, - &ierror_name, - &ierror_line)) + find_token_public_key (token_families, + slug, + key_index, + &details->issue_pub)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Parser failed on %s:%u for input `%s'\n", - ierror_name, - ierror_line, - json_dumps (output, - JSON_INDENT (2))); TALER_TESTING_FAIL (is); } - if (0 != strcmp ("token", kind)) + /* Only RSA is supported for now. */ + GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == + details->issue_pub.public_key->cipher); + + TALER_token_blind_input_copy (&details->blinding_inputs, + TALER_token_blind_input_rsa_singleton () + ); + /* FIXME: Where to get details->blinding_inputs from? */ + TALER_token_use_setup_random (&details->master); + TALER_token_use_setup_priv (&details->master, + &details->blinding_inputs, + &details->token_priv); + TALER_token_use_blinding_secret_create (&details->master, + &details->blinding_inputs, + &details->blinding_secret) + ; + GNUNET_CRYPTO_eddsa_key_get_public (&details->token_priv. + private_key + , + &details->token_pub.public_key + ); + GNUNET_CRYPTO_hash (&details->token_pub.public_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), + &details->h_token_pub.hash); + details->envelope.blinded_pub = + GNUNET_CRYPTO_message_blind_to_sign + ( + details->issue_pub.public_key, + &details->blinding_secret, + NULL, /* FIXME: Add session nonce to support CS tokens */ + &details->h_token_pub.hash, + sizeof (details->h_token_pub.hash), + details->blinding_inputs.blinding_inputs); + + if (NULL == details->envelope.blinded_pub) { - continue; - } - - GNUNET_array_grow (ps->issued_tokens, - ps->num_issued_tokens, - ps->num_issued_tokens + count); - - for (unsigned int k = 0; k < count; k++) - { - struct TALER_MERCHANT_PrivateTokenDetails *details = - &ps->issued_tokens[ps->num_issued_tokens - count + k]; - - if (GNUNET_OK != - find_token_public_key (token_families, - slug, - key_index, - &details->issue_pub)) - { - TALER_TESTING_FAIL (is); - } - - /* Only RSA is supported for now. */ - GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == - details->issue_pub.public_key->cipher); - - TALER_token_blind_input_copy (&details->blinding_inputs, - TALER_token_blind_input_rsa_singleton () - ); - /* FIXME: Where to get details->blinding_inputs from? */ - TALER_token_use_setup_random (&details->master); - TALER_token_use_setup_priv (&details->master, - &details->blinding_inputs, - &details->token_priv); - TALER_token_use_blinding_secret_create (&details->master, - &details->blinding_inputs, - &details->blinding_secret); - GNUNET_CRYPTO_eddsa_key_get_public (&details->token_priv.private_key - , - &details->token_pub.public_key); - GNUNET_CRYPTO_hash (&details->token_pub.public_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), - &details->h_token_pub.hash); - details->envelope.blinded_pub = GNUNET_CRYPTO_message_blind_to_sign - ( - details->issue_pub.public_key, - &details->blinding_secret, - NULL, /* FIXME: Add session nonce to support CS tokens */ - &details->h_token_pub.hash, - sizeof (details->h_token_pub.hash), - details->blinding_inputs.blinding_inputs); - - if (NULL == details->envelope.blinded_pub) - { - GNUNET_break (0); - TALER_TESTING_FAIL (is); - } + GNUNET_break (0); + TALER_TESTING_FAIL (is); } + } } } } @@ -1403,77 +1411,84 @@ TALER_TESTING_cmd_merchant_pay_order_choices (const char *label, #ifdef HAVE_DONAU_DONAU_SERVICE_H - struct TALER_TESTING_Command - TALER_TESTING_cmd_merchant_pay_order_donau (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *proposal_reference, - const char *coin_reference, - const char *amount_with_fee, - const char *amount_without_fee, - const char *session_id, - int choice_index, - const char *charity_reference, - const uint64_t year, - const char *donor_tax_id, - const char *salt) - { - struct PayState *ps; +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_pay_order_donau (const char *label, + const char *merchant_url, + unsigned int http_status, + const char *proposal_reference, + const char *coin_reference, + const char *amount_with_fee, + const char *amount_without_fee, + const char *session_id, + int choice_index, + const char *charity_reference, + const uint64_t year, + const char *donor_tax_id, + const char *salt) +{ + struct TALER_TESTING_Command cmd; + struct PayState *ps; + struct MerchantDonauPayData *mdpd; - struct MerchantDonauPayData *mdpd; +#if NO_LEAK_NO_COPY_NO_DUPLICATION + cmd = TALER_TESTING_cmd_merchant_pay_order_choices (...); + ps = cmd.cls; + mdpd = &pd.donau_data; +#else + mdpd = GNUNET_new (struct MerchantDonauPayData); +#endif - mdpd = GNUNET_new (struct MerchantDonauPayData); - mdpd->year = year; - mdpd->num_bkps = 3; - mdpd->charity_reference = charity_reference; + mdpd->year = year; + mdpd->num_bkps = 3; + mdpd->charity_reference = charity_reference; - /* Here we generate the h_donor_tax_id*/ - { - unsigned char hash[512 / 8]; - crypto_hash_sha512_state state; - crypto_hash_sha512_init (&state); - - unsigned int tax_length; - for (tax_length = 0; donor_tax_id[tax_length]!= '\0'; ++tax_length) - ; - unsigned int salt_length; - for (salt_length = 0; salt[salt_length]!= '\0'; ++salt_length) - ; - - crypto_hash_sha512_update (&state, (const unsigned char*) donor_tax_id, - tax_length); - crypto_hash_sha512_update (&state, (const unsigned char*) salt, salt_length); - - crypto_hash_sha512_final (&state, hash); - GNUNET_memcpy (mdpd->h_donor_tax_id.hash, hash, sizeof(hash)); - } - /* End of hash generation */ - - ps = GNUNET_new (struct PayState); - ps->http_status = http_status; - ps->proposal_reference = proposal_reference; - ps->coin_reference = coin_reference; - ps->merchant_url = merchant_url; - ps->amount_with_fee = amount_with_fee; - ps->amount_without_fee = amount_without_fee; - ps->session_id = session_id; - ps->token_reference = NULL; - ps->choice_index = choice_index; - ps->donau_data = *mdpd; /* Adding prefilled data, for future processing*/ + /* Here we generate the h_donor_tax_id*/ + { + crypto_hash_sha512_state state; + size_t tax_length = strlen (donor_tax_id); + unsigned int salt_length; + for (salt_length = 0; salt[salt_length]!= '\0'; ++salt_length) + ; + + crypto_hash_sha512_init (&state); + crypto_hash_sha512_update (&state, + (const unsigned char*) donor_tax_id, + tax_length); + crypto_hash_sha512_update (&state, + (const unsigned char*) salt, + salt_length); + GNUNET_static_assert (sizeof (mdpd->h_donor_tax_id.hash) == 512 / 8); + crypto_hash_sha512_final (&state, + mdpd->h_donor_tax_id.hash); + } + /* End of hash generation */ - { - struct TALER_TESTING_Command cmd = { - .cls = ps, - .label = label, - .run = &pay_run, - .cleanup = &pay_cleanup, - .traits = &pay_traits - }; + ps = GNUNET_new (struct PayState); + ps->http_status = http_status; + ps->proposal_reference = proposal_reference; + ps->coin_reference = coin_reference; + ps->merchant_url = merchant_url; + ps->amount_with_fee = amount_with_fee; + ps->amount_without_fee = amount_without_fee; + ps->session_id = session_id; + ps->token_reference = NULL; + ps->choice_index = choice_index; + ps->donau_data = *mdpd; /* Adding prefilled data, for future processing*/ - return cmd; - } + { + struct TALER_TESTING_Command cmd = { + .cls = ps, + .label = label, + .run = &pay_run, + .cleanup = &pay_cleanup, + .traits = &pay_traits + }; + + return cmd; } +} + #endif /* HAVE_DONAU_DONAU_SERVICE_H */