fix major bug with SQL statement missing ORDER BY freshcoin_index resulting in possible link failures (but usually lucky with old DB schema)
This commit is contained in:
parent
02ecf68a3d
commit
ca66a1d1af
@ -83,8 +83,8 @@ handle_link_data (void *cls,
|
|||||||
|
|
||||||
obj = json_pack ("{s:o, s:o, s:o}",
|
obj = json_pack ("{s:o, s:o, s:o}",
|
||||||
"denom_pub",
|
"denom_pub",
|
||||||
GNUNET_JSON_from_rsa_public_key
|
GNUNET_JSON_from_rsa_public_key (
|
||||||
(pos->denom_pub.rsa_public_key),
|
pos->denom_pub.rsa_public_key),
|
||||||
"ev_sig",
|
"ev_sig",
|
||||||
GNUNET_JSON_from_rsa_signature
|
GNUNET_JSON_from_rsa_signature
|
||||||
(pos->ev_sig.rsa_signature),
|
(pos->ev_sig.rsa_signature),
|
||||||
|
@ -349,7 +349,7 @@ refreshes_reveal_transaction (void *cls,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Reconstruct coin envelopes from transfer private key */
|
/* Reconstruct coin envelopes from transfer private key */
|
||||||
struct TALER_TransferPrivateKeyP *tpriv
|
const struct TALER_TransferPrivateKeyP *tpriv
|
||||||
= &rctx->transfer_privs[i - off];
|
= &rctx->transfer_privs[i - off];
|
||||||
struct TALER_TransferSecretP ts;
|
struct TALER_TransferSecretP ts;
|
||||||
|
|
||||||
@ -695,34 +695,24 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
if (GNUNET_OK != res)
|
if (GNUNET_OK != res)
|
||||||
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
||||||
/* Check link_sigs[i] signature */
|
/* Check link_sigs[i] signature */
|
||||||
{
|
|
||||||
struct TALER_LinkDataPS ldp = {
|
|
||||||
.purpose.size = htonl (sizeof (ldp)),
|
|
||||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
|
|
||||||
.h_denom_pub = dk_h[i],
|
|
||||||
.old_coin_pub = melt.session.coin.coin_pub,
|
|
||||||
.transfer_pub = rctx->gamma_tp
|
|
||||||
};
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_hash (rcds[i].coin_ev,
|
|
||||||
rcds[i].coin_ev_size,
|
|
||||||
&ldp.coin_envelope_hash);
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (
|
TALER_wallet_link_verify (
|
||||||
TALER_SIGNATURE_WALLET_COIN_LINK,
|
&dk_h[i],
|
||||||
&ldp,
|
&rctx->gamma_tp,
|
||||||
&link_sigs[i].eddsa_signature,
|
rcds[i].coin_ev,
|
||||||
&melt.session.coin.coin_pub.eddsa_pub))
|
rcds[i].coin_ev_size,
|
||||||
|
&melt.session.coin.coin_pub,
|
||||||
|
&link_sigs[i]))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
ret = TALER_MHD_reply_with_error (connection,
|
ret = TALER_MHD_reply_with_error (
|
||||||
|
connection,
|
||||||
MHD_HTTP_FORBIDDEN,
|
MHD_HTTP_FORBIDDEN,
|
||||||
TALER_EC_EXCHANGE_REFRESHES_REVEAL_LINK_SIGNATURE_INVALID,
|
TALER_EC_EXCHANGE_REFRESHES_REVEAL_LINK_SIGNATURE_INVALID,
|
||||||
NULL);
|
NULL);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rctx->num_fresh_coins = num_fresh_coins;
|
rctx->num_fresh_coins = num_fresh_coins;
|
||||||
rctx->rcds = rcds;
|
rctx->rcds = rcds;
|
||||||
|
@ -280,7 +280,6 @@ COMMENT ON COLUMN refunds.deposit_serial_id
|
|||||||
IS 'Identifies ONLY the merchant_pub, h_contract_terms and known_coin_id. Multiple deposits may match a refund, this only identifies one of them.';
|
IS 'Identifies ONLY the merchant_pub, h_contract_terms and known_coin_id. Multiple deposits may match a refund, this only identifies one of them.';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Create additional tables...
|
-- Create additional tables...
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS auditors
|
CREATE TABLE IF NOT EXISTS auditors
|
||||||
|
@ -794,7 +794,7 @@ postgres_get_session (void *cls)
|
|||||||
",h_coin_ev"
|
",h_coin_ev"
|
||||||
",ev_sig"
|
",ev_sig"
|
||||||
") SELECT rcx.melt_serial_id, $2, $3, "
|
") SELECT rcx.melt_serial_id, $2, $3, "
|
||||||
" denominations_serial, $5, $6, $7 "
|
" denominations_serial, $5, $6, $7"
|
||||||
" FROM denominations"
|
" FROM denominations"
|
||||||
" CROSS JOIN rcx"
|
" CROSS JOIN rcx"
|
||||||
" WHERE denom_pub_hash=$4;",
|
" WHERE denom_pub_hash=$4;",
|
||||||
@ -1108,7 +1108,7 @@ postgres_get_session (void *cls)
|
|||||||
" (SELECT known_coin_id "
|
" (SELECT known_coin_id "
|
||||||
" FROM known_coins"
|
" FROM known_coins"
|
||||||
" WHERE coin_pub=$1)"
|
" WHERE coin_pub=$1)"
|
||||||
" ORDER BY tp.transfer_pub",
|
" ORDER BY tp.transfer_pub, rrc.freshcoin_index ASC",
|
||||||
1),
|
1),
|
||||||
/* Used in #postgres_lookup_wire_transfer */
|
/* Used in #postgres_lookup_wire_transfer */
|
||||||
GNUNET_PQ_make_prepare ("lookup_transactions",
|
GNUNET_PQ_make_prepare ("lookup_transactions",
|
||||||
@ -2323,6 +2323,11 @@ postgres_preflight (void *cls,
|
|||||||
};
|
};
|
||||||
|
|
||||||
(void) cls;
|
(void) cls;
|
||||||
|
if (NULL == session)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (NULL == session->transaction_name)
|
if (NULL == session->transaction_name)
|
||||||
return; /* all good */
|
return; /* all good */
|
||||||
if (GNUNET_OK ==
|
if (GNUNET_OK ==
|
||||||
|
@ -1050,6 +1050,47 @@ TALER_CRYPTO_helper_esign_disconnect (
|
|||||||
struct TALER_CRYPTO_ExchangeSignHelper *esh);
|
struct TALER_CRYPTO_ExchangeSignHelper *esh);
|
||||||
|
|
||||||
|
|
||||||
|
/* ********************* wallet signing ************************** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign link data.
|
||||||
|
*
|
||||||
|
* @param h_denom_pub hash of the denomiantion public key of the new coin
|
||||||
|
* @param transfer_pub transfer public key
|
||||||
|
* @param coin_ev coin envelope
|
||||||
|
* @param coin_ev_size number of bytes in @a coin_ev
|
||||||
|
* @param old_coin_priv private key to sign with
|
||||||
|
* @param[out] coin_sig resulting signature
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_wallet_link_sign (const struct GNUNET_HashCode *h_denom_pub,
|
||||||
|
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||||
|
const void *coin_ev,
|
||||||
|
size_t coin_ev_size,
|
||||||
|
const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
|
||||||
|
struct TALER_CoinSpendSignatureP *coin_sig);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify link signature.
|
||||||
|
*
|
||||||
|
* @param h_denom_pub hash of the denomiantion public key of the new coin
|
||||||
|
* @param transfer_pub transfer public key
|
||||||
|
* @param coin_ev coin envelope
|
||||||
|
* @param coin_ev_size number of bytes in @a coin_ev
|
||||||
|
* @param old_coin_priv private key to sign with
|
||||||
|
* @param coin_sig resulting signature
|
||||||
|
* @return #GNUNET_OK if the signature is valid
|
||||||
|
*/
|
||||||
|
enum GNUNET_GenericReturnValue
|
||||||
|
TALER_wallet_link_verify (
|
||||||
|
const struct GNUNET_HashCode *h_denom_pub,
|
||||||
|
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||||
|
const void *coin_ev,
|
||||||
|
size_t coin_ev_size,
|
||||||
|
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
||||||
|
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||||
|
|
||||||
/* ********************* offline signing ************************** */
|
/* ********************* offline signing ************************** */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1274,6 +1274,7 @@ struct TALER_EXCHANGEDB_LinkList
|
|||||||
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
|
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
|
||||||
*/
|
*/
|
||||||
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ struct TALER_EXCHANGE_LinkHandle
|
|||||||
*
|
*
|
||||||
* @param lh link handle
|
* @param lh link handle
|
||||||
* @param json json reply with the data for one coin
|
* @param json json reply with the data for one coin
|
||||||
* @param coin_num number of the coin to decode
|
* @param coin_num number of the coin
|
||||||
* @param trans_pub our transfer public key
|
* @param trans_pub our transfer public key
|
||||||
* @param[out] coin_priv where to return private coin key
|
* @param[out] coin_priv where to return private coin key
|
||||||
* @param[out] sig where to return private coin signature
|
* @param[out] sig where to return private coin signature
|
||||||
@ -85,7 +85,7 @@ struct TALER_EXCHANGE_LinkHandle
|
|||||||
static int
|
static int
|
||||||
parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
unsigned int coin_num,
|
uint32_t coin_num,
|
||||||
const struct TALER_TransferPublicKeyP *trans_pub,
|
const struct TALER_TransferPublicKeyP *trans_pub,
|
||||||
struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
struct TALER_DenominationSignature *sig,
|
struct TALER_DenominationSignature *sig,
|
||||||
@ -112,7 +112,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TALER_link_recover_transfer_secret (trans_pub,
|
TALER_link_recover_transfer_secret (trans_pub,
|
||||||
&lh->coin_priv,
|
&lh->coin_priv,
|
||||||
&secret);
|
&secret);
|
||||||
@ -130,14 +129,10 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
{
|
{
|
||||||
struct TALER_PlanchetDetail pd;
|
struct TALER_PlanchetDetail pd;
|
||||||
struct GNUNET_HashCode c_hash;
|
struct GNUNET_HashCode c_hash;
|
||||||
struct TALER_LinkDataPS ldp = {
|
struct TALER_CoinSpendPublicKeyP old_coin_pub;
|
||||||
.purpose.size = htonl (sizeof (ldp)),
|
|
||||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
|
|
||||||
.transfer_pub = *trans_pub
|
|
||||||
};
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv,
|
||||||
&ldp.old_coin_pub.eddsa_pub);
|
&old_coin_pub.eddsa_pub);
|
||||||
pub->rsa_public_key = rpub;
|
pub->rsa_public_key = rpub;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_planchet_prepare (pub,
|
TALER_planchet_prepare (pub,
|
||||||
@ -149,22 +144,20 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return GNUNET_SYSERR;
|
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 !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
|
TALER_wallet_link_verify (&pd.denom_pub_hash,
|
||||||
&ldp,
|
trans_pub,
|
||||||
&link_sig.eddsa_signature,
|
pd.coin_ev,
|
||||||
&ldp.old_coin_pub.eddsa_pub))
|
pd.coin_ev_size,
|
||||||
|
&old_coin_pub,
|
||||||
|
&link_sig))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
|
GNUNET_free (pd.coin_ev);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
GNUNET_free (pd.coin_ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
@ -457,9 +450,9 @@ TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
end = GNUNET_STRINGS_data_to_string (&coin_pub,
|
end = GNUNET_STRINGS_data_to_string (
|
||||||
sizeof (struct
|
&coin_pub,
|
||||||
TALER_CoinSpendPublicKeyP),
|
sizeof (struct TALER_CoinSpendPublicKeyP),
|
||||||
pub_str,
|
pub_str,
|
||||||
sizeof (pub_str));
|
sizeof (pub_str));
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
|
@ -391,30 +391,20 @@ TALER_EXCHANGE_refreshes_reveal (
|
|||||||
json_array_append_new (coin_evs,
|
json_array_append_new (coin_evs,
|
||||||
GNUNET_JSON_from_data (pd.coin_ev,
|
GNUNET_JSON_from_data (pd.coin_ev,
|
||||||
pd.coin_ev_size)));
|
pd.coin_ev_size)));
|
||||||
|
|
||||||
/* compute link signature */
|
|
||||||
{
|
{
|
||||||
struct TALER_CoinSpendSignatureP link_sig;
|
struct TALER_CoinSpendSignatureP link_sig;
|
||||||
struct TALER_LinkDataPS ldp;
|
|
||||||
|
|
||||||
ldp.purpose.size = htonl (sizeof (ldp));
|
TALER_wallet_link_sign (&denom_hash,
|
||||||
ldp.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK);
|
&transfer_pub,
|
||||||
ldp.h_denom_pub = denom_hash;
|
pd.coin_ev,
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&md->melted_coin.coin_priv.eddsa_priv,
|
|
||||||
&ldp.old_coin_pub.eddsa_pub);
|
|
||||||
ldp.transfer_pub = transfer_pub;
|
|
||||||
GNUNET_CRYPTO_hash (pd.coin_ev,
|
|
||||||
pd.coin_ev_size,
|
pd.coin_ev_size,
|
||||||
&ldp.coin_envelope_hash);
|
&md->melted_coin.coin_priv,
|
||||||
GNUNET_CRYPTO_eddsa_sign (&md->melted_coin.coin_priv.eddsa_priv,
|
&link_sig);
|
||||||
&ldp,
|
|
||||||
&link_sig.eddsa_signature);
|
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (link_sigs,
|
json_array_append_new (
|
||||||
GNUNET_JSON_from_data_auto (
|
link_sigs,
|
||||||
&link_sig)));
|
GNUNET_JSON_from_data_auto (&link_sig)));
|
||||||
}
|
}
|
||||||
|
|
||||||
GNUNET_free (pd.coin_ev);
|
GNUNET_free (pd.coin_ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ libtalerutil_la_SOURCES = \
|
|||||||
taler_error_codes.c \
|
taler_error_codes.c \
|
||||||
url.c \
|
url.c \
|
||||||
util.c \
|
util.c \
|
||||||
|
wallet_signatures.c \
|
||||||
yna.c \
|
yna.c \
|
||||||
os_installation.c
|
os_installation.c
|
||||||
|
|
||||||
|
80
src/util/wallet_signatures.c
Normal file
80
src/util/wallet_signatures.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2020 Taler Systems SA
|
||||||
|
|
||||||
|
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
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file secmod_signatures.c
|
||||||
|
* @brief Utility functions for Taler security module signatures
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include "taler_util.h"
|
||||||
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TALER_wallet_link_sign (const struct GNUNET_HashCode *h_denom_pub,
|
||||||
|
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||||
|
const void *coin_ev,
|
||||||
|
size_t coin_ev_size,
|
||||||
|
const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
|
||||||
|
struct TALER_CoinSpendSignatureP *coin_sig)
|
||||||
|
{
|
||||||
|
struct TALER_LinkDataPS ldp = {
|
||||||
|
.purpose.size = htonl (sizeof (ldp)),
|
||||||
|
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
|
||||||
|
.h_denom_pub = *h_denom_pub,
|
||||||
|
.transfer_pub = *transfer_pub
|
||||||
|
};
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_hash (coin_ev,
|
||||||
|
coin_ev_size,
|
||||||
|
&ldp.coin_envelope_hash);
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&old_coin_priv->eddsa_priv,
|
||||||
|
&ldp.old_coin_pub.eddsa_pub);
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
|
||||||
|
&ldp,
|
||||||
|
&coin_sig->eddsa_signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum GNUNET_GenericReturnValue
|
||||||
|
TALER_wallet_link_verify (
|
||||||
|
const struct GNUNET_HashCode *h_denom_pub,
|
||||||
|
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||||
|
const void *coin_ev,
|
||||||
|
size_t coin_ev_size,
|
||||||
|
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
||||||
|
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||||
|
{
|
||||||
|
struct TALER_LinkDataPS ldp = {
|
||||||
|
.purpose.size = htonl (sizeof (ldp)),
|
||||||
|
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
|
||||||
|
.h_denom_pub = *h_denom_pub,
|
||||||
|
.old_coin_pub = *old_coin_pub,
|
||||||
|
.transfer_pub = *transfer_pub
|
||||||
|
};
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_hash (coin_ev,
|
||||||
|
coin_ev_size,
|
||||||
|
&ldp.coin_envelope_hash);
|
||||||
|
return
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
|
||||||
|
&ldp,
|
||||||
|
&coin_sig->eddsa_signature,
|
||||||
|
&old_coin_pub->eddsa_pub);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end of wallet_signatures.c */
|
Loading…
Reference in New Issue
Block a user