adding signature verification logic for new link signatures to libtalerexchange

This commit is contained in:
Christian Grothoff 2019-06-26 16:13:17 +02:00
parent 3a2f72b4aa
commit 0be3dd4711
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 83 additions and 44 deletions

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2017 Inria & GNUnet e.V. Copyright (C) 2014-2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2017 Inria & GNUnet e.V. Copyright (C) 2014-2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -730,7 +730,6 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
GNUNET_CRYPTO_hash (rcds[i].coin_ev, GNUNET_CRYPTO_hash (rcds[i].coin_ev,
rcds[i].coin_ev_size, rcds[i].coin_ev_size,
&ldp.coin_envelope_hash); &ldp.coin_envelope_hash);
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
&ldp.purpose, &ldp.purpose,

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2015, 2016, 2017 Taler Systems SA Copyright (C) 2015, 2016, 2017, 2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software terms of the GNU General Public License as published by the Free Software

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2015, 2016 GNUnet e.V. Copyright (C) 2015, 2016, 2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software terms of the GNU General Public License as published by the Free Software
@ -93,9 +93,11 @@ parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
{ {
struct GNUNET_CRYPTO_RsaSignature *bsig; struct GNUNET_CRYPTO_RsaSignature *bsig;
struct GNUNET_CRYPTO_RsaPublicKey *rpub; struct GNUNET_CRYPTO_RsaPublicKey *rpub;
struct TALER_CoinSpendSignatureP link_sig;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_rsa_public_key ("denom_pub", &rpub), GNUNET_JSON_spec_rsa_public_key ("denom_pub", &rpub),
GNUNET_JSON_spec_rsa_signature ("ev_sig", &bsig), GNUNET_JSON_spec_rsa_signature ("ev_sig", &bsig),
GNUNET_JSON_spec_fixed_auto ("link_sig", &link_sig),
GNUNET_JSON_spec_end() GNUNET_JSON_spec_end()
}; };
struct TALER_TransferSecretP secret; struct TALER_TransferSecretP secret;
@ -115,8 +117,8 @@ parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
&rlh->coin_priv, &rlh->coin_priv,
&secret); &secret);
TALER_planchet_setup_refresh (&secret, TALER_planchet_setup_refresh (&secret,
coin_num, coin_num,
&fc); &fc);
/* extract coin and signature */ /* extract coin and signature */
*coin_priv = fc.coin_priv; *coin_priv = fc.coin_priv;
@ -124,6 +126,44 @@ parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
= GNUNET_CRYPTO_rsa_unblind (bsig, = GNUNET_CRYPTO_rsa_unblind (bsig,
&fc.blinding_key.bks, &fc.blinding_key.bks,
rpub); rpub);
/* verify link_sig */
{
struct TALER_LinkDataPS ldp;
struct TALER_PlanchetDetail pd;
ldp.purpose.size = htonl (sizeof (ldp));
ldp.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK);
GNUNET_CRYPTO_eddsa_key_get_public (&rlh->coin_priv.eddsa_priv,
&ldp.old_coin_pub.eddsa_pub);
ldp.transfer_pub = *trans_pub;
pub->rsa_public_key = rpub;
if (GNUNET_OK !=
TALER_planchet_prepare (pub,
&fc,
&pd))
{
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
ldp.h_denom_pub = pd.denom_pub_hash;
GNUNET_CRYPTO_hash (pd.coin_ev,
pd.coin_ev_size,
&ldp.coin_envelope_hash);
GNUNET_free (pd.coin_ev);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
&ldp.purpose,
&link_sig.eddsa_signature,
&ldp.old_coin_pub.eddsa_pub))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
}
/* clean up */ /* clean up */
pub->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (rpub); pub->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (rpub);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
@ -173,7 +213,7 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
}; };
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_JSON_parse (json_array_get (json, GNUNET_JSON_parse (json_array_get (json,
session), session),
spec, spec,
NULL, NULL)) NULL, NULL))
@ -209,55 +249,55 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
json_t *jsona; json_t *jsona;
struct TALER_TransferPublicKeyP trans_pub; struct TALER_TransferPublicKeyP trans_pub;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("new_coins", GNUNET_JSON_spec_json ("new_coins",
&jsona), &jsona),
GNUNET_JSON_spec_fixed_auto ("transfer_pub", GNUNET_JSON_spec_fixed_auto ("transfer_pub",
&trans_pub), &trans_pub),
GNUNET_JSON_spec_end() GNUNET_JSON_spec_end()
}; };
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_JSON_parse (json_array_get (json, GNUNET_JSON_parse (json_array_get (json,
session), session),
spec, spec,
NULL, NULL)) NULL, NULL))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (! json_is_array (jsona)) if (! json_is_array (jsona))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
/* decode all coins */ /* decode all coins */
for (i=0;i<json_array_size (jsona);i++) for (i=0;i<json_array_size (jsona);i++)
{ {
GNUNET_assert (i + off_coin < num_coins); GNUNET_assert (i + off_coin < num_coins);
if (GNUNET_OK != if (GNUNET_OK !=
parse_refresh_link_coin (rlh, parse_refresh_link_coin (rlh,
json_array_get (jsona, json_array_get (jsona,
i), i),
i, i,
&trans_pub, &trans_pub,
&coin_privs[i+off_coin], &coin_privs[i+off_coin],
&sigs[i+off_coin], &sigs[i+off_coin],
&pubs[i+off_coin])) &pubs[i+off_coin]))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
break; break;
} }
} }
/* check if we really got all, then invoke callback */ /* check if we really got all, then invoke callback */
off_coin += i; off_coin += i;
if (i != json_array_size (jsona)) if (i != json_array_size (jsona))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
ret = GNUNET_SYSERR; ret = GNUNET_SYSERR;
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
break; break;
} }
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
} /* end of for (session) */ } /* end of for (session) */
@ -265,13 +305,13 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
if (off_coin == num_coins) if (off_coin == num_coins)
{ {
rlh->link_cb (rlh->link_cb_cls, rlh->link_cb (rlh->link_cb_cls,
MHD_HTTP_OK, MHD_HTTP_OK,
TALER_EC_NONE, TALER_EC_NONE,
num_coins, num_coins,
coin_privs, coin_privs,
sigs, sigs,
pubs, pubs,
json); json);
rlh->link_cb = NULL; rlh->link_cb = NULL;
ret = GNUNET_OK; ret = GNUNET_OK;
} }
@ -349,11 +389,11 @@ handle_refresh_link_finished (void *cls,
if (NULL != rlh->link_cb) if (NULL != rlh->link_cb)
rlh->link_cb (rlh->link_cb_cls, rlh->link_cb (rlh->link_cb_cls,
response_code, response_code,
TALER_JSON_get_error_code (j), TALER_JSON_get_error_code (j),
0, 0,
NULL, NULL,
NULL, NULL,
NULL, NULL,
j); j);
TALER_EXCHANGE_refresh_link_cancel (rlh); TALER_EXCHANGE_refresh_link_cancel (rlh);
} }