Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #95

Merged
merged 6 commits into from
Sep 15, 2023
Merged

Dev #95

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/Makefile.version
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ APPVERSION_M=2
# This is the `spec_version` field of `Runtime`
APPVERSION_N=35
# This is the patch version of this release
APPVERSION_P=11
APPVERSION_P=12
12 changes: 9 additions & 3 deletions app/src/apdu_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ __Z_INLINE void handle_getversion(__Z_UNUSED volatile uint32_t *flags, volatile
}

__Z_INLINE uint8_t extractHRP(uint32_t rx, uint32_t offset) {
uint8_t hrp_len = 0;
if (rx < offset + 1) {
THROW(APDU_CODE_DATA_INVALID);
}
Expand All @@ -77,10 +78,15 @@ __Z_INLINE uint8_t extractHRP(uint32_t rx, uint32_t offset) {
memcpy(bech32_hrp, G_io_apdu_buffer + offset + 1, bech32_hrp_len);
bech32_hrp[bech32_hrp_len] = 0; // zero terminate

return bech32_hrp_len;
hrp_len = bech32_hrp_len;
return hrp_len;
}

__Z_INLINE void extractHDPath(uint32_t rx, uint32_t offset) {
if (rx < offset + 1) {
THROW(APDU_CODE_DATA_INVALID);
}

if ((rx - offset) < sizeof(uint32_t) * HDPATH_LEN_DEFAULT) {
THROW(APDU_CODE_WRONG_LENGTH);
}
Expand Down Expand Up @@ -110,8 +116,8 @@ static void extractHDPath_HRP(uint32_t rx, uint32_t offset) {

// Check if HRP was sent
if ((rx - offset) > sizeof(uint32_t) * HDPATH_LEN_DEFAULT) {
extractHRP(rx, offset + sizeof(uint32_t) * HDPATH_LEN_DEFAULT);
encoding = checkChainConfig(hdPath[1], bech32_hrp, bech32_hrp_len);
uint8_t hrp_bech32_len = extractHRP(rx, offset + sizeof(uint32_t) * HDPATH_LEN_DEFAULT);
encoding = checkChainConfig(hdPath[1], bech32_hrp, hrp_bech32_len);
if (encoding == UNSUPPORTED) {
ZEMU_LOGF(50, "Chain config not supported for: %s\n", bech32_hrp)
THROW(APDU_CODE_COMMAND_NOT_ALLOWED);
Expand Down
7 changes: 7 additions & 0 deletions app/src/cbor/cbor_parser_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ parser_error_t parser_mapCborError(CborError err) {
}

static parser_error_t cbor_check_optFields(CborValue *data, Cbor_container *container) {
if (data == NULL || container == NULL) {
return parser_unexpected_value;
}
int key;
for (size_t i = 0; i < container->n_field; i++) {

Expand Down Expand Up @@ -67,6 +70,10 @@ static parser_error_t cbor_check_optFields(CborValue *data, Cbor_container *cont
}

static parser_error_t cbor_check_screen(CborValue *data, Cbor_container *container) {
if (data == NULL || container == NULL) {
return parser_unexpected_value;
}

int screen_key;
//check title Key
PARSER_ASSERT_OR_ERROR(cbor_value_is_integer(data), parser_unexpected_type)
Expand Down
14 changes: 3 additions & 11 deletions app/src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ uint32_t hdPath[HDPATH_LEN_DEFAULT];

uint8_t bech32_hrp_len;
char bech32_hrp[MAX_BECH32_HRP_LEN + 1];
address_encoding_e encoding;
address_encoding_e encoding = BECH32_COSMOS;

#include "cx.h"

Expand Down Expand Up @@ -73,15 +73,7 @@ static zxerr_t crypto_extractUncompressedPublicKey(uint8_t *pubKey, uint16_t pub
__Z_INLINE zxerr_t compressPubkey(const uint8_t *pubkey, uint16_t pubkeyLen, uint8_t *output, uint16_t outputLen) {
if (pubkey == NULL || output == NULL ||
pubkeyLen != PK_LEN_SECP256K1_UNCOMPRESSED || outputLen < PK_LEN_SECP256K1) {
return zxerr_unknown;
}

// Format pubkey
for (int i = 0; i < 32; i++) {
output[i] = pubkey[64 - i];
}
if ((pubkey[32] & 1) != 0) {
output[31] |= 0x80;
return zxerr_invalid_crypto_settings;
}

MEMCPY(output, pubkey, PK_LEN_SECP256K1);
Expand Down Expand Up @@ -194,7 +186,7 @@ zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t buffer_len, uint16_t *addrR
case BECH32_COSMOS: {
// Hash it
cx_hash_sha256(buffer, PK_LEN_SECP256K1, hashed1_pk, CX_SHA256_SIZE);
uint8_t hashed2_pk[CX_RIPEMD160_SIZE];
uint8_t hashed2_pk[CX_RIPEMD160_SIZE] = {0};
ripemd160_32(hashed2_pk, hashed1_pk);
CHECK_ZXERR(bech32EncodeFromBytes(addr, buffer_len - PK_LEN_SECP256K1, bech32_hrp, hashed2_pk, CX_RIPEMD160_SIZE, 1, BECH32_ENCODING_BECH32))
break;
Expand Down
2 changes: 0 additions & 2 deletions app/src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ extern char bech32_hrp[MAX_BECH32_HRP_LEN + 1];
extern uint8_t bech32_hrp_len;
extern address_encoding_e encoding;

void crypto_set_hrp(char *p);

zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen);

zxerr_t crypto_sign(uint8_t *signature, uint16_t signatureMaxlen, uint16_t *signatureLen);
Expand Down
88 changes: 60 additions & 28 deletions app/src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,75 +90,85 @@ parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_item
return tx_display_numItems(num_items);
}

__Z_INLINE bool_t parser_areEqual(uint16_t tokenIdx, const char *expected) {
__Z_INLINE bool parser_areEqual(uint16_t tokenIdx, const char *expected) {
if (parser_tx_obj.tx_json.json.tokens[tokenIdx].type != JSMN_STRING) {
return bool_false;
return false;
}

int32_t len = parser_tx_obj.tx_json.json.tokens[tokenIdx].end - parser_tx_obj.tx_json.json.tokens[tokenIdx].start;
if (len < 0) {
return bool_false;
return false;
}

if (strlen(expected) != (size_t) len) {
return bool_false;
return false;
}

const char *p = parser_tx_obj.tx_json.tx + parser_tx_obj.tx_json.json.tokens[tokenIdx].start;
for (int32_t i = 0; i < len; i++) {
if (expected[i] != *(p + i)) {
return bool_false;
return false;
}
}

return bool_true;
return true;
}

__Z_INLINE bool_t parser_isAmount(char *key) {
__Z_INLINE bool parser_isAmount(char *key) {
if (strcmp(key, "fee/amount") == 0) {
return bool_true;
return true;
ftheirs marked this conversation as resolved.
Show resolved Hide resolved
}

if (strcmp(key, "msgs/inputs/coins") == 0) {
return bool_true;
return true;
}

if (strcmp(key, "msgs/outputs/coins") == 0) {
return bool_true;
return true;
}

if (strcmp(key, "msgs/value/inputs/coins") == 0) {
return bool_true;
return true;
}

if (strcmp(key, "msgs/value/outputs/coins") == 0) {
return bool_true;
return true;
}

if (strcmp(key, "msgs/value/amount") == 0) {
return bool_true;
return true;
}

if (strcmp(key, "tip/amount") == 0) {
return bool_true;
return true;
}

return bool_false;
return false;
}

__Z_INLINE bool_t is_default_denom_base(const char *denom, uint8_t denom_len) {
if (tx_is_expert_mode()) {
return false;
__Z_INLINE parser_error_t is_default_denom_base(const char *denom, uint8_t denom_len, bool *is_default) {
if (is_default == NULL) {
return parser_unexpected_value;
}

bool is_expert_or_default = false;
CHECK_PARSER_ERR(tx_is_expert_mode_or_not_default_chainid(&is_expert_or_default))
if (is_expert_or_default) {
*is_default = false;
return parser_ok;
}

if (strlen(COIN_DEFAULT_DENOM_BASE) != denom_len) {
return bool_false;
*is_default = false;
return parser_ok;
}

if (memcmp(denom, COIN_DEFAULT_DENOM_BASE, denom_len) == 0)
return bool_true;
if (memcmp(denom, COIN_DEFAULT_DENOM_BASE, denom_len) == 0) {
*is_default = true;
return parser_ok;
}

return bool_false;
return parser_ok;
}

__Z_INLINE parser_error_t parser_formatAmountItem(uint16_t amountToken,
Expand Down Expand Up @@ -199,10 +209,11 @@ __Z_INLINE parser_error_t parser_formatAmountItem(uint16_t amountToken,
MEMZERO(outVal, outValLen);
MEMZERO(bufferUI, sizeof(bufferUI));

const char *amountPtr = parser_tx_obj.tx_json.tx + parser_tx_obj.tx_json.json.tokens[amountToken + 2].start;
if (parser_tx_obj.tx_json.json.tokens[amountToken + 2].start < 0) {
if (parser_tx_obj.tx_json.json.tokens[amountToken + 2].start < 0 ||
parser_tx_obj.tx_json.json.tokens[amountToken + 4].start < 0) {
return parser_unexpected_buffer_end;
}
const char *amountPtr = parser_tx_obj.tx_json.tx + parser_tx_obj.tx_json.json.tokens[amountToken + 2].start;

const int32_t amountLen = parser_tx_obj.tx_json.json.tokens[amountToken + 2].end -
parser_tx_obj.tx_json.json.tokens[amountToken + 2].start;
Expand All @@ -228,7 +239,9 @@ __Z_INLINE parser_error_t parser_formatAmountItem(uint16_t amountToken,

snprintf(bufferUI, sizeof(bufferUI), "%s ", tmpAmount);
// If denomination has been recognized format and replace
if (is_default_denom_base(denomPtr, denomLen)) {
bool is_default =false;
CHECK_PARSER_ERR(is_default_denom_base(denomPtr, denomLen, &is_default))
if (is_default) {
if (fpstr_to_str(bufferUI, sizeof(bufferUI), tmpAmount, COIN_DEFAULT_DENOM_FACTOR) != 0) {
return parser_unexpected_error;
}
Expand All @@ -253,7 +266,7 @@ __Z_INLINE parser_error_t parser_formatAmount(uint16_t amountToken,
}

uint8_t totalPages = 0;
bool_t showItemSet = false;
uint8_t showItemSet = 0;
uint8_t showPageIdx = pageIdx;
uint16_t showItemTokenIdx = 0;

Expand All @@ -274,7 +287,7 @@ __Z_INLINE parser_error_t parser_formatAmount(uint16_t amountToken,

if (!showItemSet) {
if (showPageIdx < subpagesCount) {
showItemSet = true;
showItemSet = 1;
showItemTokenIdx = itemTokenIdx;
ZEMU_LOGF(200, "[formatAmount] [%d] [SET] TokenIdx %d - PageIdx: %d", i, showItemTokenIdx,
showPageIdx)
Expand Down Expand Up @@ -329,6 +342,9 @@ __Z_INLINE parser_error_t parser_screenPrint(const parser_context_t *ctx,

//Translate output, cpy to tmp to assure it ends in \0
MEMZERO(tmp, tmp_len);
if(container->screen.contentPtr == NULL) {
return parser_unexpected_value;
}
MEMCPY(tmp, container->screen.contentPtr, container->screen.contentLen);
CHECK_PARSER_ERR(tx_display_translation(out, sizeof(out), tmp,container->screen.contentLen))

Expand All @@ -344,6 +360,9 @@ __Z_INLINE parser_error_t parser_screenPrint(const parser_context_t *ctx,
}

MEMZERO(ctx->tx_obj->tx_text.tmpBuffer, sizeof(ctx->tx_obj->tx_text.tmpBuffer));
if(container->screen.titlePtr == NULL) {
return parser_unexpected_value;
}
MEMCPY(tmp, container->screen.titlePtr, container->screen.titleLen);
MEMCPY(tmp + container->screen.titleLen,": ",2);
MEMCPY(tmp + container->screen.titleLen + 2, out, sizeof(out) - container->screen.titleLen -2);
Expand All @@ -354,6 +373,9 @@ __Z_INLINE parser_error_t parser_screenPrint(const parser_context_t *ctx,

//Normal print case - Prepare title
char key[MAX_TITLE_SIZE + 2] = {0};
if(container->screen.titlePtr == NULL) {
return parser_unexpected_value;
}
MEMCPY(key, container->screen.titlePtr, container->screen.titleLen);
for (uint8_t i = 0; i < container->screen.indent; i++) {
z_str3join(key, sizeof(key), SCREEN_INDENT, "");
Expand Down Expand Up @@ -438,6 +460,16 @@ __Z_INLINE parser_error_t parser_getTextualItem(const parser_context_t *ctx,
container.screen.expert = false;
CHECK_PARSER_ERR(parser_getScreenInfo(ctx, &container, displayIdx))

// title and content can be Null depending on the screen for chain id they cant be null
if (container.screen.titlePtr != NULL && container.screen.contentPtr != NULL) {
if (!strncmp(container.screen.titlePtr, "Chain id", container.screen.titleLen)){
if(!strncmp(container.screen.contentPtr, "0", container.screen.contentLen) ||
!strncmp(container.screen.contentPtr, "1", container.screen.contentLen)) {
return parser_unexpected_chain;
}
}
}

if (!app_mode_expert()) {
CHECK_PARSER_ERR(parser_getNextNonExpert(ctx, &container, displayIdx))
}
Expand Down Expand Up @@ -467,7 +499,7 @@ __Z_INLINE parser_error_t parser_getJsonItem(const parser_context_t *ctx,
return parser_unexpected_number_items;
}

if (displayIdx < 0 || displayIdx >= numItems) {
if (displayIdx >= numItems) {
return parser_display_idx_out_of_range;
}

Expand Down
Loading
Loading