commit 576ac8fbce87da94ba68a9ef4c3d61cbef32277e
parent 96297315ed832391025a0d9bb43c6d03bca93d1e
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date: Wed, 10 Apr 2024 00:58:08 +0200
Merge branch 'master' of ssh://git.taler.net/donau
Diffstat:
9 files changed, 900 insertions(+), 446 deletions(-)
diff --git a/doc/flows/poster/poster.pptx b/doc/flows/poster/poster.pptx
Binary files differ.
diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c
@@ -1340,11 +1340,8 @@ DH_keys_donation_unit_by_hash (
{
if (NULL == conn)
return NULL;
- // FIXME: server error or not found?
- // *mret = TEH_RESPONSE_reply_unknown_denom_pub_hash (conn,
- // h_denom_pub);
*mret = TALER_MHD_reply_with_error (conn,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
+ MHD_HTTP_NOT_FOUND,
TALER_EC_DONAU_GENERIC_KEYS_MISSING,
NULL);
return NULL;
@@ -1352,5 +1349,21 @@ DH_keys_donation_unit_by_hash (
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
@@ -164,4 +164,21 @@ void
DH_keys_finished (void);
+/**
+ * Create blinded signature.
+ *
+ * @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
+ */
+enum GNUNET_GenericReturnValue
+DONAU_donation_unit_sign_blinded (struct
+ DONAU_BlindedDonationUnitSignature *du_sig,
+ const struct
+ DONAU_DonationUnitHashP *h_pub,
+ const struct
+ DONAU_BlindedUniqueDonationIdentifier *budi);
+
+
#endif
diff --git a/src/donau/donau-httpd_post-batch-issue.c b/src/donau/donau-httpd_post-batch-issue.c
@@ -234,6 +234,7 @@ DH_handler_issue_receipts_post (struct DH_RequestContext *rc,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"got charity from db!\n");
/* verify charity signature */
+ // FIXME
if (GNUNET_OK !=
DONAU_charity_budi_key_pair_verify (num_bkp, irc.bkp,
&charity_meta.charity_pub,
@@ -289,11 +290,11 @@ start:
NULL);
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "request have not been made yet (first time)!\n");
+ "request has not been made yet (first time)!\n");
break; // it's the first request from the charity, we can proceed
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "request have been made already!\n");
+ "request has been made already!\n");
signatures_to_JSON (num_bkp, check_receipts_meta.blinded_sig,
blind_signatures);
return TALER_MHD_REPLY_JSON_PACK (
@@ -308,25 +309,28 @@ start:
{
MHD_RESULT mret;
struct DH_DonationUnitKey *dk;
- dk = DH_keys_donation_unit_by_hash (&irc.bkp[i].h_donation_unit_pub,
+ // 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);
- if (NULL == dk || 0 >= TALER_amount_add (&receipts_sum, &receipts_sum,
- &dk->value))
- return TALER_MHD_reply_with_error (rc->connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "budikeypairs");
+ &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));
}
- struct TALER_Amount new_receipts_to_date = {0};
+ 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 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,
MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,// TODO: other EC
- "budikeypairs");
+ TALER_EC_DONAU_EXCEEDING_DONATION_LIMIT,
+ NULL);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"calculated the new receipts to date amount\n");
@@ -335,12 +339,12 @@ start:
{
for (size_t i = 0; i < num_bkp; i++)
{
- // TODO: get donation unit private key
- const struct DONAU_DonationUnitPrivateKey du_priv;
+ // FIXME private key is missing
+ //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 == TALER_donation_unit_sign_blinded (du_sig, &du_priv, &
+ if (GNUNET_SYSERR == DONAU_donation_unit_sign_blinded (du_sig, &irc.bkp[i].h_donation_unit_pub, &
budi))
{
GNUNET_break (0);
diff --git a/src/include/donau_crypto_lib.h b/src/include/donau_crypto_lib.h
@@ -378,22 +378,6 @@ void
DONAU_blinded_donation_unit_sig_free (
struct DONAU_BlindedDonationUnitSignature *donation_unit_sig);
-/**
- * Create blinded signature.
- *
- * @param[out] du_sig where to write the signature
- * @param du_priv private key to use for signing
- * @param budi the unique identifier already blinded
- * @return #GNUNET_OK on success
- */
-enum GNUNET_GenericReturnValue
-TALER_donation_unit_sign_blinded (struct
- DONAU_BlindedDonationUnitSignature *du_sig,
- const struct
- DONAU_DonationUnitPrivateKey *du_priv,
- const struct
- DONAU_BlindedUniqueDonationIdentifier *budi);
-
/**
* Verify signature made with a donation unit public key
diff --git a/src/lib/donau_api_batch_issue_receipts.c b/src/lib/donau_api_batch_issue_receipts.c
@@ -207,7 +207,7 @@ DONAU_charity_issue_receipt (
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"signature or verification function(s) not ok\n");
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"signature and verification functions ok\n");
TALER_LOG_DEBUG ("Connecting to the donau (%s)\n",
url);
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
@@ -121,111 +121,563 @@ DONAU_PQ_query_param_donation_unit_pub (
return res;
}
+/**
+ * Closure for the array result specifications. Contains type information
+ * for the generic parser extract_array_generic and out-pointers for the results.
+ */
+struct ArrayResultCls
+{
+ /**
+ * Oid of the expected type, must match the oid in the header of the PQResult struct
+ */
+ Oid oid;
+
+ /**
+ * Target type
+ */
+ //enum TALER_PQ_ArrayType typ;
+
+ /**
+ * If not 0, defines the expected size of each entry
+ */
+ size_t same_size;
+
+ /**
+ * Out-pointer to write the number of elements in the array
+ */
+ size_t *num;
+
+ /**
+ * Out-pointer. If @a typ is TALER_PQ_array_of_byte and @a same_size is 0,
+ * allocate and put the array of @a num sizes here. NULL otherwise
+ */
+ size_t **sizes;
+
+ /**
+ * DB_connection, needed for OID-lookup for composite types
+ */
+ const struct GNUNET_PQ_Context *db;
+
+ /**
+ * Currency information for amount composites
+ */
+ char currency[TALER_CURRENCY_LEN];
+};
-// FIXME:
-// /**
-// * Function to generate a typ specific query parameter and corresponding closure
-// *
-// * @param num Number of elements in @a elements
-// * @param continuous If true, @a elements is an continuous array of data
-// * @param elements Array of @a num elements, either continuous or pointers
-// * @param sizes Array of @a num sizes, one per element, may be NULL
-// * @param same_size If not 0, all elements in @a elements have this size
-// * @param typ Supported internal type of each element in @a elements
-// * @param oid Oid of the type to be used in Postgres
-// * @param[in,out] db our database handle for looking up OIDs
-// * @return Query parameter
-// */
-// static struct GNUNET_PQ_QueryParam
-// query_param_array_generic (
-// unsigned int num,
-// bool continuous,
-// const void *elements,
-// const size_t *sizes,
-// size_t same_size,
-// enum TALER_PQ_ArrayType typ,
-// Oid oid,
-// struct GNUNET_PQ_Context *db)
-// {
-// struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls);
-
-// meta->typ = typ;
-// meta->oid = oid;
-// meta->sizes = sizes;
-// meta->same_size = same_size;
-// meta->continuous = continuous;
-// meta->db = db;
-
-// {
-// struct GNUNET_PQ_QueryParam res = {
-// .conv = qconv_array,
-// .conv_cls = meta,
-// .conv_cls_cleanup = qconv_array_cls_cleanup,
-// .data = elements,
-// .size = num,
-// .num_params = 1,
-// };
-
-// return res;
-// }
-// }
-
-// struct GNUNET_PQ_QueryParam
-// DONAU_PQ_query_param_array_blinded_donation_unit_sig (
-// size_t num,
-// const struct DONAU_BlindedDonationUnitSignature *du_sigs,
-// struct GNUNET_PQ_Context *db)
-// {
-// Oid oid;
-
-// GNUNET_assert (GNUNET_OK ==
-// GNUNET_PQ_get_oid_by_name (db,
-// "bytea",
-// &oid));
-// return query_param_array_generic (num,
-// true,
-// du_sigs,
-// NULL,
-// 0,
-// TALER_PQ_array_of_blinded_denom_sig,
-// oid,
-// NULL);
-// }
-
-// /**
-// * Extract data from a Postgres database @a result as array of a specific type
-// * from row @a row. The type information and optionally additional
-// * out-parameters are given in @a cls which is of type array_result_cls.
-// *
-// * @param cls closure of type array_result_cls
-// * @param result where to extract data from
-// * @param row row to extract data from
-// * @param fname name (or prefix) of the fields to extract from
-// * @param[in,out] dst_size where to store size of result, may be NULL
-// * @param[out] dst where to store the result
-// * @return
-// * #GNUNET_YES if all results could be extracted
-// * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
-// */
-// static enum GNUNET_GenericReturnValue
-// extract_array_generic (
-// void *cls,
-// PGresult *result,
-// int row,
-// const char *fname,
-// size_t *dst_size,
-// void *dst)
-// {
-// const struct ArrayResultCls *info = cls;
-// int data_sz;
-// char *data;
-// void *out = NULL;
-// struct GNUNET_PQ_ArrayHeader_P header;
-// int col_num;
-
-// GNUNET_assert (NULL != dst);
-// *((void **) dst) = NULL;
/**
+ * Closure for the array type handlers.
+ *
+ * May contain sizes information for the data, given (and handled) by the
+ * caller.
+ */
+struct qconv_array_cls
+{
+ /**
+ * If not null, contains the array of sizes (the size of the array is the
+ * .size field in the ambient GNUNET_PQ_QueryParam struct). We do not free
+ * this memory.
+ *
+ * If not null, this value has precedence over @a sizes, which MUST be NULL */
+ const size_t *sizes;
+
+ /**
+ * If @a size and @a c_sizes are NULL, this field defines the same size
+ * for each element in the array.
+ */
+ size_t same_size;
+
+ /**
+ * If true, the array parameter to the data pointer to the qconv_array is a
+ * continuous byte array of data, either with @a same_size each or sizes
+ * provided bytes by @a sizes;
+ */
+ bool continuous;
+
+ /**
+ * Type of the array elements
+ */
+ //enum TALER_PQ_ArrayType typ;
+
+ /**
+ * Oid of the array elements
+ */
+ Oid oid;
+
+ /**
+ * db context, needed for OID-lookup of basis-types
+ */
+ struct GNUNET_PQ_Context *db;
+};
+
+/**
+ * Function called to convert input argument into SQL parameters for arrays
+ *
+ * Note: the format for the encoding of arrays for libpq is not very well
+ * documented. We peeked into various sources (postgresql and libpqtypes) for
+ * guidance.
+ *
+ * @param cls Closure of type struct qconv_array_cls*
+ * @param data Pointer to first element in the array
+ * @param data_len Number of _elements_ in array @a data (if applicable)
+ * @param[out] param_values SQL data to set
+ * @param[out] param_lengths SQL length data to set
+ * @param[out] param_formats SQL format data to set
+ * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
+ * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
+ * @param scratch_length number of entries left in @a scratch
+ * @return -1 on error, number of offsets used in @a scratch otherwise
+ */
+static int
+qconv_array (
+ void *cls,
+ const void *data,
+ size_t data_len,
+ void *param_values[],
+ int param_lengths[],
+ int param_formats[],
+ unsigned int param_length,
+ void *scratch[],
+ unsigned int scratch_length)
+{
+ struct qconv_array_cls *meta = cls;
+ size_t num = data_len;
+ size_t total_size;
+ const size_t *sizes;
+ bool same_sized;
+ void *elements = NULL;
+ bool noerror = true;
+ /* needed to capture the encoded rsa signatures */
+ void **buffers = NULL;
+ size_t *buffer_lengths = NULL;
+
+ (void) (param_length);
+ (void) (scratch_length);
+
+ GNUNET_assert (NULL != meta);
+ GNUNET_assert (num < INT_MAX);
+
+ sizes = meta->sizes;
+ same_sized = (0 != meta->same_size);
+
+#define RETURN_UNLESS(cond) \
+ do { \
+ if (! (cond)) \
+ { \
+ GNUNET_break ((cond)); \
+ noerror = false; \
+ goto DONE; \
+ } \
+ } while (0)
+
+ /* Calculate sizes and check bounds */
+ {
+ /* num * length-field */
+ size_t x = sizeof(uint32_t);
+ size_t y = x * num;
+ RETURN_UNLESS ((0 == num) || (y / num == x));
+
+ /* size of header */
+ total_size = x = sizeof(struct GNUNET_PQ_ArrayHeader_P);
+ total_size += y;
+ RETURN_UNLESS (total_size >= x);
+
+ /* sizes of elements */
+ if (same_sized)
+ {
+ x = num * meta->same_size;
+ RETURN_UNLESS ((0 == num) || (x / num == meta->same_size));
+
+ y = total_size;
+ total_size += x;
+ RETURN_UNLESS (total_size >= y);
+ }
+ else /* sizes are different per element */
+ {
+ // switch (meta->typ)
+ // {
+ // case TALER_PQ_array_of_amount_currency:
+ // {
+ // const struct TALER_Amount *amounts = data;
+ // Oid oid_v;
+ // Oid oid_f;
+ // Oid oid_c;
+
+ // buffer_lengths = GNUNET_new_array (num, size_t);
+ // /* hoist out of loop? */
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "int8",
+ // &oid_v));
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "int4",
+ // &oid_f));
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "varchar",
+ // &oid_c));
+ // for (size_t i = 0; i<num; i++)
+ // {
+ // struct TALER_PQ_AmountCurrencyP am;
+ // size_t len;
+
+ // len = TALER_PQ_make_taler_pq_amount_currency_ (
+ // &amounts[i],
+ // oid_v,
+ // oid_f,
+ // oid_c,
+ // &am);
+ // buffer_lengths[i] = len;
+ // y = total_size;
+ // total_size += len;
+ // RETURN_UNLESS (total_size >= y);
+ // }
+ // sizes = buffer_lengths;
+ // break;
+ // }
+ // case TALER_PQ_array_of_blinded_denom_sig:
+ // {
+ const struct DONAU_BlindedDonationUnitSignature *du_sigs = data;
+ size_t len;
+
+ buffers = GNUNET_new_array (num, void *);
+ buffer_lengths = GNUNET_new_array (num, size_t);
+
+ for (size_t i = 0; i<num; i++)
+ {
+ const struct GNUNET_CRYPTO_BlindedSignature *bs =
+ du_sigs[i].blinded_sig;
+
+ switch (bs->cipher)
+ {
+ case GNUNET_CRYPTO_BSA_RSA:
+ len = GNUNET_CRYPTO_rsa_signature_encode (
+ bs->details.blinded_rsa_signature,
+ &buffers[i]);
+ RETURN_UNLESS (len != 0);
+ break;
+ case GNUNET_CRYPTO_BSA_CS:
+ len = sizeof (bs->details.blinded_cs_answer);
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+
+ /* for the cipher and marker */
+ len += 2 * sizeof(uint32_t);
+ buffer_lengths[i] = len;
+
+ y = total_size;
+ total_size += len;
+ RETURN_UNLESS (total_size >= y);
+ }
+ sizes = buffer_lengths;
+ // break;
+ // }
+ // default:
+ // GNUNET_assert (0);
+ // }
+ }
+
+ RETURN_UNLESS (INT_MAX > total_size);
+ RETURN_UNLESS (0 != total_size);
+
+ elements = GNUNET_malloc (total_size);
+ }
+
+ /* Write data */
+ {
+ char *out = elements;
+ struct GNUNET_PQ_ArrayHeader_P h = {
+ .ndim = htonl (1), /* We only support one-dimensional arrays */
+ .has_null = htonl (0), /* We do not support NULL entries in arrays */
+ .lbound = htonl (1), /* Default start index value */
+ .dim = htonl (num),
+ .oid = htonl (meta->oid),
+ };
+
+ /* Write header */
+ GNUNET_memcpy (out,
+ &h,
+ sizeof(h));
+ out += sizeof(h);
+
+ /* Write elements */
+ for (size_t i = 0; i < num; i++)
+ {
+ size_t sz = same_sized ? meta->same_size : sizes[i];
+
+ *(uint32_t *) out = htonl (sz);
+ out += sizeof(uint32_t);
+ // switch (meta->typ)
+ // {
+ // case TALER_PQ_array_of_amount:
+ // {
+ // const struct TALER_Amount *amounts = data;
+ // Oid oid_v;
+ // Oid oid_f;
+
+ // /* hoist out of loop? */
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "int8",
+ // &oid_v));
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "int4",
+ // &oid_f));
+ // {
+ // struct TALER_PQ_AmountP am
+ // = TALER_PQ_make_taler_pq_amount_ (
+ // &amounts[i],
+ // oid_v,
+ // oid_f);
+
+ // GNUNET_memcpy (out,
+ // &am,
+ // sizeof(am));
+ // }
+ // break;
+ // }
+ // case TALER_PQ_array_of_amount_currency:
+ // {
+ // const struct TALER_Amount *amounts = data;
+ // Oid oid_v;
+ // Oid oid_f;
+ // Oid oid_c;
+
+ // /* hoist out of loop? */
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "int8",
+ // &oid_v));
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "int4",
+ // &oid_f));
+ // GNUNET_assert (GNUNET_OK ==
+ // GNUNET_PQ_get_oid_by_name (meta->db,
+ // "varchar",
+ // &oid_c));
+ // {
+ // struct TALER_PQ_AmountCurrencyP am;
+ // size_t len;
+
+ // len = TALER_PQ_make_taler_pq_amount_currency_ (
+ // &amounts[i],
+ // oid_v,
+ // oid_f,
+ // oid_c,
+ // &am);
+ // GNUNET_memcpy (out,
+ // &am,
+ // len);
+ // }
+ // break;
+ // }
+ // case TALER_PQ_array_of_blinded_denom_sig:
+ // {
+ const struct DONAU_BlindedDonationUnitSignature *denom_sigs = data;
+ const struct GNUNET_CRYPTO_BlindedSignature *bs =
+ denom_sigs[i].blinded_sig;
+ uint32_t be[2];
+
+ be[0] = htonl ((uint32_t) bs->cipher);
+ be[1] = htonl (0x01); /* magic margker: blinded */
+ GNUNET_memcpy (out,
+ &be,
+ sizeof(be));
+ out += sizeof(be);
+ sz -= sizeof(be);
+
+ switch (bs->cipher)
+ {
+ case GNUNET_CRYPTO_BSA_RSA:
+ /* For RSA, 'same_sized' must have been false */
+ GNUNET_assert (NULL != buffers);
+ GNUNET_memcpy (out,
+ buffers[i],
+ sz);
+ break;
+ case GNUNET_CRYPTO_BSA_CS:
+ GNUNET_memcpy (out,
+ &bs->details.blinded_cs_answer,
+ sz);
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+ // break;
+ // }
+ // case TALER_PQ_array_of_blinded_coin_hash:
+ // {
+ // const struct TALER_BlindedCoinHashP *coin_hs = data;
+
+ // GNUNET_memcpy (out,
+ // &coin_hs[i],
+ // sizeof(struct TALER_BlindedCoinHashP));
+
+ // break;
+ // }
+ // case TALER_PQ_array_of_denom_hash:
+ // {
+ // const struct TALER_DenominationHashP *denom_hs = data;
+
+ // GNUNET_memcpy (out,
+ // &denom_hs[i],
+ // sizeof(struct TALER_DenominationHashP));
+ // break;
+ // }
+ // case TALER_PQ_array_of_hash_code:
+ // {
+ // const struct GNUNET_HashCode *hashes = data;
+
+ // GNUNET_memcpy (out,
+ // &hashes[i],
+ // sizeof(struct GNUNET_HashCode));
+ // break;
+ // }
+ // default:
+ // {
+ // GNUNET_assert (0);
+ // break;
+ // }
+ // }
+ out += sz;
+ }
+ }
+ param_values[0] = elements;
+ param_lengths[0] = total_size;
+ param_formats[0] = 1;
+ scratch[0] = elements;
+
+DONE:
+ if (NULL != buffers)
+ {
+ for (size_t i = 0; i<num; i++)
+ GNUNET_free (buffers[i]);
+ GNUNET_free (buffers);
+ }
+ GNUNET_free (buffer_lengths);
+ if (noerror)
+ return 1;
+ return -1;
+}
+
+
+/**
+ * Callback to cleanup a qconv_array_cls to be used during
+ * GNUNET_PQ_cleanup_query_params_closures
+ */
+static void
+qconv_array_cls_cleanup (void *cls)
+{
+ GNUNET_free (cls);
+}
+
+/**
+ * Function to generate a typ specific query parameter and corresponding closure
+ *
+ * @param num Number of elements in @a elements
+ * @param continuous If true, @a elements is an continuous array of data
+ * @param elements Array of @a num elements, either continuous or pointers
+ * @param sizes Array of @a num sizes, one per element, may be NULL
+ * @param same_size If not 0, all elements in @a elements have this size
+ * @param typ Supported internal type of each element in @a elements
+ * @param oid Oid of the type to be used in Postgres
+ * @param[in,out] db our database handle for looking up OIDs
+ * @return Query parameter
+ */
+static struct GNUNET_PQ_QueryParam
+query_param_array_generic (
+ unsigned int num,
+ bool continuous,
+ const void *elements,
+ const size_t *sizes,
+ size_t same_size,
+ //enum TALER_PQ_ArrayType typ,
+ Oid oid,
+ struct GNUNET_PQ_Context *db)
+{
+ struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls);
+
+ //meta->typ = typ;
+ meta->oid = oid;
+ meta->sizes = sizes;
+ meta->same_size = same_size;
+ meta->continuous = continuous;
+ meta->db = db;
+
+ {
+ struct GNUNET_PQ_QueryParam res = {
+ .conv = qconv_array,
+ .conv_cls = meta,
+ .conv_cls_cleanup = qconv_array_cls_cleanup,
+ .data = elements,
+ .size = num,
+ .num_params = 1,
+ };
+
+ return res;
+ }
+}
+
+struct GNUNET_PQ_QueryParam
+DONAU_PQ_query_param_array_blinded_donation_unit_sig (
+ size_t num,
+ const struct DONAU_BlindedDonationUnitSignature *du_sigs,
+ struct GNUNET_PQ_Context *db)
+{
+ Oid oid;
+
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_PQ_get_oid_by_name (db,
+ "bytea",
+ &oid));
+ return query_param_array_generic (num,
+ true,
+ du_sigs,
+ NULL,
+ 0,
+ //TALER_PQ_array_of_blinded_du_sig,
+ oid,
+ NULL);
+}
+
+/**
+ * Extract data from a Postgres database @a result as array of a specific type
+ * from row @a row. The type information and optionally additional
+ * out-parameters are given in @a cls which is of type array_result_cls.
+ *
+ * @param cls closure of type array_result_cls
+ * @param result where to extract data from
+ * @param row row to extract data from
+ * @param fname name (or prefix) of the fields to extract from
+ * @param[in,out] dst_size where to store size of result, may be NULL
+ * @param[out] dst where to store the result
+ * @return
+ * #GNUNET_YES if all results could be extracted
+ * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
+ */
+static enum GNUNET_GenericReturnValue
+extract_array_generic (
+ void *cls,
+ PGresult *result,
+ int row,
+ const char *fname,
+ size_t *dst_size,
+ void *dst)
+{
+ const struct ArrayResultCls *info = cls;
+ int data_sz;
+ char *data;
+ //void *out = NULL;
+ struct GNUNET_PQ_ArrayHeader_P header;
+ int col_num;
+
+ GNUNET_assert (NULL != dst);
+ *((void **) dst) = NULL;
+
#define FAIL_IF(cond) \
do { \
if ((cond)) \
@@ -234,291 +686,291 @@ DONAU_PQ_query_param_donation_unit_pub (
goto FAIL; \
} \
} while (0)
-**/
-// col_num = PQfnumber (result, fname);
-// FAIL_IF (0 > col_num);
-
-// data_sz = PQgetlength (result, row, col_num);
-// FAIL_IF (0 > data_sz);
-// FAIL_IF (sizeof(header) > (size_t) data_sz);
-
-// data = PQgetvalue (result, row, col_num);
-// FAIL_IF (NULL == data);
-
-// {
-// struct GNUNET_PQ_ArrayHeader_P *h =
-// (struct GNUNET_PQ_ArrayHeader_P *) data;
-
-// header.ndim = ntohl (h->ndim);
-// header.has_null = ntohl (h->has_null);
-// header.oid = ntohl (h->oid);
-// header.dim = ntohl (h->dim);
-// header.lbound = ntohl (h->lbound);
-
-// FAIL_IF (1 != header.ndim);
-// FAIL_IF (INT_MAX <= header.dim);
-// FAIL_IF (0 != header.has_null);
-// FAIL_IF (1 != header.lbound);
-// FAIL_IF (info->oid != header.oid);
-// }
-
-// if (NULL != info->num)
-// *info->num = header.dim;
-
-// {
-// char *in = data + sizeof(header);
-
-// switch (info->typ)
-// {
-// case TALER_PQ_array_of_amount:
-// {
-// struct TALER_Amount *amounts;
-// if (NULL != dst_size)
-// *dst_size = sizeof(struct TALER_Amount) * (header.dim);
-
-// amounts = GNUNET_new_array (header.dim,
-// struct TALER_Amount);
-// *((void **) dst) = amounts;
-
-// for (uint32_t i = 0; i < header.dim; i++)
-// {
-// struct TALER_PQ_AmountP ap;
-// struct TALER_Amount *amount = &amounts[i];
-// uint32_t val;
-// size_t sz;
-
-// GNUNET_memcpy (&val,
-// in,
-// sizeof(val));
-// sz = ntohl (val);
-// in += sizeof(val);
-
-// /* total size for this array-entry */
-// FAIL_IF (sizeof(ap) != sz);
-
-// GNUNET_memcpy (&ap,
-// in,
-// sz);
-// FAIL_IF (2 != ntohl (ap.cnt));
-
-// amount->value = GNUNET_ntohll (ap.v);
-// amount->fraction = ntohl (ap.f);
-// GNUNET_memcpy (amount->currency,
-// info->currency,
-// TALER_CURRENCY_LEN);
-
-// in += sizeof(struct TALER_PQ_AmountP);
-// }
-// return GNUNET_OK;
-// }
-// case TALER_PQ_array_of_denom_hash:
-// if (NULL != dst_size)
-// *dst_size = sizeof(struct TALER_DenominationHashP) * (header.dim);
-// out = GNUNET_new_array (header.dim,
-// struct TALER_DenominationHashP);
-// *((void **) dst) = out;
-// for (uint32_t i = 0; i < header.dim; i++)
-// {
-// uint32_t val;
-// size_t sz;
-
-// GNUNET_memcpy (&val,
-// in,
-// sizeof(val));
-// sz = ntohl (val);
-// FAIL_IF (sz != sizeof(struct TALER_DenominationHashP));
-// in += sizeof(uint32_t);
-// *(struct TALER_DenominationHashP *) out =
-// *(struct TALER_DenominationHashP *) in;
-// in += sz;
-// out += sz;
-// }
-// return GNUNET_OK;
-
-// case TALER_PQ_array_of_hash_code:
-// if (NULL != dst_size)
-// *dst_size = sizeof(struct GNUNET_HashCode) * (header.dim);
-// out = GNUNET_new_array (header.dim,
-// struct GNUNET_HashCode);
-// *((void **) dst) = out;
-// for (uint32_t i = 0; i < header.dim; i++)
-// {
-// uint32_t val;
-// size_t sz;
-
-// GNUNET_memcpy (&val,
-// in,
-// sizeof(val));
-// sz = ntohl (val);
-// FAIL_IF (sz != sizeof(struct GNUNET_HashCode));
-// in += sizeof(uint32_t);
-// *(struct GNUNET_HashCode *) out =
-// *(struct GNUNET_HashCode *) in;
-// in += sz;
-// out += sz;
-// }
-// return GNUNET_OK;
-
-// case TALER_PQ_array_of_blinded_coin_hash:
-// if (NULL != dst_size)
-// *dst_size = sizeof(struct TALER_BlindedCoinHashP) * (header.dim);
-// out = GNUNET_new_array (header.dim,
-// struct TALER_BlindedCoinHashP);
-// *((void **) dst) = out;
-// for (uint32_t i = 0; i < header.dim; i++)
-// {
-// uint32_t val;
-// size_t sz;
-
-// GNUNET_memcpy (&val,
-// in,
-// sizeof(val));
-// sz = ntohl (val);
-// FAIL_IF (sz != sizeof(struct TALER_BlindedCoinHashP));
-// in += sizeof(uint32_t);
-// *(struct TALER_BlindedCoinHashP *) out =
-// *(struct TALER_BlindedCoinHashP *) in;
-// in += sz;
-// out += sz;
-// }
-// return GNUNET_OK;
-
-// case TALER_PQ_array_of_blinded_denom_sig:
-// {
-// struct TALER_BlindedDenominationSignature *denom_sigs;
-// if (0 == header.dim)
-// {
-// if (NULL != dst_size)
-// *dst_size = 0;
-// break;
-// }
-
-// denom_sigs = GNUNET_new_array (header.dim,
-// struct TALER_BlindedDenominationSignature);
-// *((void **) dst) = denom_sigs;
-
-// /* copy data */
-// for (uint32_t i = 0; i < header.dim; i++)
-// {
-// struct TALER_BlindedDenominationSignature *denom_sig = &denom_sigs[i];
-// struct GNUNET_CRYPTO_BlindedSignature *bs;
-// uint32_t be[2];
-// uint32_t val;
-// size_t sz;
-
-// GNUNET_memcpy (&val,
-// in,
-// sizeof(val));
-// sz = ntohl (val);
-// FAIL_IF (sizeof(be) > sz);
-
-// in += sizeof(val);
-// GNUNET_memcpy (&be,
-// in,
-// sizeof(be));
-// FAIL_IF (0x01 != ntohl (be[1])); /* magic marker: blinded */
-
-// in += sizeof(be);
-// sz -= sizeof(be);
-// bs = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature);
-// bs->cipher = ntohl (be[0]);
-// bs->rc = 1;
-// switch (bs->cipher)
-// {
-// case GNUNET_CRYPTO_BSA_RSA:
-// bs->details.blinded_rsa_signature
-// = GNUNET_CRYPTO_rsa_signature_decode (in,
-// sz);
-// if (NULL == bs->details.blinded_rsa_signature)
-// {
-// GNUNET_free (bs);
-// FAIL_IF (true);
-// }
-// break;
-// case GNUNET_CRYPTO_BSA_CS:
-// if (sizeof(bs->details.blinded_cs_answer) != sz)
-// {
-// GNUNET_free (bs);
-// FAIL_IF (true);
-// }
-// GNUNET_memcpy (&bs->details.blinded_cs_answer,
-// in,
-// sz);
-// break;
-// default:
-// GNUNET_free (bs);
-// FAIL_IF (true);
-// }
-// denom_sig->blinded_sig = bs;
-// in += sz;
-// }
-// return GNUNET_OK;
-// }
-// default:
-// FAIL_IF (true);
-// }
-// }
-// FAIL:
-// GNUNET_free (*(void **) dst);
-// return GNUNET_SYSERR;
-// #undef FAIL_IF
-// }
-
-
-// /**
-// * Cleanup of the data and closure of an array spec.
-// */
-// static void
-// array_cleanup (void *cls,
-// void *rd)
-// {
-// struct ArrayResultCls *info = cls;
-// void **dst = rd;
-
-// if ((0 == info->same_size) &&
-// (NULL != info->sizes))
-// GNUNET_free (*(info->sizes));
-
-// /* Clean up signatures, if applicable */
-// if (TALER_PQ_array_of_blinded_denom_sig == info->typ)
-// {
-// struct TALER_BlindedDenominationSignature *denom_sigs = *dst;
-// GNUNET_assert (NULL != info->num);
-// for (size_t i = 0; i < *info->num; i++)
-// GNUNET_free (denom_sigs[i].blinded_sig);
-// }
-
-// GNUNET_free (cls);
-// GNUNET_free (*dst);
-// *dst = NULL;
-// }
-
-
-// struct GNUNET_PQ_ResultSpec
-// DONAU_PQ_result_spec_array_blinded_donation_unit_sig (
-// struct GNUNET_PQ_Context *db,
-// const char *name,
-// size_t *num,
-// struct DONAU_BlindedDonationUnitSignature **du_sigs)
-// {
-// struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
-
-// info->num = num;
-// info->typ = TALER_PQ_array_of_blinded_denom_sig;
-// GNUNET_assert (GNUNET_OK ==
-// GNUNET_PQ_get_oid_by_name (db,
-// "bytea",
-// &info->oid));
-
-// struct GNUNET_PQ_ResultSpec res = {
-// .conv = extract_array_generic,
-// .cleaner = array_cleanup,
-// .dst = (void *) du_sigs,
-// .fname = name,
-// .cls = info
-// };
-// return res;
-
-// }
+
+ col_num = PQfnumber (result, fname);
+ FAIL_IF (0 > col_num);
+
+ data_sz = PQgetlength (result, row, col_num);
+ FAIL_IF (0 > data_sz);
+ FAIL_IF (sizeof(header) > (size_t) data_sz);
+
+ data = PQgetvalue (result, row, col_num);
+ FAIL_IF (NULL == data);
+
+ {
+ struct GNUNET_PQ_ArrayHeader_P *h =
+ (struct GNUNET_PQ_ArrayHeader_P *) data;
+
+ header.ndim = ntohl (h->ndim);
+ header.has_null = ntohl (h->has_null);
+ header.oid = ntohl (h->oid);
+ header.dim = ntohl (h->dim);
+ header.lbound = ntohl (h->lbound);
+
+ FAIL_IF (1 != header.ndim);
+ FAIL_IF (INT_MAX <= header.dim);
+ FAIL_IF (0 != header.has_null);
+ FAIL_IF (1 != header.lbound);
+ FAIL_IF (info->oid != header.oid);
+ }
+
+ if (NULL != info->num)
+ *info->num = header.dim;
+
+ {
+ char *in = data + sizeof(header);
+
+ // switch (info->typ)
+ // {
+ // case TALER_PQ_array_of_amount:
+ // {
+ // struct TALER_Amount *amounts;
+ // if (NULL != dst_size)
+ // *dst_size = sizeof(struct TALER_Amount) * (header.dim);
+
+ // amounts = GNUNET_new_array (header.dim,
+ // struct TALER_Amount);
+ // *((void **) dst) = amounts;
+
+ // for (uint32_t i = 0; i < header.dim; i++)
+ // {
+ // struct TALER_PQ_AmountP ap;
+ // struct TALER_Amount *amount = &amounts[i];
+ // uint32_t val;
+ // size_t sz;
+
+ // GNUNET_memcpy (&val,
+ // in,
+ // sizeof(val));
+ // sz = ntohl (val);
+ // in += sizeof(val);
+
+ // /* total size for this array-entry */
+ // FAIL_IF (sizeof(ap) != sz);
+
+ // GNUNET_memcpy (&ap,
+ // in,
+ // sz);
+ // FAIL_IF (2 != ntohl (ap.cnt));
+
+ // amount->value = GNUNET_ntohll (ap.v);
+ // amount->fraction = ntohl (ap.f);
+ // GNUNET_memcpy (amount->currency,
+ // info->currency,
+ // TALER_CURRENCY_LEN);
+
+ // in += sizeof(struct TALER_PQ_AmountP);
+ // }
+ // return GNUNET_OK;
+ // }
+ // case TALER_PQ_array_of_denom_hash:
+ // if (NULL != dst_size)
+ // *dst_size = sizeof(struct TALER_DenominationHashP) * (header.dim);
+ // out = GNUNET_new_array (header.dim,
+ // struct TALER_DenominationHashP);
+ // *((void **) dst) = out;
+ // for (uint32_t i = 0; i < header.dim; i++)
+ // {
+ // uint32_t val;
+ // size_t sz;
+
+ // GNUNET_memcpy (&val,
+ // in,
+ // sizeof(val));
+ // sz = ntohl (val);
+ // FAIL_IF (sz != sizeof(struct TALER_DenominationHashP));
+ // in += sizeof(uint32_t);
+ // *(struct TALER_DenominationHashP *) out =
+ // *(struct TALER_DenominationHashP *) in;
+ // in += sz;
+ // out += sz;
+ // }
+ // return GNUNET_OK;
+
+ // case TALER_PQ_array_of_hash_code:
+ // if (NULL != dst_size)
+ // *dst_size = sizeof(struct GNUNET_HashCode) * (header.dim);
+ // out = GNUNET_new_array (header.dim,
+ // struct GNUNET_HashCode);
+ // *((void **) dst) = out;
+ // for (uint32_t i = 0; i < header.dim; i++)
+ // {
+ // uint32_t val;
+ // size_t sz;
+
+ // GNUNET_memcpy (&val,
+ // in,
+ // sizeof(val));
+ // sz = ntohl (val);
+ // FAIL_IF (sz != sizeof(struct GNUNET_HashCode));
+ // in += sizeof(uint32_t);
+ // *(struct GNUNET_HashCode *) out =
+ // *(struct GNUNET_HashCode *) in;
+ // in += sz;
+ // out += sz;
+ // }
+ // return GNUNET_OK;
+
+ // case TALER_PQ_array_of_blinded_coin_hash:
+ // if (NULL != dst_size)
+ // *dst_size = sizeof(struct TALER_BlindedCoinHashP) * (header.dim);
+ // out = GNUNET_new_array (header.dim,
+ // struct TALER_BlindedCoinHashP);
+ // *((void **) dst) = out;
+ // for (uint32_t i = 0; i < header.dim; i++)
+ // {
+ // uint32_t val;
+ // size_t sz;
+
+ // GNUNET_memcpy (&val,
+ // in,
+ // sizeof(val));
+ // sz = ntohl (val);
+ // FAIL_IF (sz != sizeof(struct TALER_BlindedCoinHashP));
+ // in += sizeof(uint32_t);
+ // *(struct TALER_BlindedCoinHashP *) out =
+ // *(struct TALER_BlindedCoinHashP *) in;
+ // in += sz;
+ // out += sz;
+ // }
+ // return GNUNET_OK;
+
+ // case TALER_PQ_array_of_blinded_denom_sig:
+ // {
+ struct DONAU_BlindedDonationUnitSignature *du_sigs;
+ if (0 == header.dim)
+ {
+ if (NULL != dst_size)
+ *dst_size = 0;
+ goto FAIL;
+ }
+
+ du_sigs = GNUNET_new_array (header.dim,
+ struct DONAU_BlindedDonationUnitSignature);
+ *((void **) dst) = du_sigs;
+
+ /* copy data */
+ for (uint32_t i = 0; i < header.dim; i++)
+ {
+ struct DONAU_BlindedDonationUnitSignature *du_sig = &du_sigs[i];
+ struct GNUNET_CRYPTO_BlindedSignature *bs;
+ uint32_t be[2];
+ uint32_t val;
+ size_t sz;
+
+ GNUNET_memcpy (&val,
+ in,
+ sizeof(val));
+ sz = ntohl (val);
+ FAIL_IF (sizeof(be) > sz);
+
+ in += sizeof(val);
+ GNUNET_memcpy (&be,
+ in,
+ sizeof(be));
+ FAIL_IF (0x01 != ntohl (be[1])); /* magic marker: blinded */
+
+ in += sizeof(be);
+ sz -= sizeof(be);
+ bs = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature);
+ bs->cipher = ntohl (be[0]);
+ bs->rc = 1;
+ switch (bs->cipher)
+ {
+ case GNUNET_CRYPTO_BSA_RSA:
+ bs->details.blinded_rsa_signature
+ = GNUNET_CRYPTO_rsa_signature_decode (in,
+ sz);
+ if (NULL == bs->details.blinded_rsa_signature)
+ {
+ GNUNET_free (bs);
+ FAIL_IF (true);
+ }
+ break;
+ case GNUNET_CRYPTO_BSA_CS:
+ if (sizeof(bs->details.blinded_cs_answer) != sz)
+ {
+ GNUNET_free (bs);
+ FAIL_IF (true);
+ }
+ GNUNET_memcpy (&bs->details.blinded_cs_answer,
+ in,
+ sz);
+ break;
+ default:
+ GNUNET_free (bs);
+ FAIL_IF (true);
+ }
+ du_sig->blinded_sig = bs;
+ in += sz;
+ }
+ return GNUNET_OK;
+ // }
+ // default:
+ // FAIL_IF (true);
+ // }
+ }
+FAIL:
+ GNUNET_free (*(void **) dst);
+ return GNUNET_SYSERR;
+#undef FAIL_IF
+}
+
+
+/**
+ * Cleanup of the data and closure of an array spec.
+ */
+static void
+array_cleanup (void *cls,
+ void *rd)
+{
+ struct ArrayResultCls *info = cls;
+ void **dst = rd;
+
+ if ((0 == info->same_size) &&
+ (NULL != info->sizes))
+ GNUNET_free (*(info->sizes));
+
+ /* Clean up signatures, if applicable */
+ // if (TALER_PQ_array_of_blinded_denom_sig == info->typ)
+ // {
+ struct DONAU_BlindedDonationUnitSignature *du_sigs = *dst;
+ GNUNET_assert (NULL != info->num);
+ for (size_t i = 0; i < *info->num; i++)
+ GNUNET_free (du_sigs[i].blinded_sig);
+ // }
+
+ GNUNET_free (cls);
+ GNUNET_free (*dst);
+ *dst = NULL;
+}
+
+
+struct GNUNET_PQ_ResultSpec
+DONAU_PQ_result_spec_array_blinded_donation_unit_sig (
+ struct GNUNET_PQ_Context *db,
+ const char *name,
+ size_t *num,
+ struct DONAU_BlindedDonationUnitSignature **du_sigs)
+{
+ struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
+
+ info->num = num;
+ // info->typ = TALER_PQ_array_of_blinded_denom_sig;
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_PQ_get_oid_by_name (db,
+ "bytea",
+ &info->oid));
+
+ struct GNUNET_PQ_ResultSpec res = {
+ .conv = extract_array_generic,
+ .cleaner = array_cleanup,
+ .dst = (void *) du_sigs,
+ .fname = name,
+ .cls = info
+ };
+ return res;
+
+}
/* end of pq/pq_query_helper.c */
diff --git a/src/testing/testing_api_cmd_issue_receipts.c b/src/testing/testing_api_cmd_issue_receipts.c
@@ -99,6 +99,8 @@ issue_receipts_status_cb (void *cls,
{
struct StatusState *ss = cls;
+ // TODO: use the public donation unit keysZZZZZ from the DONAU to verify the signatures
+
ss->birh = NULL;
if (ss->expected_response_code != biresp->hr.http_status)
{
@@ -113,8 +115,7 @@ issue_receipts_status_cb (void *cls,
TALER_TESTING_interpreter_fail (ss->is);
return;
}
- // if (ss->expected_response_code == biresp->hr.http_status)
- // ss->charity_id = (unsigned long long) biresp->details.ok.charity_id;
+
TALER_TESTING_interpreter_next (ss->is);
}
@@ -179,15 +180,13 @@ status_run (void *cls,
ss->keys = keys;
}
- // TODO: build bkps with traits from /keys request, use the public sign key from the
- // DONAU to verify the signatures
ss->bkps
= GNUNET_new_array (ss->num_bkp,
struct DONAU_BlindedUniqueDonationIdentifierKeyPair);
for (size_t cnt = 0; cnt < ss->num_bkp; cnt++)
{
struct GNUNET_CRYPTO_RsaBlindedMessage *rp;
- struct DONAU_BlindedUniqueDonationIdentifier *bp;
+ struct DONAU_BlindedUniqueDonationIdentifier *bp = {0};
DONAU_donation_unit_pub_hash (&ss->keys->donation_unit_keys[0].key,
&ss->bkps[cnt].h_donation_unit_pub);
bp = &ss->bkps[cnt].blinded_udi;
diff --git a/src/util/donau_signatures.c b/src/util/donau_signatures.c
@@ -110,19 +110,4 @@ DONAU_donation_statement_verify (
&donau_pub->eddsa_pub);
}
-
-enum GNUNET_GenericReturnValue
-TALER_donation_unit_sign_blinded (struct DONAU_BlindedDonationUnitSignature *du_sig,
- const struct DONAU_DonationUnitPrivateKey *du_priv,
- const struct DONAU_BlindedUniqueDonationIdentifier *budi)
-{
- 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_signatures.c */