implement handle_refresh_reveal_finished (200 OK handler)
This commit is contained in:
parent
1e8529a19e
commit
6b048a0dc6
@ -869,6 +869,7 @@ TALER_MINT_refresh_prepare (unsigned int num_melts,
|
|||||||
unsigned int j;
|
unsigned int j;
|
||||||
struct GNUNET_HashContext *hash_context;
|
struct GNUNET_HashContext *hash_context;
|
||||||
|
|
||||||
|
/* build up melt data structure */
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
|
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
|
||||||
&md.link_secrets[i],
|
&md.link_secrets[i],
|
||||||
@ -1660,9 +1661,107 @@ struct TALER_MINT_RefreshRevealHandle
|
|||||||
*/
|
*/
|
||||||
struct MeltData *md;
|
struct MeltData *md;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index selected by the mint in cut-and-choose to not be revealed.
|
||||||
|
*/
|
||||||
|
uint16_t noreveal_index;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We got a 200 OK response for the /refresh/reveal operation.
|
||||||
|
* Extract the coin signatures and return them to the caller.
|
||||||
|
* The signatures we get from the mint is for the blinded value.
|
||||||
|
* Thus, we first must unblind them and then should verify their
|
||||||
|
* validity.
|
||||||
|
*
|
||||||
|
* If everything checks out, we return the unblinded signatures
|
||||||
|
* to the application via the callback.
|
||||||
|
*
|
||||||
|
* @param rrh operation handle
|
||||||
|
* @param jsona reply from the mint
|
||||||
|
* @param[out] coin_privs array of length `num_fresh_coins`, initialized to contain private keys
|
||||||
|
* @param[out] sigs array of length `num_fresh_coins`, initialized to cointain RSA signatures
|
||||||
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
refresh_reveal_ok (struct TALER_MINT_RefreshRevealHandle *rrh,
|
||||||
|
json_t *jsona,
|
||||||
|
struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||||
|
struct TALER_DenominationSignature *sigs)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (! json_is_array (jsona))
|
||||||
|
{
|
||||||
|
/* We expected an array of coins */
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (rrh->md->num_fresh_coins != json_array_size (jsona))
|
||||||
|
{
|
||||||
|
/* Number of coins generated does not match our expectation */
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
for (i=0;i<rrh->md->num_fresh_coins;i++)
|
||||||
|
{
|
||||||
|
const struct FreshCoin *fc;
|
||||||
|
struct TALER_DenominationPublicKey *pk;
|
||||||
|
json_t *json;
|
||||||
|
struct GNUNET_CRYPTO_rsa_Signature *blind_sig;
|
||||||
|
struct GNUNET_CRYPTO_rsa_Signature *sig;
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
struct GNUNET_HashCode coin_hash;
|
||||||
|
|
||||||
|
struct MAJ_Specification spec[] = {
|
||||||
|
MAJ_spec_rsa_signature ("ev_sig", &blind_sig),
|
||||||
|
MAJ_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
fc = &rrh->md->fresh_coins[rrh->noreveal_index][i];
|
||||||
|
pk = &rrh->md->fresh_pks[i];
|
||||||
|
json = json_array_get (jsona, i);
|
||||||
|
GNUNET_assert (NULL != json);
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
MAJ_parse_json (json,
|
||||||
|
spec))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unblind the signature */
|
||||||
|
sig = GNUNET_CRYPTO_rsa_unblind (blind_sig,
|
||||||
|
fc->blinding_key.rsa_blinding_key,
|
||||||
|
pk->rsa_public_key);
|
||||||
|
GNUNET_CRYPTO_rsa_signature_free (blind_sig);
|
||||||
|
|
||||||
|
/* verify the signature */
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
||||||
|
&coin_pub.eddsa_pub);
|
||||||
|
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
||||||
|
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
||||||
|
&coin_hash);
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_rsa_verify (&coin_hash,
|
||||||
|
sig,
|
||||||
|
pk->rsa_public_key))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
GNUNET_CRYPTO_rsa_signature_free (sig);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
coin_privs[i] = fc->coin_priv;
|
||||||
|
sigs[i].rsa_signature = sig;
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called when we're done processing the
|
* Function called when we're done processing the
|
||||||
* HTTP /refresh/reveal request.
|
* HTTP /refresh/reveal request.
|
||||||
@ -1687,8 +1786,35 @@ handle_refresh_reveal_finished (void *cls,
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case MHD_HTTP_OK:
|
case MHD_HTTP_OK:
|
||||||
GNUNET_break (0); // FIXME: NOT implemented!
|
{
|
||||||
// rrh->reveal_cb = NULL; (call with real result, do not call again below)
|
struct TALER_CoinSpendPrivateKeyP coin_privs[rrh->md->num_fresh_coins];
|
||||||
|
struct TALER_DenominationSignature sigs[rrh->md->num_fresh_coins];
|
||||||
|
unsigned int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset (sigs, 0, sizeof (sigs));
|
||||||
|
ret = refresh_reveal_ok (rrh,
|
||||||
|
json,
|
||||||
|
coin_privs,
|
||||||
|
sigs);
|
||||||
|
if (GNUNET_OK != ret)
|
||||||
|
{
|
||||||
|
response_code = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rrh->reveal_cb (rrh->reveal_cb_cls,
|
||||||
|
MHD_HTTP_OK,
|
||||||
|
rrh->md->num_fresh_coins,
|
||||||
|
coin_privs,
|
||||||
|
sigs,
|
||||||
|
json);
|
||||||
|
rrh->reveal_cb = NULL;
|
||||||
|
}
|
||||||
|
for (i=0;i<rrh->md->num_fresh_coins;i++)
|
||||||
|
if (NULL != sigs[i].rsa_signature)
|
||||||
|
GNUNET_CRYPTO_rsa_signature_free (sigs[i].rsa_signature);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MHD_HTTP_BAD_REQUEST:
|
case MHD_HTTP_BAD_REQUEST:
|
||||||
/* This should never happen, either us or the mint is buggy
|
/* This should never happen, either us or the mint is buggy
|
||||||
@ -1820,6 +1946,7 @@ TALER_MINT_refresh_reveal (struct TALER_MINT_Handle *mint,
|
|||||||
/* finally, we can actually issue the request */
|
/* finally, we can actually issue the request */
|
||||||
rrh = GNUNET_new (struct TALER_MINT_RefreshRevealHandle);
|
rrh = GNUNET_new (struct TALER_MINT_RefreshRevealHandle);
|
||||||
rrh->mint = mint;
|
rrh->mint = mint;
|
||||||
|
rrh->noreveal_index = noreveal_index;
|
||||||
rrh->reveal_cb = reveal_cb;
|
rrh->reveal_cb = reveal_cb;
|
||||||
rrh->reveal_cb_cls = reveal_cb_cls;
|
rrh->reveal_cb_cls = reveal_cb_cls;
|
||||||
rrh->md = md;
|
rrh->md = md;
|
||||||
|
Loading…
Reference in New Issue
Block a user