summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-10-31 17:56:56 +0100
committerChristian Grothoff <christian@grothoff.org>2021-10-31 17:56:56 +0100
commit3eae999efc0cb923aebd2bf7214c5f4093217d4f (patch)
tree9581fa718e127a79779ee1a095d4e017549f2b5e
parentde8e0907aadecf4f97c0eb8230217751f3fd44a1 (diff)
downloadexchange-3eae999efc0cb923aebd2bf7214c5f4093217d4f.tar.gz
exchange-3eae999efc0cb923aebd2bf7214c5f4093217d4f.tar.bz2
exchange-3eae999efc0cb923aebd2bf7214c5f4093217d4f.zip
distinguish between blind and non-blind denomination signatures
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c4
-rw-r--r--src/exchange/taler-exchange-httpd_keys.h2
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c19
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c14
-rw-r--r--src/exchangedb/plugin_exchangedb_common.c2
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c18
-rw-r--r--src/include/taler_crypto_lib.h64
-rw-r--r--src/include/taler_exchange_service.h2
-rw-r--r--src/include/taler_exchangedb_plugin.h6
-rw-r--r--src/include/taler_json_lib.h29
-rw-r--r--src/include/taler_pq_lib.h25
-rw-r--r--src/json/json_helper.c98
-rw-r--r--src/json/json_pack.c26
-rw-r--r--src/lib/exchange_api_refreshes_reveal.c12
-rw-r--r--src/lib/exchange_api_withdraw.c2
-rw-r--r--src/lib/exchange_api_withdraw2.c8
-rw-r--r--src/pq/pq_query_helper.c94
-rw-r--r--src/pq/pq_result_helper.c127
-rw-r--r--src/util/crypto.c16
-rw-r--r--src/util/crypto_helper_denom.c8
-rw-r--r--src/util/denom.c48
21 files changed, 550 insertions, 74 deletions
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index e18295c65..ad06b6684 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -1918,14 +1918,14 @@ TEH_keys_denomination_by_hash2 (
}
-struct TALER_DenominationSignature
+struct TALER_BlindedDenominationSignature
TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,
const void *msg,
size_t msg_size,
enum TALER_ErrorCode *ec)
{
struct TEH_KeyStateHandle *ksh;
- struct TALER_DenominationSignature none;
+ struct TALER_BlindedDenominationSignature none;
memset (&none,
0,
diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h
index db967a31b..9ad0c6a3a 100644
--- a/src/exchange/taler-exchange-httpd_keys.h
+++ b/src/exchange/taler-exchange-httpd_keys.h
@@ -171,7 +171,7 @@ TEH_keys_denomination_by_hash2 (struct TEH_KeyStateHandle *ksh,
* @return signature, the value inside the structure will be NULL on failure,
* see @a ec for details about the failure
*/
-struct TALER_DenominationSignature
+struct TALER_BlindedDenominationSignature
TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,
const void *msg,
size_t msg_size,
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index 925f7a094..4ec703136 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -55,7 +55,8 @@
static MHD_RESULT
reply_refreshes_reveal_success (struct MHD_Connection *connection,
unsigned int num_freshcoins,
- const struct TALER_DenominationSignature *sigs)
+ const struct
+ TALER_BlindedDenominationSignature *sigs)
{
json_t *list;
@@ -68,8 +69,8 @@ reply_refreshes_reveal_success (struct MHD_Connection *connection,
json_t *obj;
obj = GNUNET_JSON_PACK (
- TALER_JSON_pack_denom_sig ("ev_sig",
- &sigs[freshcoin_index]));
+ TALER_JSON_pack_blinded_denom_sig ("ev_sig",
+ &sigs[freshcoin_index]));
GNUNET_assert (0 ==
json_array_append_new (list,
obj));
@@ -123,7 +124,7 @@ struct RevealContext
/**
* Envelopes with the signatures to be returned. Initially NULL.
*/
- struct TALER_DenominationSignature *ev_sigs;
+ struct TALER_BlindedDenominationSignature *ev_sigs;
/**
* Size of the @e dks, @e rcds and @e ev_sigs arrays (if non-NULL).
@@ -187,10 +188,10 @@ check_exists_cb (void *cls,
if (NULL == rctx->ev_sigs)
{
rctx->ev_sigs = GNUNET_new_array (num_freshcoins,
- struct TALER_DenominationSignature);
+ struct TALER_BlindedDenominationSignature);
for (unsigned int i = 0; i<num_freshcoins; i++)
- TALER_denom_sig_deep_copy (&rctx->ev_sigs[i],
- &rrcs[i].coin_sig);
+ TALER_blinded_denom_sig_deep_copy (&rctx->ev_sigs[i],
+ &rrcs[i].coin_sig);
}
}
@@ -683,7 +684,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
/* sign _early_ (optimistic!) to keep out of transaction scope! */
rctx->ev_sigs = GNUNET_new_array (rctx->num_fresh_coins,
- struct TALER_DenominationSignature);
+ struct TALER_BlindedDenominationSignature);
for (unsigned int i = 0; i<rctx->num_fresh_coins; i++)
{
enum TALER_ErrorCode ec = TALER_EC_NONE;
@@ -769,7 +770,7 @@ cleanup:
if (NULL != rctx->ev_sigs)
{
for (unsigned int i = 0; i<num_fresh_coins; i++)
- TALER_denom_sig_free (&rctx->ev_sigs[i]);
+ TALER_blinded_denom_sig_free (&rctx->ev_sigs[i]);
GNUNET_free (rctx->ev_sigs);
rctx->ev_sigs = NULL; /* just to be safe... */
}
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c
index d9c3b9e94..ef1bb27d9 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -199,7 +199,7 @@ withdraw_transaction (void *cls,
struct WithdrawContext *wc = cls;
struct TALER_EXCHANGEDB_Reserve r;
enum GNUNET_DB_QueryStatus qs;
- struct TALER_DenominationSignature denom_sig;
+ struct TALER_BlindedDenominationSignature denom_sig;
#if OPTIMISTIC_SIGN
/* store away optimistic signature to protect
@@ -231,7 +231,7 @@ withdraw_transaction (void *cls,
optimization trade-off loses in this case: we unnecessarily computed
a signature :-( */
#if OPTIMISTIC_SIGN
- TALER_denom_sig_free (&denom_sig);
+ TALER_blinded_denom_sig_free (&denom_sig);
#endif
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
@@ -582,7 +582,7 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
{
/* Even if #withdraw_transaction() failed, it may have created a signature
(or we might have done it optimistically above). */
- TALER_denom_sig_free (&wc.collectable.sig);
+ TALER_blinded_denom_sig_free (&wc.collectable.sig);
GNUNET_JSON_parse_free (spec);
return mhd_ret;
}
@@ -593,7 +593,7 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
if (wc.kyc_denied)
{
- TALER_denom_sig_free (&wc.collectable.sig);
+ TALER_blinded_denom_sig_free (&wc.collectable.sig);
return TALER_MHD_REPLY_JSON_PACK (
rc->connection,
MHD_HTTP_ACCEPTED,
@@ -607,9 +607,9 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
ret = TALER_MHD_REPLY_JSON_PACK (
rc->connection,
MHD_HTTP_OK,
- TALER_JSON_pack_denom_sig ("ev_sig",
- &wc.collectable.sig));
- TALER_denom_sig_free (&wc.collectable.sig);
+ TALER_JSON_pack_blinded_denom_sig ("ev_sig",
+ &wc.collectable.sig));
+ TALER_blinded_denom_sig_free (&wc.collectable.sig);
return ret;
}
}
diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c
index 2d482698d..a07ae78c1 100644
--- a/src/exchangedb/plugin_exchangedb_common.c
+++ b/src/exchangedb/plugin_exchangedb_common.c
@@ -49,7 +49,7 @@ common_free_reserve_history (void *cls,
struct TALER_EXCHANGEDB_CollectableBlindcoin *cbc;
cbc = rh->details.withdraw;
- TALER_denom_sig_free (&cbc->sig);
+ TALER_blinded_denom_sig_free (&cbc->sig);
GNUNET_free (cbc);
break;
}
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 017145e61..85550e980 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -4404,8 +4404,8 @@ postgres_get_withdraw_info (
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&collectable->denom_pub_hash),
- TALER_PQ_result_spec_denom_sig ("denom_sig",
- &collectable->sig),
+ TALER_PQ_result_spec_blinded_denom_sig ("denom_sig",
+ &collectable->sig),
GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
&collectable->reserve_sig),
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
@@ -4456,7 +4456,7 @@ postgres_insert_withdraw_info (
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&collectable->h_coin_envelope),
GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash),
- TALER_PQ_query_param_denom_sig (&collectable->sig),
+ TALER_PQ_query_param_blinded_denom_sig (&collectable->sig),
GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub),
GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig),
TALER_PQ_query_param_absolute_time (&now),
@@ -4660,8 +4660,8 @@ add_withdraw_coin (void *cls,
&cbc->h_coin_envelope),
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&cbc->denom_pub_hash),
- TALER_PQ_result_spec_denom_sig ("denom_sig",
- &cbc->sig),
+ TALER_PQ_result_spec_blinded_denom_sig ("denom_sig",
+ &cbc->sig),
GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
&cbc->reserve_sig),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
@@ -6088,7 +6088,7 @@ postgres_insert_refresh_reveal (
GNUNET_PQ_query_param_fixed_size (rrc->coin_ev,
rrc->coin_ev_size),
GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
- TALER_PQ_query_param_denom_sig (&rrc->coin_sig),
+ TALER_PQ_query_param_blinded_denom_sig (&rrc->coin_sig),
GNUNET_PQ_query_param_end
};
enum GNUNET_DB_QueryStatus qs;
@@ -6180,8 +6180,8 @@ add_revealed_coins (void *cls,
GNUNET_PQ_result_spec_variable_size ("coin_ev",
(void **) &rrc->coin_ev,
&rrc->coin_ev_size),
- TALER_PQ_result_spec_denom_sig ("ev_sig",
- &rrc->coin_sig),
+ TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
+ &rrc->coin_sig),
GNUNET_PQ_result_spec_end
};
@@ -6309,7 +6309,7 @@ cleanup:
struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &grctx.rrcs[i];
TALER_denom_pub_free (&rrc->denom_pub);
- TALER_denom_sig_free (&rrc->coin_sig);
+ TALER_blinded_denom_sig_free (&rrc->coin_sig);
GNUNET_free (rrc->coin_ev);
}
GNUNET_free (grctx.rrcs);
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index af567ba02..69acfa0b3 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -524,6 +524,34 @@ struct TALER_DenominationSignature
/**
+ * @brief Type for *blinded* denomination signatures for Taler.
+ * Must be unblinded before it becomes valid.
+ */
+struct TALER_BlindedDenominationSignature
+{
+
+ /**
+ * Type of the signature.
+ */
+ enum TALER_DenominationCipher cipher;
+
+ /**
+ * Details, depending on @e cipher.
+ */
+ union
+ {
+
+ /**
+ * If we use #TALER_DENOMINATION_RSA in @a cipher.
+ */
+ struct GNUNET_CRYPTO_RsaSignature *blinded_rsa_signature;
+
+ } details;
+
+};
+
+
+/**
* @brief Type of public signing keys for verifying blindly signed coins.
*/
struct TALER_DenominationPublicKey
@@ -663,6 +691,16 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig);
/**
+ * Free internals of @a denom_sig, but not @a denom_sig itself.
+ *
+ * @param[in] denom_sig signature to free
+ */
+void
+TALER_blinded_denom_sig_free (
+ struct TALER_BlindedDenominationSignature *denom_sig);
+
+
+/**
* Compute the hash of the given @a denom_pub.
*
* @param denom_pub public key to hash
@@ -698,6 +736,19 @@ TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst,
/**
+ * Make a (deep) copy of the given @a denom_src to
+ * @a denom_dst.
+ *
+ * @param[out] denom_dst target to copy to
+ * @param denom_str public key to copy
+ */
+void
+TALER_blinded_denom_sig_deep_copy (
+ struct TALER_BlindedDenominationSignature *denom_dst,
+ const struct TALER_BlindedDenominationSignature *denom_src);
+
+
+/**
* Compare two denomination public keys.
*
* @param denom1 first key
@@ -1014,11 +1065,12 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
-TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
- const struct GNUNET_CRYPTO_RsaSignature *blind_sig,
- const struct TALER_PlanchetSecretsP *ps,
- const struct TALER_CoinPubHash *c_hash,
- struct TALER_FreshCoin *coin);
+TALER_planchet_to_coin (
+ const struct TALER_DenominationPublicKey *dk,
+ const struct TALER_BlindedDenominationSignature *blind_sig,
+ const struct TALER_PlanchetSecretsP *ps,
+ const struct TALER_CoinPubHash *c_hash,
+ struct TALER_FreshCoin *coin);
/* ****************** Refresh crypto primitives ************* */
@@ -1215,7 +1267,7 @@ TALER_CRYPTO_helper_denom_poll (struct TALER_CRYPTO_DenominationHelper *dh);
* @return signature, the value inside the structure will be NULL on failure,
* see @a ec for details about the failure
*/
-struct TALER_DenominationSignature
+struct TALER_BlindedDenominationSignature
TALER_CRYPTO_helper_denom_sign (
struct TALER_CRYPTO_DenominationHelper *dh,
const struct TALER_DenominationHash *h_denom_pub,
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index 6daa120d4..361956cbe 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1387,7 +1387,7 @@ typedef void
(*TALER_EXCHANGE_Withdraw2Callback) (
void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct GNUNET_CRYPTO_RsaSignature *blind_sig);
+ const struct TALER_BlindedDenominationSignature *blind_sig);
/**
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index aa67092ee..17df75281 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -696,9 +696,9 @@ struct TALER_EXCHANGEDB_CollectableBlindcoin
{
/**
- * Our signature over the (blinded) coin.
+ * Our (blinded) signature over the (blinded) coin.
*/
- struct TALER_DenominationSignature sig;
+ struct TALER_BlindedDenominationSignature sig;
/**
* Hash of the denomination key (which coin was generated).
@@ -1616,7 +1616,7 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin
/**
* Signature generated by the exchange over the coin (in blinded format).
*/
- struct TALER_DenominationSignature coin_sig;
+ struct TALER_BlindedDenominationSignature coin_sig;
};
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index e381a7a10..26df1f113 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -160,6 +160,21 @@ TALER_JSON_pack_denom_sig (
/**
* Generate packer instruction for a JSON field of type
+ * blinded denomination signature (that needs to be
+ * unblinded before it becomes valid).
+ *
+ * @param name name of the field to add to the object
+ * @param sig signature
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_blinded_denom_sig (
+ const char *name,
+ const struct TALER_BlindedDenominationSignature *sig);
+
+
+/**
+ * Generate packer instruction for a JSON field of type
* amount.
*
* @param name name of the field to add to the object
@@ -328,6 +343,20 @@ TALER_JSON_spec_denom_sig (const char *field,
/**
+ * Generate line in parser specification for a
+ * blinded denomination signature.
+ *
+ * @param field name of the field
+ * @param sig the blinded signature to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_blinded_denom_sig (
+ const char *field,
+ struct TALER_BlindedDenominationSignature *sig);
+
+
+/**
* The expected field stores a possibly internationalized string.
* Internationalization means that there is another field "$name_i18n"
* which is an object where the keys are languages. If this is
diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h
index 07057722a..6e69cdf6d 100644
--- a/src/include/taler_pq_lib.h
+++ b/src/include/taler_pq_lib.h
@@ -78,6 +78,18 @@ TALER_PQ_query_param_denom_sig (
/**
+ * Generate query parameter for a blinded denomination signature. Internally,
+ * the various attributes of the signature will be serialized into on
+ * variable-size BLOB.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_blinded_denom_sig (
+ const struct TALER_BlindedDenominationSignature *denom_sig);
+
+
+/**
* Generate query parameter for a JSON object (stored as a string
* in the DB). Note that @a x must really be a JSON object or array,
* passing just a value (string, integer) is not supported and will
@@ -169,6 +181,19 @@ TALER_PQ_result_spec_denom_sig (const char *name,
/**
+ * Blinded denomination signature expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] denom_sig where to store the denomination signature
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_blinded_denom_sig (
+ const char *name,
+ struct TALER_BlindedDenominationSignature *denom_sig);
+
+
+/**
* json_t expected.
*
* @param name name of the field in the table
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index d509f4eff..1684e7f35 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -433,7 +433,7 @@ TALER_JSON_spec_relative_time (const char *name,
* @param[out] spec where to write the data
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
-static int
+static enum GNUNET_GenericReturnValue
parse_denom_pub (void *cls,
json_t *root,
struct GNUNET_JSON_Specification *spec)
@@ -528,7 +528,7 @@ TALER_JSON_spec_denom_pub (const char *field,
* @param[out] spec where to write the data
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
-static int
+static enum GNUNET_GenericReturnValue
parse_denom_sig (void *cls,
json_t *root,
struct GNUNET_JSON_Specification *spec)
@@ -614,6 +614,100 @@ TALER_JSON_spec_denom_sig (const char *field,
/**
+ * Parse given JSON object to blinded denomination 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_denom_sig (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
+{
+ struct TALER_BlindedDenominationSignature *denom_sig = spec->ptr;
+ uint32_t cipher;
+ struct GNUNET_JSON_Specification dspec[] = {
+ GNUNET_JSON_spec_uint32 ("cipher",
+ &cipher),
+ GNUNET_JSON_spec_end ()
+ };
+ const char *emsg;
+ unsigned int eline;
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (root,
+ dspec,
+ &emsg,
+ &eline))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ denom_sig->cipher = (enum TALER_DenominationCipher) cipher;
+ switch (denom_sig->cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ {
+ struct GNUNET_JSON_Specification ispec[] = {
+ GNUNET_JSON_spec_rsa_signature (
+ "blinded_rsa_signature",
+ &denom_sig->details.blinded_rsa_signature),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (root,
+ ispec,
+ &emsg,
+ &eline))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+ }
+ default:
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+}
+
+
+/**
+ * Cleanup data left from parsing denomination public key.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_blinded_denom_sig (void *cls,
+ struct GNUNET_JSON_Specification *spec)
+{
+ struct TALER_BlindedDenominationSignature *denom_sig = spec->ptr;
+
+ TALER_blinded_denom_sig_free (denom_sig);
+}
+
+
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_blinded_denom_sig (
+ const char *field,
+ struct TALER_BlindedDenominationSignature *sig)
+{
+ struct GNUNET_JSON_Specification ret = {
+ .parser = &parse_blinded_denom_sig,
+ .cleaner = &clean_blinded_denom_sig,
+ .field = field,
+ .ptr = sig
+ };
+
+ return ret;
+}
+
+
+/**
* Closure for #parse_i18n_string.
*/
struct I18nContext
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
index 0d1c95708..59e3afb77 100644
--- a/src/json/json_pack.c
+++ b/src/json/json_pack.c
@@ -142,6 +142,32 @@ TALER_JSON_pack_denom_sig (
struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_blinded_denom_sig (
+ const char *name,
+ const struct TALER_BlindedDenominationSignature *sig)
+{
+ struct GNUNET_JSON_PackSpec ps = {
+ .field_name = name,
+ };
+
+ switch (sig->cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ ps.object
+ = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_uint64 ("cipher",
+ TALER_DENOMINATION_RSA),
+ GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature",
+ sig->details.blinded_rsa_signature));
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+ return ps;
+}
+
+
+struct GNUNET_JSON_PackSpec
TALER_JSON_pack_amount (const char *name,
const struct TALER_Amount *amount)
{
diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c
index 0af37c021..c275e0a4d 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -137,12 +137,12 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
const struct TALER_PlanchetSecretsP *fc;
struct TALER_DenominationPublicKey *pk;
json_t *jsonai;
- struct GNUNET_CRYPTO_RsaSignature *blind_sig;
+ struct TALER_BlindedDenominationSignature blind_sig;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinPubHash coin_hash;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_rsa_signature ("ev_sig",
- &blind_sig),
+ TALER_JSON_spec_blinded_denom_sig ("ev_sig",
+ &blind_sig),
GNUNET_JSON_spec_end ()
};
struct TALER_FreshCoin coin;
@@ -170,17 +170,17 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
&coin_hash);
if (GNUNET_OK !=
TALER_planchet_to_coin (pk,
- blind_sig,
+ &blind_sig,
fc,
&coin_hash,
&coin))
{
GNUNET_break_op (0);
- GNUNET_CRYPTO_rsa_signature_free (blind_sig);
+ GNUNET_JSON_parse_free (spec);
GNUNET_JSON_parse_free (outer_spec);
return GNUNET_SYSERR;
}
- GNUNET_CRYPTO_rsa_signature_free (blind_sig);
+ GNUNET_JSON_parse_free (spec);
sigs[i] = coin.sig;
}
GNUNET_JSON_parse_free (outer_spec);
diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c
index 8e00cfcdb..5e823ee6d 100644
--- a/src/lib/exchange_api_withdraw.c
+++ b/src/lib/exchange_api_withdraw.c
@@ -88,7 +88,7 @@ static void
handle_reserve_withdraw_finished (
void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct GNUNET_CRYPTO_RsaSignature *blind_sig)
+ const struct TALER_BlindedDenominationSignature *blind_sig)
{
struct TALER_EXCHANGE_WithdrawHandle *wh = cls;
struct TALER_EXCHANGE_WithdrawResponse wr = {
diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c
index e001a3154..d50892e5b 100644
--- a/src/lib/exchange_api_withdraw2.c
+++ b/src/lib/exchange_api_withdraw2.c
@@ -99,10 +99,10 @@ static enum GNUNET_GenericReturnValue
reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh,
const json_t *json)
{
- struct GNUNET_CRYPTO_RsaSignature *blind_sig;
+ struct TALER_BlindedDenominationSignature blind_sig;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_rsa_signature ("ev_sig",
- &blind_sig),
+ TALER_JSON_spec_blinded_denom_sig ("ev_sig",
+ &blind_sig),
GNUNET_JSON_spec_end ()
};
struct TALER_EXCHANGE_HttpResponse hr = {
@@ -122,7 +122,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh,
/* signature is valid, return it to the application */
wh->cb (wh->cb_cls,
&hr,
- blind_sig);
+ &blind_sig);
/* make sure callback isn't called again after return */
wh->cb = NULL;
GNUNET_JSON_parse_free (spec);
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index 3f51ddbe8..618877608 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -265,7 +265,7 @@ qconv_denom_sig (void *cls,
const struct TALER_DenominationSignature *denom_sig = data;
size_t tlen;
size_t len;
- uint32_t be;
+ uint32_t be[2];
char *buf;
void *tbuf;
@@ -273,7 +273,8 @@ qconv_denom_sig (void *cls,
GNUNET_assert (1 == param_length);
GNUNET_assert (scratch_length > 0);
GNUNET_break (NULL == cls);
- be = htonl ((uint32_t) denom_sig->cipher);
+ be[0] = htonl ((uint32_t) denom_sig->cipher);
+ be[1] = htonl (0x00); /* magic marker: unblinded */
switch (denom_sig->cipher)
{
case TALER_DENOMINATION_RSA:
@@ -329,6 +330,95 @@ TALER_PQ_query_param_denom_sig (
* Function called to convert input argument into SQL parameters.
*
* @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @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_blinded_denom_sig (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)
+{
+ const struct TALER_BlindedDenominationSignature *denom_sig = data;
+ size_t tlen;
+ size_t len;
+ uint32_t be[2];
+ char *buf;
+ void *tbuf;
+
+ (void) cls;
+ GNUNET_assert (1 == param_length);
+ GNUNET_assert (scratch_length > 0);
+ GNUNET_break (NULL == cls);
+ be[0] = htonl ((uint32_t) denom_sig->cipher);
+ be[1] = htonl (0x01); /* magic marker: blinded */
+ switch (denom_sig->cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ tlen = GNUNET_CRYPTO_rsa_signature_encode (
+ denom_sig->details.blinded_rsa_signature,
+ &tbuf);
+ break;
+ // TODO: add case for Clause-Schnorr
+ default:
+ GNUNET_assert (0);
+ }
+ len = tlen + sizeof (be);
+ buf = GNUNET_malloc (len);
+ memcpy (buf,
+ &be,
+ sizeof (be));
+ switch (denom_sig->cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ memcpy (&buf[sizeof (be)],
+ tbuf,
+ tlen);
+ GNUNET_free (tbuf);
+ break;
+ // TODO: add case for Clause-Schnorr
+ default:
+ GNUNET_assert (0);
+ }
+
+ scratch[0] = buf;
+ param_values[0] = (void *) buf;
+ param_lengths[0] = len;
+ param_formats[0] = 1;
+ return 1;
+}
+
+
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_blinded_denom_sig (
+ const struct TALER_BlindedDenominationSignature *denom_sig)
+{
+ struct GNUNET_PQ_QueryParam res = {
+ .conv = &qconv_blinded_denom_sig,
+ .data = denom_sig,
+ .num_params = 1
+ };
+
+ return res;
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
* @param data pointer to input argument, here a `json_t *`
* @param data_len number of bytes in @a data (if applicable)
* @param[out] param_values SQL data to set
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index 57bcf6dd3..2f570b6bb 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -630,7 +630,7 @@ extract_denom_sig (void *cls,
size_t len;
const char *res;
int fnum;
- uint32_t be;
+ uint32_t be[2];
(void) cls;
fnum = PQfnumber (result,
@@ -661,9 +661,14 @@ extract_denom_sig (void *cls,
memcpy (&be,
res,
sizeof (be));
+ if (0x00 != ntohl (be[1]))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
res += sizeof (be);
len -= sizeof (be);
- sig->cipher = ntohl (be);
+ sig->cipher = ntohl (be[0]);
switch (sig->cipher)
{
case TALER_DENOMINATION_RSA:
@@ -717,4 +722,122 @@ TALER_PQ_result_spec_denom_sig (const char *name,
}
+/**
+ * Extract data from a Postgres database @a result at row @a row.
+ *
+ * @param cls closure
+ * @param result where to extract data from
+ * @param int 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_blinded_denom_sig (void *cls,
+ PGresult *result,
+ int row,
+ const char *fname,
+ size_t *dst_size,
+ void *dst)
+{
+ struct TALER_BlindedDenominationSignature *sig = dst;
+ size_t len;
+ const char *res;
+ int fnum;
+ uint32_t be[2];
+
+ (void) cls;
+ fnum = PQfnumber (result,
+ fname);
+ if (fnum < 0)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (PQgetisnull (result,
+ row,
+ fnum))
+ return GNUNET_NO;
+
+ /* if a field is null, continue but
+ * remember that we now return a different result */
+ len = PQgetlength (result,
+ row,
+ fnum);
+ res = PQgetvalue (result,
+ row,
+ fnum);
+ if (len < sizeof (be))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ memcpy (&be,
+ res,
+ sizeof (be));
+ if (0x01 != ntohl (be[1])) /* magic marker: blinded */
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ res += sizeof (be);
+ len -= sizeof (be);
+ sig->cipher = ntohl (be[0]);
+ switch (sig->cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ sig->details.blinded_rsa_signature
+ = GNUNET_CRYPTO_rsa_signature_decode (res,
+ len);
+ if (NULL == sig->details.blinded_rsa_signature)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+ // FIXME: add CS case!
+ default:
+ GNUNET_break (0);
+ }
+ return GNUNET_SYSERR;
+}
+
+
+/**
+ * Function called to clean up memory allocated
+ * by a #GNUNET_PQ_ResultConverter.
+ *
+ * @param cls closure
+ * @param rd result data to clean up
+ */
+static void
+clean_blinded_denom_sig (void *cls,
+ void *rd)
+{
+ struct TALER_BlindedDenominationSignature *denom_sig = rd;
+
+ (void) cls;
+ TALER_blinded_denom_sig_free (denom_sig);
+}
+
+
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_blinded_denom_sig (
+ const char *name,
+ struct TALER_BlindedDenominationSignature *denom_sig)
+{
+ struct GNUNET_PQ_ResultSpec res = {
+ .conv = &extract_blinded_denom_sig,
+ .cleaner = &clean_blinded_denom_sig,
+ .dst = (void *) denom_sig,
+ .fname = name
+ };
+
+ return res;
+}
+
+
/* end of pq_result_helper.c */
diff --git a/src/util/crypto.c b/src/util/crypto.c
index c7b459450..99744304b 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -212,21 +212,23 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
enum GNUNET_GenericReturnValue
-TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
- const struct GNUNET_CRYPTO_RsaSignature *blind_sig,
- const struct TALER_PlanchetSecretsP *ps,
- const struct TALER_CoinPubHash *c_hash,
- struct TALER_FreshCoin *coin)
+TALER_planchet_to_coin (
+ const struct TALER_DenominationPublicKey *dk,
+ const struct TALER_BlindedDenominationSignature *blind_sig,
+ const struct TALER_PlanchetSecretsP *ps,
+ const struct TALER_CoinPubHash *c_hash,
+ struct TALER_FreshCoin *coin)
{
struct TALER_DenominationSignature sig;
- // FIXME-Gian/Lucien: this will be the bigger
+ // FIXME-Gian/Lucien: this may need a bigger
// change, as you have the extra round trip
// => to be discussed!
GNUNET_assert (TALER_DENOMINATION_RSA == dk->cipher);
+ GNUNET_assert (TALER_DENOMINATION_RSA == blind_sig->cipher);
sig.cipher = TALER_DENOMINATION_RSA;
sig.details.rsa_signature
- = TALER_rsa_unblind (blind_sig,
+ = TALER_rsa_unblind (blind_sig->details.blinded_rsa_signature,
&ps->blinding_key.bks,
dk->details.rsa_public_key);
if (GNUNET_OK !=
diff --git a/src/util/crypto_helper_denom.c b/src/util/crypto_helper_denom.c
index ba56a4e71..4dfd32fbd 100644
--- a/src/util/crypto_helper_denom.c
+++ b/src/util/crypto_helper_denom.c
@@ -541,7 +541,7 @@ TALER_CRYPTO_helper_denom_poll (struct TALER_CRYPTO_DenominationHelper *dh)
}
-struct TALER_DenominationSignature
+struct TALER_BlindedDenominationSignature
TALER_CRYPTO_helper_denom_sign (
struct TALER_CRYPTO_DenominationHelper *dh,
const struct TALER_DenominationHash *h_denom_pub,
@@ -549,8 +549,8 @@ TALER_CRYPTO_helper_denom_sign (
size_t msg_size,
enum TALER_ErrorCode *ec)
{
- struct TALER_DenominationSignature ds = {
- .details.rsa_signature = NULL
+ struct TALER_BlindedDenominationSignature ds = {
+ .details.blinded_rsa_signature = NULL
};
{
char buf[sizeof (struct TALER_CRYPTO_SignRequest) + msg_size];
@@ -652,7 +652,7 @@ TALER_CRYPTO_helper_denom_sign (
}
*ec = TALER_EC_NONE;
ds.cipher = TALER_DENOMINATION_RSA;
- ds.details.rsa_signature = rsa_signature;
+ ds.details.blinded_rsa_signature = rsa_signature;
return ds;
}
case TALER_HELPER_RSA_MT_RES_SIGN_FAILURE:
diff --git a/src/util/denom.c b/src/util/denom.c
index 33b507639..8d6ddd5e7 100644
--- a/src/util/denom.c
+++ b/src/util/denom.c
@@ -169,6 +169,27 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)
}
+void
+TALER_blinded_denom_sig_free (
+ struct TALER_BlindedDenominationSignature *denom_sig)
+{
+ switch (denom_sig->cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ if (NULL != denom_sig->details.blinded_rsa_signature)
+ {
+ GNUNET_CRYPTO_rsa_signature_free (
+ denom_sig->details.blinded_rsa_signature);
+ denom_sig->details.blinded_rsa_signature = NULL;
+ }
+ return;
+ // TODO: add case for Clause-Schnorr
+ default:
+ GNUNET_assert (0);
+ }
+}
+
+
/**
* Make a (deep) copy of the given @a denom_src to
* @a denom_dst.
@@ -214,13 +235,26 @@ TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst,
}
-/**
- * Compare two denomination public keys.
- *
- * @param denom1 first key
- * @param denom2 second key
- * @return 0 if the keys are equal, otherwise -1 or 1
- */
+void
+TALER_blinded_denom_sig_deep_copy (
+ struct TALER_BlindedDenominationSignature *denom_dst,
+ const struct TALER_BlindedDenominationSignature *denom_src)
+{
+ *denom_dst = *denom_src; /* shallow copy */
+ switch (denom_src->cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ denom_dst->details.blinded_rsa_signature
+ = GNUNET_CRYPTO_rsa_signature_dup (
+ denom_src->details.blinded_rsa_signature);
+ return;
+ // TODO: add case for Clause-Schnorr
+ default:
+ GNUNET_assert (0);
+ }
+}
+
+
int
TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1,
const struct TALER_DenominationPublicKey *denom2)