Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fbeutin-ledger committed Dec 17, 2024
1 parent 2c18817 commit b9d7c7f
Show file tree
Hide file tree
Showing 24 changed files with 1,260 additions and 953 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ ifdef TEST_PUBLIC_KEY
DEFINES += TEST_PUBLIC_KEY
endif

ifdef TRUSTED_NAME_TEST_KEY
$(info [INFO] TRUSTED_NAME_TEST_KEY enabled)
DEFINES += TRUSTED_NAME_TEST_KEY
endif

DEFINES += SDK_TLV_PARSER


########################################
# Protobuf files regeneration #
Expand Down
7 changes: 4 additions & 3 deletions ledger_app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ sdk = "C"
devices = ["nanos", "nanox", "nanos+", "stax", "flex"]

[use_cases]
use_test_keys = "TEST_PUBLIC_KEY=1"
dbg_use_test_keys = "DEBUG=1 TEST_PUBLIC_KEY=1"
testing_dbg_use_test_keys = "DEBUG=1 TESTING=1 TEST_PUBLIC_KEY=1"
use_test_keys = "TEST_PUBLIC_KEY=1 TRUSTED_NAME_TEST_KEY=1"
dbg_use_test_keys = "DEBUG=1 TEST_PUBLIC_KEY=1 TRUSTED_NAME_TEST_KEY=1"
full_replay = "DEBUG=1 TESTING=1 TEST_PUBLIC_KEY=1 TRUSTED_NAME_TEST_KEY=1 FIXED_TLV_CHALLENGE=1"
dbg_full_replay = "DEBUG=1 TESTING=1 TEST_PUBLIC_KEY=1 TRUSTED_NAME_TEST_KEY=1 FIXED_TLV_CHALLENGE=1"

[tests]
pytest_directory = "./test/python/"
16 changes: 13 additions & 3 deletions src/apdu_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ static uint16_t check_instruction(uint8_t instruction, uint8_t subcommand) {
return INVALID_INSTRUCTION;
}

if (instruction == GET_CHALLENGE && (subcommand != SWAP && subcommand != SWAP_NG)) {
PRINTF("Instruction GET_CHALLENGE is only for SWAP based flows\n");
return INVALID_INSTRUCTION;
}

if (instruction == SEND_TRUSTED_NAME_DESCRIPTOR && (subcommand != SWAP && subcommand != SWAP_NG)) {
PRINTF("Instruction SEND_TRUSTED_NAME_DESCRIPTOR is only for SWAP based flows\n");
return INVALID_INSTRUCTION;
}

if ((instruction == CHECK_REFUND_ADDRESS_AND_DISPLAY ||
instruction == CHECK_REFUND_ADDRESS_NO_DISPLAY) &&
(subcommand != SWAP && subcommand != SWAP_NG)) {
Expand Down Expand Up @@ -108,7 +118,7 @@ static uint16_t check_instruction(uint8_t instruction, uint8_t subcommand) {
check_subcommand_context = true;
break;
case SEND_TRUSTED_NAME_DESCRIPTOR:
check_current_state = CHALLENGE_SENT;
check_current_state = SIGNATURE_CHECKED;
check_subcommand_context = true;
break;
case CHECK_PAYOUT_ADDRESS:
Expand Down Expand Up @@ -229,8 +239,8 @@ uint16_t check_apdu_validity(uint8_t *apdu, size_t apdu_length, command_t *comma
return WRONG_P2_EXTENSION;
}
// Split reception is only for PROCESS_TRANSACTION_RESPONSE_COMMAND
if (instruction != PROCESS_TRANSACTION_RESPONSE_COMMAND && !is_whole_apdu) {
PRINTF("Extension %d refused, only allowed for PROCESS_TRANSACTION_RESPONSE instruction\n",
if (instruction != PROCESS_TRANSACTION_RESPONSE_COMMAND && instruction != SEND_TRUSTED_NAME_DESCRIPTOR && !is_whole_apdu) {
PRINTF("Extension %d refused, only allowed for PROCESS_TRANSACTION_RESPONSE and SEND_TRUSTED_NAME_DESCRIPTOR instruction\n",
extension);
return WRONG_P2_EXTENSION;
}
Expand Down
5 changes: 5 additions & 0 deletions src/buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ typedef struct buf_s {
uint16_t size;
} buf_t;

typedef struct cbuf_s {
const uint8_t *bytes;
uint16_t size;
} cbuf_t;

bool parse_to_sized_buffer(uint8_t *in_buffer,
uint16_t in_size,
uint8_t size_of_length_field,
Expand Down
6 changes: 2 additions & 4 deletions src/get_challenge_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ static uint32_t challenge;
* Generate a new challenge from the Random Number Generator
*/
void roll_challenge(void) {
#ifdef HAVE_TRUSTED_NAME_TEST
#ifdef FIXED_TLV_CHALLENGE
challenge = 0xdeadbeef;
#else
challenge = cx_rng_u32();
Expand Down Expand Up @@ -49,7 +49,5 @@ int get_challenge_handler(void) {
return -1;
}

G_swap_ctx.state = CHALLENGE_SENT;

return 0;
}
}
43 changes: 43 additions & 0 deletions src/pki.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "os.h"
#include "cx.h"
#include "pki.h"
#include "os_pki.h"

int check_signature_with_pki(uint8_t *buffer,
uint8_t buffer_length,
uint8_t expected_key_usage,
const cbuf_t *signature) {
uint8_t key_usage = 0;
size_t certificate_name_len = 0;
uint8_t certificate_name[CERTIFICATE_TRUSTED_NAME_MAXLEN] = {0};
cx_ecfp_384_public_key_t public_key = {0};

bolos_err_t bolos_err;
bolos_err = os_pki_get_info(&key_usage, certificate_name, &certificate_name_len, &public_key);
if (bolos_err != 0x0000) {
PRINTF("Error %x while getting PKI certificate info\n", bolos_err);
return -1;
}

if (key_usage != expected_key_usage) {
PRINTF("Wrong usage certificate %d, expected %d\n", key_usage, expected_key_usage);
return -1;
}

PRINTF("Certificate '%s' loaded with success\n", certificate_name);

// Checking the signature with PKI
if (!os_pki_verify(buffer, buffer_length, (uint8_t *)signature->bytes, signature->size)) {
PRINTF("Error, '%.*H' is not a signature of buffer '%.*H' by the PKI key '%.*H'\n",
signature->size,
signature->bytes,
buffer_length,
buffer,
sizeof(public_key),
&public_key);
return -1;
}

PRINTF("Signature verified successfully\n");
return 0;
}
14 changes: 14 additions & 0 deletions src/pki.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <cx.h>
#include <os.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

#include "buf.h"

int check_signature_with_pki(uint8_t *buffer,
uint8_t buffer_length,
uint8_t expected_key_usage,
const cbuf_t *signature);
2 changes: 0 additions & 2 deletions src/states.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ typedef enum {
PROVIDER_CHECKED,
TRANSACTION_RECEIVED,
SIGNATURE_CHECKED,
CHALLENGE_SENT,
TRUSTED_NAME_DESCRIPTOR_RECEIVED,
PAYOUT_ADDRESS_CHECKED,
ALL_ADDRESSES_CHECKED,
WAITING_USER_VALIDATION,
Expand Down
6 changes: 6 additions & 0 deletions src/swap_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ typedef enum {
AMOUNT_FORMATTING_FAILED = 0x6A8B,
APPLICATION_NOT_INSTALLED = 0x6A8C,
WRONG_EXTRA_ID_OR_EXTRA_DATA = 0x6A8D,
WRONG_CHALLENGE = 0x6A8E,
WRONG_TLV_CONTENT = 0x6A8F,
MISSING_TLV_CONTENT = 0x6A90,
WRONG_TLV_FORMAT = 0x6A91,
WRONG_TLV_KEY_ID = 0x6A92,
WRONG_TLV_SIGNATURE = 0x6A93,
CLASS_NOT_SUPPORTED = 0x6E00,
MALFORMED_APDU = 0x6E01,
INVALID_DATA_LENGTH = 0x6E02,
Expand Down
41 changes: 41 additions & 0 deletions src/tlv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <cx.h>
#include <os.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

#include "buf.h"

// List of TLV tags recognized by the Exchange application
#define TLV_TAGS \
X(STRUCT_TYPE, 0x01) \
X(STRUCT_VERSION, 0x02) \
X(TRUSTED_NAME_TYPE, 0x70) \
X(TRUSTED_NAME_SOURCE, 0x71) \
X(TRUSTED_NAME, 0x20) \
X(CHAIN_ID, 0x23) \
X(ADDRESS, 0x22) \
X(SOURCE_CONTRACT, 0x73) \
X(CHALLENGE, 0x12) \
X(SIGNER_KEY_ID, 0x13) \
X(SIGNER_ALGO, 0x14) \
X(SIGNATURE, 0x15)

// Parsed TLV data
typedef struct tlv_out_s {
uint8_t struct_version;
uint8_t struct_type;
cbuf_t token_account;
cbuf_t owner;
cbuf_t spl_token;
uint64_t chain_id;
uint32_t challenge;
uint8_t name_type;
uint8_t name_source;

uint8_t key_id;
uint8_t sig_algorithm;
cbuf_t input_sig;
} tlv_out_t;
Loading

0 comments on commit b9d7c7f

Please sign in to comment.