Commit ab5a6c06 authored by xpetrak2's avatar xpetrak2
Browse files

Initial trading ID change of basic trade made safe

A peer is allowed to change their ID during TS_COMMITTMENT
parent 76276155
...@@ -284,9 +284,10 @@ int create_trade_execution(trade_execution_t **execution, const trade_t *trade) ...@@ -284,9 +284,10 @@ int create_trade_execution(trade_execution_t **execution, const trade_t *trade)
static int create_trade_execution_basic(trade_execution_basic_t **basic, static int create_trade_execution_basic(trade_execution_basic_t **basic,
const trade_t *trade) const trade_t *trade)
{ {
trade_execution_basic_t *exec_data; trade_execution_basic_t *exec_data;
char *script; char new_id_hex[2 * PUBLIC_KEY_SIZE + 1];
trade_basic_t *trade_data; char *script;
trade_basic_t *trade_data;
trade_data = (trade_basic_t *) trade->data; trade_data = (trade_basic_t *) trade->data;
...@@ -302,6 +303,14 @@ static int create_trade_execution_basic(trade_execution_basic_t **basic, ...@@ -302,6 +303,14 @@ static int create_trade_execution_basic(trade_execution_basic_t **basic,
memcpy(exec_data->commitment, memcpy(exec_data->commitment,
trade_data->my_commitment, trade_data->my_commitment,
SHA3_256_SIZE); SHA3_256_SIZE);
sodium_bin2hex(new_id_hex,
sizeof(new_id_hex),
trade->my_identity->keypair.public_key,
PUBLIC_KEY_SIZE);
sign_message(new_id_hex,
trade->order->owner.me->keypair.secret_key,
exec_data->idsig);
break; break;
case TS_KEY_AND_COMMITTED_EXCHANGE: case TS_KEY_AND_COMMITTED_EXCHANGE:
memcpy(exec_data->pubkey, memcpy(exec_data->pubkey,
......
...@@ -890,24 +890,22 @@ static int process_trade_execution(const trade_execution_t *trade_execution, ...@@ -890,24 +890,22 @@ static int process_trade_execution(const trade_execution_t *trade_execution,
const unsigned char *sender_id, const unsigned char *sender_id,
global_state_t *global_state) global_state_t *global_state)
{ {
/* counterparty's identifier must remain the same, unless this is int ret;
* the trade acceptance */
if (memcmp(trade->cp_identifier, sender_id, PUBLIC_KEY_SIZE)) { if ((ret = trade_execution_verify(trade_execution, trade, sender_id))) {
if (trade->step != TS_PROPOSAL) { log_debug("process_trade_execution - received incorrect "
log_debug("process_trade_execution - received " "trade.execution");
"trade.execution from a wrong peer"); /* if the trade should be aborted */
return 0; if (ret == 1) {
linkedlist_delete_safely(trade->node, trade_clear);
} }
memcpy(trade->cp_identifier, sender_id, PUBLIC_KEY_SIZE);
}
if (memcmp(trade->order->id, trade_execution->order, SHA3_256_SIZE)) {
log_debug("process_trade_execution - counterparty's "
"trade.execution refering to a different order");
linkedlist_delete_safely(trade->node, trade_clear);
return 0; return 0;
} }
if (trade_update(trade, execution_step, trade_execution->data)) { if (trade_update(trade,
execution_step,
trade_execution->data,
sender_id)) {
log_debug("process_trade_execution - received incorrect trade " log_debug("process_trade_execution - received incorrect trade "
"data"); "data");
linkedlist_delete_safely(trade->node, trade_clear); linkedlist_delete_safely(trade->node, trade_clear);
...@@ -1003,7 +1001,7 @@ static int process_trade_proposal(const trade_proposal_t *trade_proposal, ...@@ -1003,7 +1001,7 @@ static int process_trade_proposal(const trade_proposal_t *trade_proposal,
return 1; return 1;
} }
trade_update(trade, TS_PROPOSAL, trade_proposal); trade_update(trade, TS_PROPOSAL, trade_proposal, sender_id);
trade->step = trade_step_get_next(trade); trade->step = trade_step_get_next(trade);
......
...@@ -189,15 +189,22 @@ trade_t *trade_find(const linkedlist_t *trades, ...@@ -189,15 +189,22 @@ trade_t *trade_find(const linkedlist_t *trades,
* @param trade Trade to be updated. * @param trade Trade to be updated.
* @param next_step Next step of a trade. * @param next_step Next step of a trade.
* @param data Next step's data. * @param data Next step's data.
* @param sender_id The data received from this id.
* *
* @return 0 Successfully updated. * @return 0 Successfully updated.
* @return 1 Incorrect data. * @return 1 Incorrect data.
*/ */
int trade_update(trade_t *trade, enum trade_step next_step, const void *data) int trade_update(trade_t *trade,
enum trade_step next_step,
const void *data,
const unsigned char *sender_id)
{ {
switch (trade->type) { switch (trade->type) {
case TT_BASIC: case TT_BASIC:
return trade_basic_update(trade, next_step, data); return trade_basic_update(trade,
next_step,
data,
sender_id);
} }
return 1; return 1;
...@@ -224,6 +231,31 @@ void trade_execution_delete(trade_execution_t *trade_execution, ...@@ -224,6 +231,31 @@ void trade_execution_delete(trade_execution_t *trade_execution,
free(trade_execution); free(trade_execution);
} }
/**
* Verify trade.execution of a trade.
*
* @param execution trade.execution to be verified.
* @param trade trade.execution for this trade.
* @param sender_id trade.execution received from this id.
*
* @return 0 trade.execution is legit.
* @return 1 trade.execution is not legit and the trade
* should be aborted.
* @return 2 trade.execution is not legit but the trade
* does not need to be aborted.
*/
int trade_execution_verify(const trade_execution_t *execution,
const trade_t *trade,
const unsigned char *sender_id)
{
switch (trade->type) {
case TT_BASIC:
return trade_execution_basic_verify(execution,
trade,
sender_id);
}
}
/** /**
* Initialize trade.proposal of a trade. * Initialize trade.proposal of a trade.
* *
......
...@@ -109,11 +109,17 @@ trade_t *trade_find(const linkedlist_t *trades, ...@@ -109,11 +109,17 @@ trade_t *trade_find(const linkedlist_t *trades,
const void *attribute, const void *attribute,
int (*cmp_func) (const trade_t *trade, int (*cmp_func) (const trade_t *trade,
const void *attribute)); const void *attribute));
int trade_update(trade_t *trade, enum trade_step next_step, const void *data); int trade_update(trade_t *trade,
enum trade_step next_step,
const void *data,
const unsigned char *sender_id);
void trade_execution_delete(trade_execution_t *data, void trade_execution_delete(trade_execution_t *data,
enum trade_type type, enum trade_type type,
enum trade_step step); enum trade_step step);
int trade_execution_verify(const trade_execution_t *execution,
const trade_t *trade,
const unsigned char *sender_id);
void trade_proposal_init(trade_proposal_t *trade_proposal, void trade_proposal_init(trade_proposal_t *trade_proposal,
const trade_t *trade); const trade_t *trade);
......
...@@ -185,13 +185,15 @@ static int trade_basic_save(const trade_t *trade, const char *trades_dir) ...@@ -185,13 +185,15 @@ static int trade_basic_save(const trade_t *trade, const char *trades_dir)
* @param trade The trade. * @param trade The trade.
* @param next_step Next step of a trade. * @param next_step Next step of a trade.
* @param data The next step's data. * @param data The next step's data.
* @param sender_id The data received from this id.
* *
* @return 0 Successfully updated. * @return 0 Successfully updated.
* @return 1 Incorrect input data. * @return 1 Incorrect input data.
*/ */
int trade_basic_update(trade_t *trade, int trade_basic_update(trade_t *trade,
enum trade_step next_step, enum trade_step next_step,
const void *data) const void *data,
const unsigned char *sender_id)
{ {
enum trade_step cur_step; enum trade_step cur_step;
trade_execution_basic_t *execution; trade_execution_basic_t *execution;
...@@ -217,6 +219,9 @@ int trade_basic_update(trade_t *trade, ...@@ -217,6 +219,9 @@ int trade_basic_update(trade_t *trade,
memcpy(trade_data->cp_commitment, memcpy(trade_data->cp_commitment,
execution->commitment, execution->commitment,
SHA3_256_SIZE); SHA3_256_SIZE);
memcpy(trade->cp_identifier,
sender_id,
PUBLIC_KEY_SIZE);
break; break;
case TS_KEY_AND_COMMITTED_EXCHANGE: case TS_KEY_AND_COMMITTED_EXCHANGE:
memcpy(trade->cp_pubkey, memcpy(trade->cp_pubkey,
...@@ -292,8 +297,62 @@ void trade_execution_basic_delete(trade_execution_basic_t *execution, ...@@ -292,8 +297,62 @@ void trade_execution_basic_delete(trade_execution_basic_t *execution,
step == TS_KEY_AND_COMMITTED_EXCHANGE) { step == TS_KEY_AND_COMMITTED_EXCHANGE) {
if (execution->script) { if (execution->script) {
free(execution->script); free(execution->script);
execution->script = NULL;
}
}
}
/**
* Verify trade.execution of a basic trade.
*
* @param execution trade.execution to be verified.
* @param trade trade.execution for this trade.
* @param sender_id trade.execution received from this id.
*
* @return 0 trade.execution is legit.
* @return 1 trade.execution is not legit and the trade
* should be aborted.
* @return 2 trade.execution is not legit but the trade
* does not need to be aborted.
*/
int trade_execution_basic_verify(const trade_execution_t *execution,
const trade_t *trade,
const unsigned char *sender_id)
{
const trade_execution_basic_t *exec_data;
char new_id_hex[2 * PUBLIC_KEY_SIZE + 1];
exec_data = (trade_execution_basic_t *) execution->data;
/* counterparty's identifier must remain the same, unless this is
* the trade acceptance */
if (memcmp(trade->cp_identifier, sender_id, PUBLIC_KEY_SIZE)) {
if (trade->step != TS_PROPOSAL) {
log_debug("trade_execution_basic_verify - received "
"trade.execution from a wrong peer");
return 1;
}
sodium_bin2hex(new_id_hex,
sizeof(new_id_hex),
sender_id,
PUBLIC_KEY_SIZE);
if (verify_signature(new_id_hex,
trade->cp_identifier,
exec_data->idsig)) {
log_debug("trade_execution_basic_verify - received "
"trade.execution from a wrong peer");
/* possible MITM attempt */
return 2;
} }
} }
if (memcmp(trade->order->id, execution->order, SHA3_256_SIZE)) {
log_debug("trade_execution_basic_verify - counterparty's "
"trade.execution referring to a different order");
return 1;
}
return 0;
} }
/** /**
......
...@@ -55,6 +55,9 @@ typedef struct s_trade_execution_basic { ...@@ -55,6 +55,9 @@ typedef struct s_trade_execution_basic {
unsigned char committed[TRADE_BASIC_COMMITTED_SIZE]; unsigned char committed[TRADE_BASIC_COMMITTED_SIZE];
/** Double hash of the secret 'x' from the first trading script. */ /** Double hash of the secret 'x' from the first trading script. */
unsigned char hx[RIPEMD_160_SIZE]; unsigned char hx[RIPEMD_160_SIZE];
/** Signature of the trade identifier, signed by the order's
* identity. */
unsigned char idsig[SIGNATURE_SIZE];
/** Trading public key. */ /** Trading public key. */
unsigned char pubkey[PUBLIC_KEY_SIZE]; unsigned char pubkey[PUBLIC_KEY_SIZE];
/** Trading script. */ /** Trading script. */
...@@ -64,12 +67,16 @@ typedef struct s_trade_execution_basic { ...@@ -64,12 +67,16 @@ typedef struct s_trade_execution_basic {
void trade_basic_cancel(trade_t *trade); void trade_basic_cancel(trade_t *trade);
void trade_basic_clear(trade_basic_t *data); void trade_basic_clear(trade_basic_t *data);
void trade_basic_init_data(trade_basic_t *data); void trade_basic_init_data(trade_basic_t *data);
int trade_basic_update(trade_t *trade, int trade_basic_update(trade_t *trade,
enum trade_step next_step, enum trade_step next_step,
const void *data); const void *data,
const unsigned char *sender_id);
void trade_execution_basic_delete(trade_execution_basic_t *execution, void trade_execution_basic_delete(trade_execution_basic_t *execution,
enum trade_step step); enum trade_step step);
int trade_execution_basic_verify(const trade_execution_t *execution,
const trade_t *trade,
const unsigned char *sender_id);
void trade_proposal_basic_init(trade_proposal_t *trade_proposal, void trade_proposal_basic_init(trade_proposal_t *trade_proposal,
const trade_basic_t *trade_data); const trade_basic_t *trade_data);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment