Skip to content

Commit

Permalink
poolregistration refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
janmazak committed Jan 11, 2021
1 parent d9a375f commit 110a182
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 53 deletions.
7 changes: 7 additions & 0 deletions src/cardano.h
Expand Up @@ -35,4 +35,11 @@ STATIC_ASSERT(LOVELACE_MAX_SUPPLY < LOVELACE_INVALID, "bad LOVELACE_INVALID");

#define TESTNET_NETWORK_ID 0


typedef enum {
DATA_DESCRIPTION_PATH = 1,
DATA_DESCRIPTION_HASH = 2,
} data_description_kind_t;


#endif
26 changes: 16 additions & 10 deletions src/securityPolicy.c
Expand Up @@ -373,22 +373,28 @@ security_policy_t policyForSignTxCertificateStaking(
PROMPT();
}

// for stake pool registration certificates
security_policy_t policyForSignTxCertificateStakePoolRegistration()
{
PROMPT_IF(true);
PROMPT();
}

security_policy_t policyForSignTxStakePoolRegistrationOwner(pool_owner_t* owner)
security_policy_t policyForSignTxStakePoolRegistrationOwner(
const sign_tx_usecase_t signTxUsecase,
const pool_owner_t* owner
)
{
switch (owner->ownerType) {
case SIGN_TX_POOL_OWNER_TYPE_KEY_HASH:
SHOW_IF(true);
break;
if (owner->descriptionKind == DATA_DESCRIPTION_PATH)
DENY_UNLESS(is_valid_stake_pool_owner_path(&owner->path));

switch(signTxUsecase) {
case SIGN_TX_USECASE_POOL_REGISTRATION_OWNER:
SHOW();

case SIGN_TX_POOL_OWNER_TYPE_PATH:
SHOW_IF(is_valid_stake_pool_owner_path(&owner->path));
break;
#ifdef POOL_OPERATOR_APP
case SIGN_TX_USECASE_POOL_REGISTRATION_OPERATOR:
DENY_UNLESS(owner->descriptionKind == DATA_DESCRIPTION_HASH);
SHOW();
#endif

default:
ASSERT(false);
Expand Down
6 changes: 4 additions & 2 deletions src/securityPolicy.h
Expand Up @@ -63,9 +63,11 @@ security_policy_t policyForSignTxCertificateStakePoolRetirement(
uint64_t epoch
);
#endif
security_policy_t policyForSignTxCertificateStakePoolRegistration(
security_policy_t policyForSignTxCertificateStakePoolRegistration();
security_policy_t policyForSignTxStakePoolRegistrationOwner(
const sign_tx_usecase_t signTxUsecase,
const pool_owner_t* owner
);
security_policy_t policyForSignTxStakePoolRegistrationOwner(pool_owner_t* owner);
security_policy_t policyForSignTxStakePoolRegistrationMetadata();
security_policy_t policyForSignTxStakePoolRegistrationNoMetadata();
security_policy_t policyForSignTxStakePoolRegistrationConfirm();
Expand Down
80 changes: 48 additions & 32 deletions src/signTxPoolRegistration.c
Expand Up @@ -130,36 +130,36 @@ static void handlePoolParams_ui_runStep()
UI_STEP(HANDLE_POOLPARAMS_STEP_DISPLAY_POOL_KEY_HASH) {
ui_displayHexBufferScreen(
"Pool ID",
subctx->poolParams.poolKeyHash, SIZEOF(subctx->poolParams.poolKeyHash),
subctx->stateData.poolParams.poolKeyHash, SIZEOF(subctx->stateData.poolParams.poolKeyHash),
this_fn
);
}
UI_STEP(HANDLE_POOLPARAMS_STEP_DISPLAY_PLEDGE) {
ui_displayAmountScreen(
"Pledge",
subctx->poolParams.pledge,
subctx->stateData.poolParams.pledge,
this_fn
);
}
UI_STEP(HANDLE_POOLPARAMS_STEP_DISPLAY_COST) {
ui_displayAmountScreen(
"Cost",
subctx->poolParams.cost,
subctx->stateData.poolParams.cost,
this_fn
);
}
UI_STEP(HANDLE_POOLPARAMS_STEP_DISPLAY_MARGIN) {
ui_displayMarginScreen(
subctx->poolParams.marginNumerator,
subctx->poolParams.marginDenominator,
subctx->stateData.poolParams.marginNumerator,
subctx->stateData.poolParams.marginDenominator,
this_fn
);
}
UI_STEP(HANDLE_POOLPARAMS_STEP_DISPLAY_REWARD_ACCOUNT) {
ui_displayAddressScreen(
"Reward account",
subctx->poolParams.rewardAccount,
SIZEOF(subctx->poolParams.rewardAccount),
subctx->stateData.poolParams.rewardAccount,
SIZEOF(subctx->stateData.poolParams.rewardAccount),
this_fn
);
}
Expand All @@ -183,7 +183,7 @@ static void signTxPoolRegistration_handlePoolParamsAPDU(uint8_t* wireDataBuffer,
subctx->currentOwner = 0;
subctx->currentRelay = 0;

explicit_bzero(&subctx->poolParams, SIZEOF(subctx->poolParams));
explicit_bzero(&subctx->stateData.poolParams, SIZEOF(subctx->stateData.poolParams));
}
{
// parse data
Expand All @@ -207,7 +207,7 @@ static void signTxPoolRegistration_handlePoolParamsAPDU(uint8_t* wireDataBuffer,
VALIDATE(SIZEOF(*wireHeader) == wireDataSize, ERR_INVALID_DATA);

{
pool_registration_params_t* p = &subctx->poolParams;
pool_registration_params_t* p = &subctx->stateData.poolParams;

TRACE_BUFFER(wireHeader->poolKeyHash, SIZEOF(wireHeader->poolKeyHash));
STATIC_ASSERT(SIZEOF(wireHeader->poolKeyHash) == SIZEOF(p->poolKeyHash), "wrong poolKeyHash size");
Expand Down Expand Up @@ -268,7 +268,7 @@ static void signTxPoolRegistration_handlePoolParamsAPDU(uint8_t* wireDataBuffer,
// Note: make sure that everything in subctx is initialized properly
txHashBuilder_addPoolRegistrationCertificate(
txHashBuilder,
&subctx->poolParams,
&subctx->stateData.poolParams,
subctx->numOwners, subctx->numRelays
);

Expand Down Expand Up @@ -306,14 +306,27 @@ static void handleOwner_ui_runStep()
UI_STEP_BEGIN(subctx->ui_step);

UI_STEP(HANDLE_OWNER_STEP_DISPLAY) {
ui_displayOwnerScreen(&subctx->owner, subctx->currentOwner, commonTxData->networkId, this_fn);
ui_displayOwnerScreen(&subctx->stateData.owner, subctx->currentOwner, commonTxData->networkId, this_fn);
}
UI_STEP(HANDLE_OWNER_STEP_RESPOND) {
respondSuccessEmptyMsg();

subctx->currentOwner++;
if (subctx->currentOwner == subctx->numOwners) {
VALIDATE(subctx->numOwnersGivenByPath == 1, ERR_INVALID_DATA);
switch (commonTxData->signTxUsecase) {
case SIGN_TX_USECASE_POOL_REGISTRATION_OWNER:
VALIDATE(subctx->numOwnersGivenByPath == 1, ERR_INVALID_DATA);
break;

#ifdef POOL_OPERATOR_APP
case SIGN_TX_USECASE_POOL_REGISTRATION_OPERATOR:
ASSERT(subctx->numOwnersGivenByPath <= 1);
break;
#endif

default:
ASSERT(false);
}

advanceState();
}
Expand All @@ -330,7 +343,9 @@ static void signTxPoolRegistration_handleOwnerAPDU(uint8_t* wireDataBuffer, size
ASSERT(wireDataSize < BUFFER_SIZE_PARANOIA);
}

explicit_bzero(&subctx->owner, SIZEOF(subctx->owner));
pool_owner_t* owner = &subctx->stateData.owner;

explicit_bzero(owner, SIZEOF(subctx->stateData.owner));

{
// parse data
Expand All @@ -339,21 +354,22 @@ static void signTxPoolRegistration_handleOwnerAPDU(uint8_t* wireDataBuffer, size
read_view_t view = make_read_view(wireDataBuffer, wireDataBuffer + wireDataSize);

VALIDATE(view_remainingSize(&view) >= 1, ERR_INVALID_DATA);
subctx->owner.ownerType = parse_u1be(&view);
switch (subctx->owner.ownerType) {
owner->descriptionKind = parse_u1be(&view);
switch (owner->descriptionKind) {

case SIGN_TX_POOL_OWNER_TYPE_KEY_HASH:
case DATA_DESCRIPTION_HASH:
VALIDATE(view_remainingSize(&view) == ADDRESS_KEY_HASH_LENGTH, ERR_INVALID_DATA);
STATIC_ASSERT(SIZEOF(subctx->owner.keyHash) == ADDRESS_KEY_HASH_LENGTH, "wrong owner.keyHash size");
os_memmove(subctx->owner.keyHash, VIEW_REMAINING_TO_TUPLE_BUF_SIZE(&view));
TRACE_BUFFER(subctx->owner.keyHash, SIZEOF(subctx->owner.keyHash));
STATIC_ASSERT(SIZEOF(owner->keyHash) == ADDRESS_KEY_HASH_LENGTH, "wrong owner.keyHash size");
os_memmove(owner->keyHash, VIEW_REMAINING_TO_TUPLE_BUF_SIZE(&view));
TRACE_BUFFER(owner->keyHash, SIZEOF(owner->keyHash));
break;

case SIGN_TX_POOL_OWNER_TYPE_PATH:
view_skipBytes(&view, bip44_parseFromWire(&subctx->owner.path, VIEW_REMAINING_TO_TUPLE_BUF_SIZE(&view)));
case DATA_DESCRIPTION_PATH:
view_skipBytes(&view, bip44_parseFromWire(&owner->path, VIEW_REMAINING_TO_TUPLE_BUF_SIZE(&view)));
// further validation of the path in security policy below
TRACE("Owner given by path:");
BIP44_PRINTF(&subctx->owner.path);
BIP44_PRINTF(&owner->path);
PRINTF("\n");
VALIDATE(view_remainingSize(&view) == 0, ERR_INVALID_DATA);

subctx->numOwnersGivenByPath++;
Expand All @@ -366,15 +382,15 @@ static void signTxPoolRegistration_handleOwnerAPDU(uint8_t* wireDataBuffer, size
}
}

security_policy_t policy = policyForSignTxStakePoolRegistrationOwner(&subctx->owner);
security_policy_t policy = policyForSignTxStakePoolRegistrationOwner(commonTxData->signTxUsecase, owner);
TRACE("Policy: %d", (int) policy);
ENSURE_NOT_DENIED(policy);

{
// compute key hash if needed
if (subctx->owner.ownerType == SIGN_TX_POOL_OWNER_TYPE_PATH) {
write_view_t view = make_write_view(subctx->owner.keyHash, subctx->owner.keyHash + SIZEOF(subctx->owner.keyHash));
view_appendPublicKeyHash(&view, &subctx->owner.path);
if (owner->descriptionKind == DATA_DESCRIPTION_PATH) {
write_view_t view = make_write_view(owner->keyHash, owner->keyHash + SIZEOF(owner->keyHash));
view_appendPublicKeyHash(&view, &owner->path);
}
}

Expand All @@ -383,7 +399,7 @@ static void signTxPoolRegistration_handleOwnerAPDU(uint8_t* wireDataBuffer, size
TRACE("Adding owner to tx hash");
txHashBuilder_addPoolRegistrationCertificate_addOwner(
txHashBuilder,
subctx->owner.keyHash, SIZEOF(subctx->owner.keyHash)
owner->keyHash, SIZEOF(owner->keyHash)
);
TRACE();
}
Expand Down Expand Up @@ -606,7 +622,7 @@ static void handleMetadata_ui_runStep()
TRACE("UI step %d", subctx->ui_step);
ui_callback_fn_t* this_fn = handleMetadata_ui_runStep;

pool_metadata_t* md = &subctx->metadata;
pool_metadata_t* md = &subctx->stateData.metadata;

UI_STEP_BEGIN(subctx->ui_step);

Expand Down Expand Up @@ -684,13 +700,13 @@ static void signTxPoolRegistration_handlePoolMetadataAPDU(uint8_t* wireDataBuffe
ASSERT(wireDataSize < BUFFER_SIZE_PARANOIA);
}

explicit_bzero(&subctx->metadata, SIZEOF(subctx->metadata));
explicit_bzero(&subctx->stateData.metadata, SIZEOF(subctx->stateData.metadata));

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

pool_metadata_t* md = &subctx->metadata;
pool_metadata_t* md = &subctx->stateData.metadata;

read_view_t view = make_read_view(wireDataBuffer, wireDataBuffer + wireDataSize);

Expand Down Expand Up @@ -745,8 +761,8 @@ static void signTxPoolRegistration_handlePoolMetadataAPDU(uint8_t* wireDataBuffe
TRACE("Adding metadata hash to tx hash");
txHashBuilder_addPoolRegistrationCertificate_addPoolMetadata(
txHashBuilder,
subctx->metadata.url, subctx->metadata.urlSize,
subctx->metadata.hash, SIZEOF(subctx->metadata.hash)
subctx->stateData.metadata.url, subctx->stateData.metadata.urlSize,
subctx->stateData.metadata.hash, SIZEOF(subctx->stateData.metadata.hash)
);
}

Expand Down
10 changes: 6 additions & 4 deletions src/signTxPoolRegistration.h
Expand Up @@ -32,7 +32,7 @@ typedef struct {
} pool_metadata_t;

typedef struct {
uint8_t ownerType;
uint8_t descriptionKind;
uint8_t keyHash[ADDRESS_KEY_HASH_LENGTH];
bip44_path_t path;
} pool_owner_t;
Expand All @@ -47,14 +47,16 @@ typedef struct {
uint16_t numOwners;
uint16_t numRelays;

pool_registration_params_t poolParams;

union {
struct {
pool_registration_params_t poolParams;
};
pool_owner_t owner;
pool_metadata_t metadata;
};
} stateData;
} pool_registration_context_t;


void signTxPoolRegistration_init();

bool signTxPoolRegistration_isValidInstruction(uint8_t p2);
Expand Down
10 changes: 5 additions & 5 deletions src/uiScreens.c
Expand Up @@ -298,13 +298,13 @@ void ui_displayOwnerScreen(
ASSERT(isValidNetworkId(networkId));
ASSERT(ownerIndex < POOL_MAX_OWNERS);

switch (owner->ownerType) {
switch (owner->descriptionKind) {

case SIGN_TX_POOL_OWNER_TYPE_KEY_HASH:
case DATA_DESCRIPTION_HASH:
ASSERT(SIZEOF(owner->keyHash) == ADDRESS_KEY_HASH_LENGTH);
break;

case SIGN_TX_POOL_OWNER_TYPE_PATH:
case DATA_DESCRIPTION_PATH:
ASSERT(bip44_isValidStakingKeyPath(&owner->path));
break;

Expand All @@ -316,7 +316,7 @@ void ui_displayOwnerScreen(
// we display the owner as bech32-encoded reward address for his staking key
uint8_t rewardAddress[REWARD_ACCOUNT_SIZE];
{
if (owner->ownerType == SIGN_TX_POOL_OWNER_TYPE_PATH) {
if (owner->descriptionKind == DATA_DESCRIPTION_PATH) {
addressParams_t rewardAddressParams = {
.type = REWARD,
.networkId = networkId,
Expand Down Expand Up @@ -347,7 +347,7 @@ void ui_displayOwnerScreen(
explicit_bzero(ownerDescription, SIZEOF(ownerDescription));
size_t descLen = 0; // owner description length

if (owner->ownerType == SIGN_TX_POOL_OWNER_TYPE_PATH) {
if (owner->descriptionKind == DATA_DESCRIPTION_PATH) {
descLen += bip44_printToStr(&owner->path, ownerDescription, SIZEOF(ownerDescription));
}

Expand Down

0 comments on commit 110a182

Please sign in to comment.