distinguish between blind and non-blind denomination signatures

This commit is contained in:
Christian Grothoff 2021-10-31 17:56:56 +01:00
parent de8e0907aa
commit 3eae999efc
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
21 changed files with 550 additions and 74 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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... */
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -523,6 +523,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.
*/
@ -662,6 +690,16 @@ void
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.
*
@ -697,6 +735,19 @@ TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst,
const struct TALER_DenominationSignature *denom_src);
/**
* 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.
*
@ -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,

View File

@ -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);
/**

View File

@ -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;
};

View File

@ -158,6 +158,21 @@ TALER_JSON_pack_denom_sig (
const struct TALER_DenominationSignature *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.
@ -327,6 +342,20 @@ TALER_JSON_spec_denom_sig (const char *field,
struct TALER_DenominationSignature *sig);
/**
* 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"

View File

@ -77,6 +77,18 @@ TALER_PQ_query_param_denom_sig (
const struct TALER_DenominationSignature *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,
@ -168,6 +180,19 @@ TALER_PQ_result_spec_denom_sig (const char *name,
struct TALER_DenominationSignature *denom_sig);
/**
* 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.
*

View File

@ -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)
@ -613,6 +613,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.
*/

View File

@ -141,6 +141,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)

View File

@ -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);

View File

@ -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 = {

View File

@ -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);

View File

@ -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:
@ -325,6 +326,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.
*

View File

@ -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 */

View File

@ -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 !=

View File

@ -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:

View File

@ -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)