Skip to content

Commit

Permalink
add validity interval start
Browse files Browse the repository at this point in the history
  • Loading branch information
janmazak committed Jan 27, 2021
1 parent 9275f8e commit 19ca2d4
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 29 deletions.
5 changes: 5 additions & 0 deletions src/securityPolicy.c
Expand Up @@ -421,6 +421,11 @@ security_policy_t policyForSignTxMetadata()
SHOW_IF(true);
}

security_policy_t policyForSignTxValidityIntervalStart()
{
SHOW_IF(true); // TODO use SHOW() in operator app
}

security_policy_t policyForSignTxConfirm()
{
PROMPT_IF(true);
Expand Down
2 changes: 2 additions & 0 deletions src/securityPolicy.h
Expand Up @@ -74,6 +74,8 @@ security_policy_t policyForSignTxWithdrawal();

security_policy_t policyForSignTxMetadata();

security_policy_t policyForSignTxValidityIntervalStart();

security_policy_t policyForSignTxWitness(
bool isSigningPoolRegistrationAsOwner,
const bip44_path_t* pathSpec
Expand Down
164 changes: 150 additions & 14 deletions src/signTx.c
Expand Up @@ -15,8 +15,8 @@
#include "securityPolicy.h"

enum {
SIGN_TX_METADATA_NO = 1,
SIGN_TX_METADATA_YES = 2
SIGN_TX_INCLUDED_NO = 1,
SIGN_TX_INCLUDED_YES = 2
};

enum {
Expand Down Expand Up @@ -59,16 +59,23 @@ static inline void advanceStage()
break;

case SIGN_STAGE_FEE:
// we should have received fee
ASSERT(ctx->feeReceived);

ctx->stage = SIGN_STAGE_TTL;
break;

if (ctx->includeTtl) {
// wait for TTL APDU
break;
}

// intentional fallthrough

case SIGN_STAGE_TTL:
// we should have received ttl
ASSERT(ctx->ttlReceived);
if (ctx->includeTtl)
ASSERT(ctx->ttlReceived);

ctx->stage = SIGN_STAGE_CERTIFICATES;

if (ctx->numCertificates > 0) {
txHashBuilder_enterCertificates(&ctx->txHashBuilder);
break;
Expand Down Expand Up @@ -102,6 +109,21 @@ static inline void advanceStage()
// intentional fallthrough

case SIGN_STAGE_METADATA:
if (ctx->includeMetadata)
ASSERT(ctx->metadataReceived);

ctx->stage = SIGN_STAGE_VALIDITY_INTERVAL;

if (ctx->includeValidityIntervalStart) {
break;
}

// intentional fallthrough

case SIGN_STAGE_VALIDITY_INTERVAL:
if (ctx->includeValidityIntervalStart)
ASSERT(ctx->validityIntervalStartReceived);

ctx->stage = SIGN_STAGE_CONFIRM;
break;

Expand Down Expand Up @@ -166,7 +188,7 @@ static inline void checkForFinishedSubmachines()
TRACE();
ASSERT(ctx->currentOutput < ctx->numOutputs);
ctx->stage = SIGN_STAGE_OUTPUTS;

ctx->currentOutput++;
if (ctx->currentOutput == ctx->numOutputs) {
advanceStage();
Expand Down Expand Up @@ -257,6 +279,8 @@ static void signTx_handleInitAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_t wi
// initialization
ctx->feeReceived = false;
ctx->ttlReceived = false;
ctx->metadataReceived = false;
ctx->validityIntervalStartReceived = false;

ctx->currentInput = 0;
ctx->currentOutput = 0;
Expand All @@ -274,7 +298,9 @@ static void signTx_handleInitAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_t wi
uint8_t networkId;
uint8_t protocolMagic[4];

uint8_t includeTtl;
uint8_t includeMetadata;
uint8_t includeValidityIntervalStart;
uint8_t isSigningPoolRegistrationAsOwner;

uint8_t numInputs[4];
Expand All @@ -295,19 +321,45 @@ static void signTx_handleInitAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_t wi
ctx->commonTxData.protocolMagic = u4be_read(wireHeader->protocolMagic);
TRACE("protocol magic %d", ctx->commonTxData.protocolMagic);

switch (wireHeader->includeTtl) {
case SIGN_TX_INCLUDED_YES:
ctx->includeTtl = true;
break;

case SIGN_TX_INCLUDED_NO:
ctx->includeTtl = false;
break;

default:
THROW(ERR_INVALID_DATA);
}

switch (wireHeader->includeMetadata) {
case SIGN_TX_METADATA_YES:
case SIGN_TX_INCLUDED_YES:
ctx->includeMetadata = true;
break;

case SIGN_TX_METADATA_NO:
case SIGN_TX_INCLUDED_NO:
ctx->includeMetadata = false;
break;

default:
THROW(ERR_INVALID_DATA);
}

switch (wireHeader->includeValidityIntervalStart) {
case SIGN_TX_INCLUDED_YES:
ctx->includeValidityIntervalStart = true;
break;

case SIGN_TX_INCLUDED_NO:
ctx->includeValidityIntervalStart = false;
break;

default:
THROW(ERR_INVALID_DATA);
}

switch (wireHeader->isSigningPoolRegistrationAsOwner) {
case SIGN_TX_POOL_REGISTRATION_YES:
ctx->commonTxData.isSigningPoolRegistrationAsOwner = true;
Expand Down Expand Up @@ -378,7 +430,9 @@ static void signTx_handleInitAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_t wi
ctx->numOutputs,
ctx->numCertificates,
ctx->numWithdrawals,
ctx->includeMetadata
ctx->includeTtl,
ctx->includeMetadata,
ctx->includeValidityIntervalStart
);

security_policy_t policy = policyForSignTxInit(
Expand Down Expand Up @@ -606,6 +660,7 @@ static void signTx_handleTtl_ui_runStep()

UI_STEP(HANDLE_TTL_STEP_DISPLAY) {
char ttlString[50];
// TODO just display it as a plain uint64, the same as validity interval start
str_formatTtl(ctx->stageData.ttl, ttlString, SIZEOF(ttlString));
ui_displayPaginatedText(
"Transaction TTL",
Expand All @@ -625,6 +680,7 @@ static void signTx_handleTtlAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_t wir
{
// sanity checks
CHECK_STAGE(SIGN_STAGE_TTL);
ASSERT(ctx->includeTtl == true);

VALIDATE(p2 == P2_UNUSED, ERR_INVALID_REQUEST_PARAMETERS);
ASSERT(wireDataSize < BUFFER_SIZE_PARANOIA);
Expand Down Expand Up @@ -1087,7 +1143,9 @@ static void signTx_handleMetadataAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_
TRACE_BUFFER(wireDataBuffer, wireDataSize);

VALIDATE(wireDataSize == METADATA_HASH_LENGTH, ERR_INVALID_DATA);
STATIC_ASSERT(SIZEOF(ctx->stageData.metadata.metadataHash) == METADATA_HASH_LENGTH, "inconsistent metadata hash length");
os_memmove(ctx->stageData.metadata.metadataHash, wireDataBuffer, SIZEOF(ctx->stageData.metadata.metadataHash));
ctx->metadataReceived = true;
}

security_policy_t policy = policyForSignTxMetadata();
Expand Down Expand Up @@ -1119,10 +1177,87 @@ static void signTx_handleMetadataAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_
signTx_handleMetadata_ui_runStep();
}

// ============================== VALIDITY INTERVAL START ==============================

enum {
HANDLE_VALIDITY_INTERVAL_STEP_DISPLAY = 900,
HANDLE_VALIDITY_INTERVAL_STEP_RESPOND,
HANDLE_VALIDITY_INTERVAL_STEP_INVALID,
};

static void signTx_handleValidityInterval_ui_runStep()
{
TRACE("UI step %d", ctx->ui_step);
ui_callback_fn_t* this_fn = signTx_handleValidityInterval_ui_runStep;

UI_STEP_BEGIN(ctx->ui_step);

UI_STEP(HANDLE_VALIDITY_INTERVAL_STEP_DISPLAY) {
ui_displayUint64Screen(
"Validity interval start",
ctx->stageData.validityIntervalStart,
this_fn
);
}
UI_STEP(HANDLE_VALIDITY_INTERVAL_STEP_RESPOND) {
respondSuccessEmptyMsg();
advanceStage();
}
UI_STEP_END(HANDLE_VALIDITY_INTERVAL_STEP_INVALID);
}

static void signTx_handleValidityIntervalAPDU(uint8_t p2, uint8_t* wireDataBuffer, size_t wireDataSize)
{
{
// sanity checks
CHECK_STAGE(SIGN_STAGE_VALIDITY_INTERVAL);
ASSERT(ctx->includeValidityIntervalStart == true);

VALIDATE(p2 == P2_UNUSED, ERR_INVALID_REQUEST_PARAMETERS);
ASSERT(wireDataSize < BUFFER_SIZE_PARANOIA);
}

{
// parse data
TRACE_BUFFER(wireDataBuffer, wireDataSize);

VALIDATE(wireDataSize == 8, ERR_INVALID_DATA);
ctx->stageData.validityIntervalStart = u8be_read(wireDataBuffer);
ctx->validityIntervalStartReceived = true;
}

security_policy_t policy = policyForSignTxValidityIntervalStart();
TRACE("Policy: %d", (int) policy);
ENSURE_NOT_DENIED(policy);

{
// select UI step
switch (policy) {
# define CASE(POLICY, UI_STEP) case POLICY: {ctx->ui_step=UI_STEP; break;}
CASE(POLICY_SHOW_BEFORE_RESPONSE, HANDLE_VALIDITY_INTERVAL_STEP_DISPLAY);
CASE(POLICY_ALLOW_WITHOUT_PROMPT, HANDLE_VALIDITY_INTERVAL_STEP_RESPOND);
# undef CASE
default:
THROW(ERR_NOT_IMPLEMENTED);
}
}

{
TRACE("Adding validity interval start to tx hash");
txHashBuilder_addValidityIntervalStart(
&ctx->txHashBuilder,
ctx->stageData.validityIntervalStart
);
TRACE();
}

signTx_handleValidityInterval_ui_runStep();
}

// ============================== CONFIRM ==============================

enum {
HANDLE_CONFIRM_STEP_FINAL_CONFIRM = 900,
HANDLE_CONFIRM_STEP_FINAL_CONFIRM = 1000,
HANDLE_CONFIRM_STEP_RESPOND,
HANDLE_CONFIRM_STEP_INVALID,
};
Expand Down Expand Up @@ -1199,7 +1334,7 @@ static void signTx_handleConfirmAPDU(uint8_t p2, uint8_t* wireDataBuffer MARK_UN
// ============================== WITNESS ==============================

enum {
HANDLE_WITNESS_STEP_WARNING = 1000,
HANDLE_WITNESS_STEP_WARNING = 1100,
HANDLE_WITNESS_STEP_DISPLAY,
HANDLE_WITNESS_STEP_CONFIRM,
HANDLE_WITNESS_STEP_RESPOND,
Expand Down Expand Up @@ -1324,8 +1459,9 @@ static subhandler_fn_t* lookup_subhandler(uint8_t p1)
CASE(0x06, signTx_handleCertificateAPDU);
CASE(0x07, signTx_handleWithdrawalAPDU);
CASE(0x08, signTx_handleMetadataAPDU);
CASE(0x09, signTx_handleConfirmAPDU);
CASE(0x0a, signTx_handleWitnessAPDU);
CASE(0x09, signTx_handleValidityIntervalAPDU);
CASE(0x0a, signTx_handleConfirmAPDU);
CASE(0x0f, signTx_handleWitnessAPDU);
DEFAULT(NULL)
# undef CASE
# undef DEFAULT
Expand Down
14 changes: 11 additions & 3 deletions src/signTx.h
Expand Up @@ -22,8 +22,9 @@ typedef enum {
SIGN_STAGE_CERTIFICATES_POOL = 30, // pool registration certificate sub-machine
SIGN_STAGE_WITHDRAWALS = 31,
SIGN_STAGE_METADATA = 32,
SIGN_STAGE_CONFIRM = 33,
SIGN_STAGE_WITNESSES = 34,
SIGN_STAGE_VALIDITY_INTERVAL = 33,
SIGN_STAGE_CONFIRM = 34,
SIGN_STAGE_WITNESSES = 35,
} sign_tx_stage_t;

enum {
Expand Down Expand Up @@ -68,19 +69,25 @@ typedef struct {

uint16_t numInputs;
uint16_t numOutputs;
bool includeTtl;
uint16_t numCertificates;
uint16_t numWithdrawals; // reward withdrawals
uint16_t numWitnesses;
bool includeMetadata;
bool includeValidityIntervalStart;
uint16_t numWitnesses;

uint16_t currentInput;
uint16_t currentOutput;
uint16_t currentCertificate;
uint16_t currentWithdrawal;
uint16_t currentWitness;

// TODO add js tests for missing ttl and inclusion of validity interval start
// TODO display ttl with pershing routine, also validity interval start, but only on mainnet?
bool feeReceived;
bool ttlReceived;
bool metadataReceived;
bool validityIntervalStartReceived;

tx_hash_builder_t txHashBuilder;
uint8_t txHash[TX_HASH_LENGTH];
Expand All @@ -93,6 +100,7 @@ typedef struct {
sign_tx_certificate_data_t certificate;
sign_tx_withdrawal_data_t withdrawal;
sign_tx_metadata_data_t metadata;
uint64_t validityIntervalStart;
sign_tx_witness_data_t witness;
} stageData;

Expand Down

0 comments on commit 19ca2d4

Please sign in to comment.