diff options
author | Matyja Lukas Adam <lukas.matyja@students.bfh.ch> | 2024-04-27 00:47:42 +0200 |
---|---|---|
committer | Matyja Lukas Adam <lukas.matyja@students.bfh.ch> | 2024-04-27 00:47:42 +0200 |
commit | 9a4fa301b12fe6c21fa45e691c84379506b8002c (patch) | |
tree | 87b9dd5a9448e0a0a8db4d1f2b18bfaf2f5d2a4b | |
parent | 7899ba706aee4ae7e51ff9f832306d2358c1b37f (diff) | |
download | donau-9a4fa301b12fe6c21fa45e691c84379506b8002c.tar.gz donau-9a4fa301b12fe6c21fa45e691c84379506b8002c.tar.bz2 donau-9a4fa301b12fe6c21fa45e691c84379506b8002c.zip |
[testing] work on issue receipts
-rw-r--r-- | src/donau/donau-httpd_batch-issue.c | 9 | ||||
-rw-r--r-- | src/donaudb/0002-donau_receipts_issued.sql | 2 | ||||
-rw-r--r-- | src/donaudb/donau_do_insert_issued_receipts.sql | 6 | ||||
-rw-r--r-- | src/donaudb/pg_insert_issued_receipt.c | 6 | ||||
-rw-r--r-- | src/include/donau_json_lib.h | 12 | ||||
-rw-r--r-- | src/include/donau_service.h | 10 | ||||
-rw-r--r-- | src/json/donau_json.c | 125 | ||||
-rw-r--r-- | src/lib/donau_api_batch_issue_receipts.c | 109 | ||||
-rw-r--r-- | src/pq/pq_query_helper.c | 7 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_issue_receipts.c | 8 | ||||
-rw-r--r-- | src/util/donau_crypto.c | 12 |
11 files changed, 266 insertions, 40 deletions
diff --git a/src/donau/donau-httpd_batch-issue.c b/src/donau/donau-httpd_batch-issue.c index e9d095e..968a818 100644 --- a/src/donau/donau-httpd_batch-issue.c +++ b/src/donau/donau-httpd_batch-issue.c @@ -84,7 +84,7 @@ signatures_to_JSON (const size_t num_sig, { for (size_t i = 0; i < num_sig; i++) { - struct DONAU_BlindedDonationUnitSignature*signature = &signatures[i]; + struct DONAU_BlindedDonationUnitSignature *signature = &signatures[i]; GNUNET_assert ( 0 == json_array_append ( j_signatures, @@ -316,7 +316,6 @@ start: &receipts_sum, &dk->value)); } - // struct TALER_Amount new_receipts_to_date; /* sign budis and send the signatures back */ struct DONAU_BlindedDonationUnitSignature du_sigs[num_bkps]; @@ -377,9 +376,11 @@ start: signatures_to_JSON (num_bkps, du_sigs, blind_signatures); return TALER_MHD_REPLY_JSON_PACK ( rc->connection, - MHD_HTTP_OK, + MHD_HTTP_CREATED, GNUNET_JSON_pack_array_steal ("blind_signatures", - blind_signatures)); + blind_signatures), + TALER_JSON_pack_amount("issued_amount", + &receipts_sum)); } diff --git a/src/donaudb/0002-donau_receipts_issued.sql b/src/donaudb/0002-donau_receipts_issued.sql index 0904ab5..f79c8cf 100644 --- a/src/donaudb/0002-donau_receipts_issued.sql +++ b/src/donaudb/0002-donau_receipts_issued.sql @@ -16,7 +16,7 @@ CREATE TABLE receipts_issued (receipt_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE - ,blinded_sig BYTEA[] + ,blinded_sig BYTEA[] NOT nULL ,charity_id BIGINT NOT NULL REFERENCES charities (charity_id) ON DELETE CASCADE ,receipt_hash BYTEA PRIMARY KEY CHECK (LENGTH(receipt_hash)=64) ,amount taler_amount NOT NULL diff --git a/src/donaudb/donau_do_insert_issued_receipts.sql b/src/donaudb/donau_do_insert_issued_receipts.sql index 6018fd8..4354161 100644 --- a/src/donaudb/donau_do_insert_issued_receipts.sql +++ b/src/donaudb/donau_do_insert_issued_receipts.sql @@ -16,7 +16,7 @@ CREATE OR REPLACE FUNCTION do_insert_issued_receipts ( IN in_charity_id BIGINT -- charity id which made the issue receitps request - --,IN in_blinded_sig BYTEA[] -- blinded signatures + ,IN in_blinded_sig BYTEA[] -- blinded signatures ,IN in_receipt_hash BYTEA -- hash over all budi key pairs (primary key) ,IN in_amount taler_amount -- total amount of the requested receipts ,OUT out_smaller_than_max_per_year BOOLEAN @@ -54,8 +54,8 @@ BEGIN UPDATE charities SET receipts_to_date=new_receipts_to_date WHERE charity_id=in_charity_id; - INSERT INTO receipts_issued (/*blinded_sig,*/ charity_id, receipt_hash, amount) - VALUES (/*in_blinded_sig,*/ in_charity_id, in_receipt_hash, in_amount); + INSERT INTO receipts_issued (blinded_sig, charity_id, receipt_hash, amount) + VALUES (in_blinded_sig, in_charity_id, in_receipt_hash, in_amount); ELSE out_smaller_than_max_per_year=FALSE; END IF; diff --git a/src/donaudb/pg_insert_issued_receipt.c b/src/donaudb/pg_insert_issued_receipt.c index 919c508..d758015 100644 --- a/src/donaudb/pg_insert_issued_receipt.c +++ b/src/donaudb/pg_insert_issued_receipt.c @@ -49,8 +49,8 @@ DH_PG_insert_issued_receipt ( struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&charity_id), - // DONAU_PQ_query_param_array_blinded_donation_unit_sig (num_blinded_sig, - // signatures, pc->conn), + DONAU_PQ_query_param_array_blinded_donation_unit_sig (num_blinded_sig, + signatures, pc->conn), GNUNET_PQ_query_param_auto_from_type (&h_receipt->hash), TALER_PQ_query_param_amount (pc->conn, amount_receipts_request), @@ -64,7 +64,7 @@ DH_PG_insert_issued_receipt ( "SELECT " " out_smaller_than_max_per_year AS smaller_than_max_per_year" " FROM do_insert_issued_receipts" - "($1,$2,$3);"); + "($1,$2,$3,$4);"); qs = GNUNET_PQ_eval_prepared_singleton_select (pc->conn, "insert_issued_receipts_request", diff --git a/src/include/donau_json_lib.h b/src/include/donau_json_lib.h index efadfa5..1f243e4 100644 --- a/src/include/donau_json_lib.h +++ b/src/include/donau_json_lib.h @@ -72,6 +72,18 @@ DONAU_JSON_spec_blinded_donation_identifier ( /** + * Generate line in parser specification for donation unit signature. + * + * @param field name of the field + * @param[out] sig the signature to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +DONAU_JSON_spec_blinded_donation_unit_sig (const char *field, + struct DONAU_BlindedDonationUnitSignature *sig); + + +/** * Generate packer instruction for a JSON field of type * unsigned integer. * diff --git a/src/include/donau_service.h b/src/include/donau_service.h index 213d84f..7701f30 100644 --- a/src/include/donau_service.h +++ b/src/include/donau_service.h @@ -470,17 +470,16 @@ struct DONAU_BatchIssueResponse struct { - uint32_t num_donau_sigs; - /** * Blind signature provided by the donau */ - const struct TALER_BlindedDonationUnitSignature *donau_sigs; + struct DONAU_BlindedDonationUnitSignature *donau_sigs; /** - * total amount over all donation receipts of a year specified by the request. + * total issued amount over all donation receipts of a donation specified + * by the request (confirmation). */ - const struct TALER_Amount total_amount; + struct TALER_Amount issued_amount; } ok; @@ -535,7 +534,6 @@ DONAU_charity_issue_receipt ( struct GNUNET_CURL_Context *ctx, const char *url, const struct DONAU_CharityPrivateKeyP *charity_priv, - const struct DONAU_CharityPublicKeyP *charity_pub, const uint64_t charity_id, const uint64_t year, const size_t num_bkp, diff --git a/src/json/donau_json.c b/src/json/donau_json.c index 90fd6dd..629e005 100644 --- a/src/json/donau_json.c +++ b/src/json/donau_json.c @@ -366,6 +366,131 @@ DONAU_JSON_spec_blinded_donation_identifier (const char *field, return ret; } +/** + * Parse given JSON object to blinded donation unit signature. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_blinded_donation_unit_sig (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct DONAU_BlindedDonationUnitSignature *du_sig = spec->ptr; + struct GNUNET_CRYPTO_BlindedSignature *blinded_sig; + const char *cipher; + struct GNUNET_JSON_Specification dspec[] = { + GNUNET_JSON_spec_string ("cipher", + &cipher), + GNUNET_JSON_spec_end () + }; + const char *emsg; + unsigned int eline; + + (void) cls; + if (GNUNET_OK != + GNUNET_JSON_parse (root, + dspec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + blinded_sig->cipher = string_to_cipher (cipher); + blinded_sig->rc = 1; + switch (blinded_sig->cipher) + { + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + { + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_rsa_signature ( + "blinded_rsa_signature", + &blinded_sig->details.blinded_rsa_signature), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (root, + ispec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + GNUNET_free (blinded_sig); + return GNUNET_SYSERR; + } + du_sig->blinded_sig = blinded_sig; + return GNUNET_OK; + } + case GNUNET_CRYPTO_BSA_CS: + { + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_uint32 ("b", + &blinded_sig->details.blinded_cs_answer.b), + GNUNET_JSON_spec_fixed_auto ("s", + &blinded_sig->details.blinded_cs_answer. + s_scalar), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (root, + ispec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + GNUNET_free (blinded_sig); + return GNUNET_SYSERR; + } + du_sig->blinded_sig = blinded_sig; + return GNUNET_OK; + } + } + GNUNET_break_op (0); + GNUNET_free (blinded_sig); + return GNUNET_SYSERR; +} + + +/** + * Cleanup data left from parsing donation unit public key. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_blinded_donation_unit_sig (void *cls, + struct GNUNET_JSON_Specification *spec) +{ + struct DONAU_BlindedDonationUnitSignature *du_sig = spec->ptr; + + (void) cls; + DONAU_blinded_donation_unit_sig_free (du_sig); +} + + +struct GNUNET_JSON_Specification +DONAU_JSON_spec_blinded_donation_unit_sig (const char *field, + struct DONAU_BlindedDonationUnitSignature *sig) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_blinded_donation_unit_sig, + .cleaner = &clean_blinded_donation_unit_sig, + .field = field, + .ptr = sig + }; + + sig->blinded_sig = NULL; + return ret; +} struct GNUNET_JSON_PackSpec DONAU_JSON_pack_blinded_donation_unit_sig ( diff --git a/src/lib/donau_api_batch_issue_receipts.c b/src/lib/donau_api_batch_issue_receipts.c index 0f3eaf0..4ab9a52 100644 --- a/src/lib/donau_api_batch_issue_receipts.c +++ b/src/lib/donau_api_batch_issue_receipts.c @@ -73,6 +73,82 @@ struct DONAU_BatchIssueReceiptHandle }; + +/** + * Decode the JSON in @a resp_obj from the /batch-issue/$CHARITY_ID response + * and store the data in the @a biresp. + * + * @param[in] resp_obj JSON object to parse + * @param[in] birh contains the callback function + * @param[out] biresp where to store the results we decoded + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + * (malformed JSON) + */ +static enum GNUNET_GenericReturnValue +handle_batch_issue_ok (const json_t *resp_obj, + struct DONAU_BatchIssueReceiptHandle *birh, + struct DONAU_BatchIssueResponse *biresp) +{ + struct TALER_Amount issued_amount = biresp->details.ok.issued_amount; + + if (!json_is_object(resp_obj)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + const json_t *j_blind_signatures; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount_any ("issued_amount", + &issued_amount), + GNUNET_JSON_spec_array_const ("blind_signatures", + &j_blind_signatures), + GNUNET_JSON_spec_end () + }; + if (GNUNET_OK != + GNUNET_JSON_parse (resp_obj, + spec, + NULL, + NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + const unsigned long long num_du_sigs + = json_array_size (j_blind_signatures); + if (0 != num_du_sigs) + { + struct DONAU_BlindedDonationUnitSignature du_sigs[num_du_sigs]; + unsigned int index; + json_t *du_sig_obj; + json_array_foreach (j_blind_signatures, + index, + du_sig_obj) + { + struct GNUNET_JSON_Specification spec[] = { + DONAU_JSON_spec_blinded_donation_unit_sig ("blinded_signature", + &du_sigs[index]), + GNUNET_JSON_spec_end () + }; + if (GNUNET_OK != + GNUNET_JSON_parse (du_sig_obj, + spec, + NULL, + NULL)) + { + GNUNET_break_op (0); + for (size_t i = 0; i<index; i++) + DONAU_blinded_donation_unit_sig_free (&du_sigs[i]); + return GNUNET_SYSERR; + } + } + } + birh->cb (birh->cb_cls, + biresp); + birh->cb = NULL; + return GNUNET_OK; +} + + /** * Transform issue receipt request into JSON. * @@ -137,15 +213,25 @@ handle_batch_issue_finished (void *cls, switch (response_code) { case MHD_HTTP_CREATED: + if (GNUNET_OK != + handle_batch_issue_ok (j, + birh, + &biresp)) + { + biresp.hr.http_status = 0; + biresp.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + } break; case MHD_HTTP_NO_CONTENT: biresp.hr.ec = TALER_JSON_get_error_code (j); biresp.hr.hint = TALER_JSON_get_error_hint (j); break; + //invalid charity signature case MHD_HTTP_FORBIDDEN: biresp.hr.ec = TALER_JSON_get_error_code (j); biresp.hr.hint = TALER_JSON_get_error_hint (j); break; + //one or more donation units are not known to the Donau case MHD_HTTP_NOT_FOUND: biresp.hr.ec = TALER_JSON_get_error_code (j); biresp.hr.hint = TALER_JSON_get_error_hint (j); @@ -154,6 +240,16 @@ handle_batch_issue_finished (void *cls, biresp.hr.ec = TALER_JSON_get_error_code (j); biresp.hr.hint = TALER_JSON_get_error_hint (j); break; + //Donation limit is not sufficent + case MHD_HTTP_CONFLICT: + biresp.hr.ec = TALER_JSON_get_error_code (j); + biresp.hr.hint = TALER_JSON_get_error_hint (j); + break; + // donation unit key is no longer valid + case MHD_HTTP_GONE: + biresp.hr.ec = TALER_JSON_get_error_code (j); + biresp.hr.hint = TALER_JSON_get_error_hint (j); + break; default: /* unexpected response code */ GNUNET_break_op (0); @@ -181,7 +277,6 @@ DONAU_charity_issue_receipt ( struct GNUNET_CURL_Context *ctx, const char *url, const struct DONAU_CharityPrivateKeyP *charity_priv, - const struct DONAU_CharityPublicKeyP *charity_pub, const uint64_t charity_id, const uint64_t year, const size_t num_bkp, @@ -197,18 +292,8 @@ DONAU_charity_issue_receipt ( // make signature over budi-key-pair DONAU_charity_bkp_sign (num_bkp, bkp, charity_priv, &birh->charity_sig); - /* FIXME temporary test */ - if (GNUNET_OK != - DONAU_charity_bkp_verify (num_bkp, bkp, - charity_pub, - &birh->charity_sig)) - { - GNUNET_break_op (0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "signature or verification function(s) not ok\n"); - } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "signature and verification functions ok\n"); + "Made charity signature\n"); TALER_LOG_DEBUG ("Connecting to the donau (%s)\n", url); birh->url = GNUNET_strdup (url); diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 865db08..3803750 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -361,9 +361,7 @@ qconv_array ( len = sizeof (bs->details.blinded_cs_answer); break; default: - // FIXME (set to zero) - GNUNET_assert (1); - len = 0; + GNUNET_assert (0); break; } @@ -509,8 +507,7 @@ qconv_array ( sz); break; default: - // FIXME (set to zero) - GNUNET_assert (1); + GNUNET_assert (0); } // break; // } diff --git a/src/testing/testing_api_cmd_issue_receipts.c b/src/testing/testing_api_cmd_issue_receipts.c index f0a6703..c442c0e 100644 --- a/src/testing/testing_api_cmd_issue_receipts.c +++ b/src/testing/testing_api_cmd_issue_receipts.c @@ -99,7 +99,7 @@ issue_receipts_status_cb (void *cls, { struct StatusState *ss = cls; - // TODO: use the public donation unit keysZZZZZ from the DONAU to verify the signatures + // TODO: use the public donation unit keys from the DONAU to verify the signatures ss->birh = NULL; if (ss->expected_response_code != biresp->hr.http_status) @@ -136,7 +136,6 @@ status_run (void *cls, ss->is = is; /* Get charity id and the charity private key from trait */ - const struct DONAU_CharityPublicKeyP *charity_pub; { const struct TALER_TESTING_Command *charity_post_cmd; const unsigned long long *charity_id; @@ -150,9 +149,7 @@ status_run (void *cls, if (GNUNET_OK != TALER_TESTING_get_trait_charity_id (charity_post_cmd, &charity_id) || GNUNET_OK != TALER_TESTING_get_trait_charity_priv (charity_post_cmd, - &charity_priv) || - GNUNET_OK != TALER_TESTING_get_trait_charity_pub (charity_post_cmd, - &charity_pub)) + &charity_priv)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (is); @@ -208,7 +205,6 @@ status_run (void *cls, TALER_TESTING_interpreter_get_context (is), TALER_TESTING_get_donau_url (is), &ss->charity_priv, - charity_pub, ss->charity_id, ss->year, ss->num_bkp, diff --git a/src/util/donau_crypto.c b/src/util/donau_crypto.c index 5eedc52..fd12c41 100644 --- a/src/util/donau_crypto.c +++ b/src/util/donau_crypto.c @@ -97,6 +97,18 @@ DONAU_donation_unit_pub_free ( void +DONAU_blinded_donation_unit_sig_free ( + struct DONAU_BlindedDonationUnitSignature *du_sig) +{ + if (NULL != du_sig->blinded_sig) + { + GNUNET_CRYPTO_blinded_sig_decref (du_sig->blinded_sig); + du_sig->blinded_sig = NULL; + } +} + + +void DONAU_donation_unit_pub_hash ( const struct DONAU_DonationUnitPublicKey *donation_unit_pub, struct DONAU_DonationUnitHashP *donation_unit_hash |