summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatyja Lukas Adam <lukas.matyja@students.bfh.ch>2024-04-27 00:47:42 +0200
committerMatyja Lukas Adam <lukas.matyja@students.bfh.ch>2024-04-27 00:47:42 +0200
commit9a4fa301b12fe6c21fa45e691c84379506b8002c (patch)
tree87b9dd5a9448e0a0a8db4d1f2b18bfaf2f5d2a4b
parent7899ba706aee4ae7e51ff9f832306d2358c1b37f (diff)
downloaddonau-9a4fa301b12fe6c21fa45e691c84379506b8002c.tar.gz
donau-9a4fa301b12fe6c21fa45e691c84379506b8002c.tar.bz2
donau-9a4fa301b12fe6c21fa45e691c84379506b8002c.zip
[testing] work on issue receipts
-rw-r--r--src/donau/donau-httpd_batch-issue.c9
-rw-r--r--src/donaudb/0002-donau_receipts_issued.sql2
-rw-r--r--src/donaudb/donau_do_insert_issued_receipts.sql6
-rw-r--r--src/donaudb/pg_insert_issued_receipt.c6
-rw-r--r--src/include/donau_json_lib.h12
-rw-r--r--src/include/donau_service.h10
-rw-r--r--src/json/donau_json.c125
-rw-r--r--src/lib/donau_api_batch_issue_receipts.c109
-rw-r--r--src/pq/pq_query_helper.c7
-rw-r--r--src/testing/testing_api_cmd_issue_receipts.c8
-rw-r--r--src/util/donau_crypto.c12
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