Skip to content

Commit

Permalink
Improve set_partner_key handler
Browse files Browse the repository at this point in the history
  • Loading branch information
fbeutin-ledger committed Aug 7, 2023
1 parent e054003 commit 3c27baf
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 36 deletions.
9 changes: 8 additions & 1 deletion src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
bool parse_to_sized_buffer(uint8_t *in_buffer, uint16_t in_size, uint8_t size_of_lenght_field, buf_t *out, uint16_t *offset) {
if (*offset + size_of_lenght_field > in_size) {
// We can't even read the size
PRINTF("Failed to read the header sized %d, only %d bytes available\n",
size_of_lenght_field,
in_size);
return false;
}

Expand All @@ -20,13 +23,17 @@ bool parse_to_sized_buffer(uint8_t *in_buffer, uint16_t in_size, uint8_t size_of
} else if (size_of_lenght_field == 4) {
out->size = U4BE(in_buffer, *offset);
} else {
PRINTF("Unable to read a %d sized header\n", size_of_lenght_field);
return false;
}
*offset += size_of_lenght_field;


if (*offset + out->size > in_size) {
// Not enough bytes to read buffer size
PRINTF("Not enough remaining bytes to read. Total bytes %d, offset %d, hedaer advertizes %d bytes\n",
in_size,
*offset,
out->size);
return false;
}

Expand Down
79 changes: 44 additions & 35 deletions src/set_partner_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,69 +5,78 @@
#include "set_partner_key.h"
#include "swap_errors.h"
#include "globals.h"
#include "buffer.h"
#include "io.h"
#include "cx.h"

int set_partner_key(const command_t *cmd) {
static uint16_t parse_set_partner_key_command(const command_t *cmd, buf_t *partner_name, uint8_t **raw_pubkey) {
// data is serialized as
// 1 byte - partner name length L
// L bytes - partner name
// 65 bytes - uncompressed partner public key
if (cmd->data.size < 1) {
PRINTF("Error: Input buffer is too small\n");

return reply_error(INCORRECT_COMMAND_DATA);
uint16_t offset = 0;
if (!parse_to_sized_buffer(cmd->data.bytes, cmd->data.size, 1, partner_name, &offset)) {
PRINTF("Failed to read partner name from partner credentials\n");
return INCORRECT_COMMAND_DATA;
}

G_swap_ctx.partner.name_length = cmd->data.bytes[0];

if ((G_swap_ctx.partner.name_length < MIN_PARTNER_NAME_LENGHT) ||
(G_swap_ctx.partner.name_length > MAX_PARTNER_NAME_LENGHT)) {
if ((partner_name->size < MIN_PARTNER_NAME_LENGHT) || (partner_name->size > MAX_PARTNER_NAME_LENGHT)) {
PRINTF("Error: Partner name length should be in [%u, %u]\n",
MIN_PARTNER_NAME_LENGHT,
MAX_PARTNER_NAME_LENGHT);

return reply_error(INCORRECT_COMMAND_DATA);
return INCORRECT_COMMAND_DATA;
}

if (1 + G_swap_ctx.partner.name_length + UNCOMPRESSED_KEY_LENGTH != cmd->data.size) {
if (offset + UNCOMPRESSED_KEY_LENGTH != cmd->data.size) {
PRINTF("Error: Input buffer length doesn't match correct SET_PARTNER_KEY message\n");
return INCORRECT_COMMAND_DATA;
}
*raw_pubkey = cmd->data.bytes + offset;

return 0;
}

return reply_error(INCORRECT_COMMAND_DATA);
int set_partner_key(const command_t *cmd) {
// Use dedicated function to extract the partner name and public key
buf_t partner;
uint8_t *raw_pubkey;
uint16_t err = parse_set_partner_key_command(cmd, &partner, &raw_pubkey);
if (err != 0) {
return reply_error(err);
}

// The incoming partner name is NOT NULL terminated, so we use memcpy and
// manually NULL terminate the buffer
memset(G_swap_ctx.partner.name, 0, sizeof(G_swap_ctx.partner.name));
memcpy(G_swap_ctx.partner.name, cmd->data.bytes + 1, G_swap_ctx.partner.name_length);
memcpy(G_swap_ctx.partner.name, partner.bytes, partner.size);
G_swap_ctx.partner.name_length = partner.size;

// Create the verifying key from the raw public key. Curve used depends of the flow
cx_curve_t curve;
if (cmd->subcommand == SWAP) {
if (cx_ecfp_init_public_key_no_throw(CX_CURVE_SECP256K1,
cmd->data.bytes + 1 + G_swap_ctx.partner.name_length,
UNCOMPRESSED_KEY_LENGTH,
&(G_swap_ctx.partner.public_key)) != CX_OK) {
PRINTF("Error: cx_ecfp_init_public_key_no_throw\n");
return reply_error(INTERNAL_ERROR);
}
curve = CX_CURVE_SECP256K1;
} else {
curve = CX_CURVE_256R1;
}

if (cmd->subcommand == SELL || cmd->subcommand == FUND || cmd->subcommand == SWAP_NG || cmd->subcommand == SELL_NG || cmd->subcommand == FUND_NG) {
if (cx_ecfp_init_public_key_no_throw(CX_CURVE_256R1,
cmd->data.bytes + 1 + G_swap_ctx.partner.name_length,
UNCOMPRESSED_KEY_LENGTH,
&(G_swap_ctx.partner.public_key)) != CX_OK) {
PRINTF("Error: cx_ecfp_init_public_key_no_throw\n");
return reply_error(INTERNAL_ERROR);
}
if (cx_ecfp_init_public_key_no_throw(curve,
raw_pubkey,
UNCOMPRESSED_KEY_LENGTH,
&(G_swap_ctx.partner.public_key)) != CX_OK) {
PRINTF("Error: cx_ecfp_init_public_key_no_throw\n");
return reply_error(INTERNAL_ERROR);
}

cx_hash_sha256(cmd->data.bytes,
cmd->data.size,
G_swap_ctx.sha256_digest,
sizeof(G_swap_ctx.sha256_digest));
// Save the hash of the entire credentials to check that the Ledger key signed it later
if (cx_hash_sha256(cmd->data.bytes,
cmd->data.size,
G_swap_ctx.sha256_digest,
sizeof(G_swap_ctx.sha256_digest)) == 0) {
PRINTF("cx_hash_sha256 internal error\n");
return reply_error(INTERNAL_ERROR);
}

if (reply_success() < 0) {
PRINTF("Error: failed to send\n");

return -1;
}

Expand Down

0 comments on commit 3c27baf

Please sign in to comment.