diff --git a/src_features/provideTxSimu/cmd_getTxSimulation.c b/src_features/provideTxSimu/cmd_getTxSimulation.c index 8fe8b43830..97200d3166 100644 --- a/src_features/provideTxSimu/cmd_getTxSimulation.c +++ b/src_features/provideTxSimu/cmd_getTxSimulation.c @@ -43,6 +43,19 @@ enum { TAG_DER_SIGNATURE = 0x15, }; +// This enum needs to be ordered the same way as the TAGGs above ! +enum { + BIT_STRUCTURE_TYPE, + BIT_STRUCTURE_VERSION, + BIT_CHAIN_ID, + BIT_TX_HASH, + BIT_W3C_NORMALIZED_RISK, + BIT_W3C_NORMALIZED_CATEGORY, + BIT_W3C_PROVIDER_MSG, + BIT_W3C_TINY_URL, + BIT_DER_SIGNATURE, +}; + // clang-format off static const char *const TX_SIMULATION_CATEGORY[CATEGORY_NB_MAX] = { "Raw signing detected", // CATEGORY_RAW_SIGNING @@ -305,6 +318,28 @@ static bool verify_signature(s_sig_ctx *sig_ctx) { return ret_code; } +/** + * @brief Verify the received fields + * + * Check the mandatory fields are present + * + * @param[in] rcv_bit indicates received fields + * @return whether it was successful + */ +static bool verify_fields(uint32_t rcv_bit) { + uint32_t expected_fields; + expected_fields = (1 << BIT_STRUCTURE_TYPE) | (1 << BIT_STRUCTURE_VERSION) | + (1 << BIT_CHAIN_ID) | (1 << BIT_TX_HASH) | (1 << BIT_W3C_NORMALIZED_RISK) | + (1 << BIT_W3C_NORMALIZED_CATEGORY) | (1 << BIT_W3C_TINY_URL) | + (1 << BIT_DER_SIGNATURE); + + if ((rcv_bit & expected_fields) != expected_fields) { + return false; + } + + return true; +} + /** * @brief Print the simulation parameters. * @@ -384,6 +419,7 @@ static uint16_t parse_tlv(const uint8_t *data, uint8_t length) { uint16_t sw = APDU_RESPONSE_INTERNAL_ERROR; uint32_t tag_start_off; s_sig_ctx sig_ctx = {0}; + uint32_t rcv_bit = 0; // Reset the structures explicit_bzero(&TX_SIMULATION, sizeof(tx_simulation_t)); @@ -408,30 +444,39 @@ static uint16_t parse_tlv(const uint8_t *data, uint8_t length) { switch (field_tag) { case TAG_STRUCTURE_TYPE: sw = parse_struct_type(data + offset, field_len); + rcv_bit |= (1 << BIT_STRUCTURE_TYPE); break; case TAG_STRUCTURE_VERSION: sw = parse_struct_version(data + offset, field_len); + rcv_bit |= (1 << BIT_STRUCTURE_VERSION); break; case TAG_CHAIN_ID: sw = parse_chain_id(data + offset, field_len); + rcv_bit |= (1 << BIT_CHAIN_ID); break; case TAG_TX_HASH: sw = parse_tx_hash(data + offset, field_len); + rcv_bit |= (1 << BIT_TX_HASH); break; case TAG_W3C_NORMALIZED_RISK: sw = parse_risk(data + offset, field_len); + rcv_bit |= (1 << BIT_W3C_NORMALIZED_RISK); break; case TAG_W3C_NORMALIZED_CATEGORY: sw = parse_category(data + offset, field_len); + rcv_bit |= (1 << BIT_W3C_NORMALIZED_CATEGORY); break; case TAG_W3C_PROVIDER_MSG: sw = parse_provider_msg(data + offset, field_len); + rcv_bit |= (1 << BIT_W3C_PROVIDER_MSG); break; case TAG_W3C_TINY_URL: sw = parse_tiny_url(data + offset, field_len); + rcv_bit |= (1 << BIT_W3C_TINY_URL); break; case TAG_DER_SIGNATURE: sw = parse_signature(data + offset, field_len, &sig_ctx); + rcv_bit |= (1 << BIT_DER_SIGNATURE); break; default: PRINTF("Skipping unknown tag: %d\n", field_tag); @@ -449,7 +494,10 @@ static uint16_t parse_tlv(const uint8_t *data, uint8_t length) { } } if (sw == APDU_RESPONSE_OK) { - if (verify_signature(&sig_ctx) == false) { + if (verify_fields(rcv_bit) == false) { + PRINTF("Missing fields!\n"); + sw = APDU_RESPONSE_INVALID_DATA; + } else if (verify_signature(&sig_ctx) == false) { PRINTF("Signature verification failed!\n"); sw = APDU_RESPONSE_INVALID_DATA; }