Skip to content

Commit

Permalink
refactor destination types 2
Browse files Browse the repository at this point in the history
  • Loading branch information
janmazak committed Aug 10, 2022
1 parent 841c2fe commit 2c92c11
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 128 deletions.
51 changes: 28 additions & 23 deletions src/securityPolicy.c
Expand Up @@ -309,7 +309,7 @@ security_policy_t policyForSignTxInit(
uint16_t numRequiredSigners,
bool includeScriptDataHash,
bool includeNetworkId,
bool includeTotalCollateral,
bool includeTotalCollateral, // TODO add other babbage elements too and update the policy
uint16_t numReferenceInputs
)
{
Expand Down Expand Up @@ -404,24 +404,27 @@ security_policy_t policyForSignTxInput(sign_tx_signingmode_t txSigningMode)
DENY(); // should not be reached
}

// For each transaction (third-party) address output
// For each transaction output with third-party address
security_policy_t policyForSignTxOutputAddressBytes(
const tx_output_description_t* output,
sign_tx_signingmode_t txSigningMode,
const uint8_t* rawAddressBuffer, size_t rawAddressSize,
const uint8_t networkId, const uint32_t protocolMagic,
bool includeDatumHash, bool includeRefScript
const uint8_t networkId, const uint32_t protocolMagic
)
{
ASSERT(rawAddressSize < BUFFER_SIZE_PARANOIA);
ASSERT(rawAddressSize >= 1);
ASSERT(output->destination.type == DESTINATION_THIRD_PARTY);
const uint8_t* addressBuffer = output->destination.address.buffer;
const size_t addressSize = output->destination.address.size;

const address_type_t addressType = getAddressType(rawAddressBuffer[0]);
ASSERT(addressSize < BUFFER_SIZE_PARANOIA);
ASSERT(addressSize >= 1);

const address_type_t addressType = getAddressType(addressBuffer[0]);
{
// check address type and network identification
switch (addressType) {

case BYRON:
DENY_IF(extractProtocolMagic(rawAddressBuffer, rawAddressSize) != protocolMagic);
DENY_IF(extractProtocolMagic(addressBuffer, addressSize) != protocolMagic);
break;

case REWARD_KEY:
Expand All @@ -432,7 +435,7 @@ security_policy_t policyForSignTxOutputAddressBytes(

default: {
// shelley types allowed in output
const uint8_t addressNetworkId = getNetworkId(rawAddressBuffer[0]);
const uint8_t addressNetworkId = getNetworkId(addressBuffer[0]);
DENY_IF(addressNetworkId != networkId);
break;
}
Expand All @@ -443,31 +446,31 @@ security_policy_t policyForSignTxOutputAddressBytes(
switch (addressType) {

case BASE_PAYMENT_KEY_STAKE_KEY:
DENY_IF(rawAddressSize != 1 + ADDRESS_KEY_HASH_LENGTH + ADDRESS_KEY_HASH_LENGTH);
DENY_IF(addressSize != 1 + ADDRESS_KEY_HASH_LENGTH + ADDRESS_KEY_HASH_LENGTH);
break;
case BASE_PAYMENT_KEY_STAKE_SCRIPT:
DENY_IF(rawAddressSize != 1 + ADDRESS_KEY_HASH_LENGTH + SCRIPT_HASH_LENGTH);
DENY_IF(addressSize != 1 + ADDRESS_KEY_HASH_LENGTH + SCRIPT_HASH_LENGTH);
break;
case BASE_PAYMENT_SCRIPT_STAKE_KEY:
DENY_IF(rawAddressSize != 1 + SCRIPT_HASH_LENGTH + ADDRESS_KEY_HASH_LENGTH);
DENY_IF(addressSize != 1 + SCRIPT_HASH_LENGTH + ADDRESS_KEY_HASH_LENGTH);
break;
case BASE_PAYMENT_SCRIPT_STAKE_SCRIPT:
DENY_IF(rawAddressSize != 1 + SCRIPT_HASH_LENGTH + SCRIPT_HASH_LENGTH);
DENY_IF(addressSize != 1 + SCRIPT_HASH_LENGTH + SCRIPT_HASH_LENGTH);
break;

case ENTERPRISE_KEY:
DENY_IF(rawAddressSize != 1 + ADDRESS_KEY_HASH_LENGTH);
DENY_IF(addressSize != 1 + ADDRESS_KEY_HASH_LENGTH);
break;
case ENTERPRISE_SCRIPT:
DENY_IF(rawAddressSize != 1 + SCRIPT_HASH_LENGTH);
DENY_IF(addressSize != 1 + SCRIPT_HASH_LENGTH);
break;

default: // not meaningful or complicated to verify address length in the other cases
break;
}
}

if (includeDatumHash) {
if (output->includeDatum) {
// together with the above requirement on SPENDING_PATH,
// this forbids datum in change outputs entirely
DENY_UNLESS(allows_datum_hash(addressType));
Expand All @@ -494,7 +497,7 @@ security_policy_t policyForSignTxOutputAddressBytes(
case SIGN_TX_SIGNINGMODE_PLUTUS_TX:
// utxo on a Plutus script address without datum hash is unspendable
// but we can't DENY because it is valid for native scripts
WARN_IF(allows_datum_hash(addressType) && !includeDatumHash);
WARN_IF(allows_datum_hash(addressType) && !output->includeDatum);
// we always show third-party output addresses
SHOW();
break;
Expand All @@ -508,12 +511,14 @@ security_policy_t policyForSignTxOutputAddressBytes(

// For each output given by payment derivation path
security_policy_t policyForSignTxOutputAddressParams(
const tx_output_description_t* output,
sign_tx_signingmode_t txSigningMode,
const addressParams_t* params,
const uint8_t networkId, const uint32_t protocolMagic,
bool includeDatumHash, bool includeRefScript
const uint8_t networkId, const uint32_t protocolMagic
)
{
ASSERT(output->destination.type == DESTINATION_DEVICE_OWNED);
const addressParams_t* params = output->destination.params;

DENY_UNLESS(isValidAddressParams(params));

// only allow valid address types
Expand Down Expand Up @@ -549,7 +554,7 @@ security_policy_t policyForSignTxOutputAddressParams(
DENY_IF(violatesSingleAccountOrStoreIt(&params->spendingKeyPath));
}

if (includeDatumHash) {
if (output->includeDatum) {
// together with the above requirement on SPENDING_PATH,
// this forbids datum in change outputs entirely
DENY_UNLESS(allows_datum_hash(params->type));
Expand All @@ -570,7 +575,7 @@ security_policy_t policyForSignTxOutputAddressParams(
SHOW_UNLESS(is_standard_base_address(params));

// outputs (eUTXOs) with datum hash are not interchangeable
SHOW_IF(includeDatumHash); // can't happen for operator
SHOW_IF(output->includeDatum); // can't happen for operator

// it is safe to hide the remaining change outputs
ALLOW();
Expand Down
10 changes: 4 additions & 6 deletions src/securityPolicy.h
Expand Up @@ -48,16 +48,14 @@ security_policy_t policyForSignTxInit(
security_policy_t policyForSignTxInput(sign_tx_signingmode_t txSigningMode);

security_policy_t policyForSignTxOutputAddressBytes(
const tx_output_description_t* output,
sign_tx_signingmode_t txSigningMode,
const uint8_t* rawAddressBuffer, size_t rawAddressSize,
const uint8_t networkId, const uint32_t protocolMagic,
bool includeDatumHash, bool includeRefScript
const uint8_t networkId, const uint32_t protocolMagic
);
security_policy_t policyForSignTxOutputAddressParams(
const tx_output_description_t* output,
sign_tx_signingmode_t txSigningMode,
const addressParams_t* params,
const uint8_t networkId, const uint32_t protocolMagic,
bool includeDatumHash, bool includeRefScript
const uint8_t networkId, const uint32_t protocolMagic
);
security_policy_t policyForSignTxOutputDatumHash(
security_policy_t outputPolicy
Expand Down
78 changes: 39 additions & 39 deletions src/signTxOutput.c
Expand Up @@ -207,36 +207,34 @@ static void handleOutput_addressBytes()
{
output_context_t* subctx = accessSubcontext();
ASSERT(subctx->stateData.destination.type == DESTINATION_THIRD_PARTY);

tx_output_description_t output = {
.format = subctx->serializationFormat,
.destination = {
.type = DESTINATION_THIRD_PARTY,
.address = {
.buffer = subctx->stateData.destination.address.buffer,
.size = subctx->stateData.destination.address.size
}
},
.amount = subctx->stateData.adaAmount,
.numAssetGroups = subctx->numAssetGroups,
.includeDatum = subctx->includeDatum,
.includeRefScript = subctx->includeRefScript,
};

security_policy_t policy = policyForSignTxOutputAddressBytes(
&output,
commonTxData->txSigningMode,
subctx->stateData.destination.address.buffer, subctx->stateData.destination.address.size,
commonTxData->networkId, commonTxData->protocolMagic,
subctx->includeDatum, subctx->includeRefScript
commonTxData->networkId, commonTxData->protocolMagic
);
TRACE("Policy: %d", (int) policy);
ENSURE_NOT_DENIED(policy);

subctx->outputSecurityPolicy = policy;

{
// add to tx
tx_hash_builder_output txOut = {
.format = subctx->serializationFormat,
.addressBuffer = subctx->stateData.destination.address.buffer,
.addressSize = subctx->stateData.destination.address.size,
.amount = subctx->stateData.adaAmount,
.numAssetGroups = subctx->numAssetGroups,
.includeDatum = subctx->includeDatum,
.includeRefScript = subctx->includeRefScript,
};
// TODO rename to tx_output_descriptor_t and use also as argument for security policies?

txHashBuilder_addOutput_topLevelData(
&BODY_CTX->txHashBuilder,
&txOut
);
txHashBuilder_addOutput_topLevelData(&BODY_CTX->txHashBuilder, &output);
}

{
// select UI steps
switch (policy) {
Expand Down Expand Up @@ -315,15 +313,26 @@ static void handleOutput_addressParams()
{
output_context_t* subctx = accessSubcontext();
ASSERT(subctx->stateData.destination.type == DESTINATION_DEVICE_OWNED);

tx_output_description_t output = {
.format = subctx->serializationFormat,
.destination = {
.type = DESTINATION_DEVICE_OWNED,
.params = &subctx->stateData.destination.params
},
.amount = subctx->stateData.adaAmount,
.numAssetGroups = subctx->numAssetGroups,
.includeDatum = subctx->includeDatum,
.includeRefScript = subctx->includeRefScript,
};

security_policy_t policy = policyForSignTxOutputAddressParams(
&output,
commonTxData->txSigningMode,
&subctx->stateData.destination.params,
commonTxData->networkId, commonTxData->protocolMagic,
subctx->includeDatum, subctx->includeRefScript
commonTxData->networkId, commonTxData->protocolMagic
);
TRACE("Policy: %d", (int) policy);
ENSURE_NOT_DENIED(policy);

subctx->outputSecurityPolicy = policy;

{
Expand All @@ -337,21 +346,12 @@ static void handleOutput_addressParams()
ASSERT(addressSize > 0);
ASSERT(addressSize <= MAX_ADDRESS_SIZE);

// pass the derived address to tx hash builder
output.destination.type = DESTINATION_THIRD_PARTY;
output.destination.address.buffer = addressBuffer;
output.destination.address.size = addressSize;

tx_hash_builder_output txOut;

txOut.format = subctx->serializationFormat;
txOut.addressBuffer = addressBuffer;
txOut.addressSize = addressSize;
txOut.amount = subctx->stateData.adaAmount;
txOut.numAssetGroups = subctx->numAssetGroups;
txOut.includeDatum = subctx->includeDatum;
txOut.includeRefScript = subctx->includeRefScript;

txHashBuilder_addOutput_topLevelData(
&BODY_CTX->txHashBuilder,
&txOut
);
txHashBuilder_addOutput_topLevelData(&BODY_CTX->txHashBuilder, &output);
}

{
Expand Down
23 changes: 13 additions & 10 deletions src/txHashBuilder.c
Expand Up @@ -75,7 +75,7 @@ static void cbor_append_txInput(
}
}

static void cbor_append_txOutput_array(tx_hash_builder_t* builder, const tx_hash_builder_output* output)
static void cbor_append_txOutput_array(tx_hash_builder_t* builder, const tx_output_description_t* output)
{
ASSERT(output->format == ARRAY_LEGACY);

Expand All @@ -86,8 +86,10 @@ static void cbor_append_txOutput_array(tx_hash_builder_t* builder, const tx_hash
// ]
BUILDER_APPEND_CBOR(CBOR_TYPE_ARRAY, 2 + output->includeDatum);
{
BUILDER_APPEND_CBOR(CBOR_TYPE_BYTES, output->addressSize);
BUILDER_APPEND_DATA(output->addressBuffer, output->addressSize);
ASSERT(output->destination.type == DESTINATION_THIRD_PARTY);
ASSERT(output->destination.address.size < BUFFER_SIZE_PARANOIA);
BUILDER_APPEND_CBOR(CBOR_TYPE_BYTES, output->destination.address.size);
BUILDER_APPEND_DATA(output->destination.address.buffer, output->destination.address.size);
}

if (output->numAssetGroups == 0) {
Expand All @@ -109,7 +111,7 @@ static void cbor_append_txOutput_array(tx_hash_builder_t* builder, const tx_hash
}
}

static void cbor_append_txOutput_map(tx_hash_builder_t* builder, const tx_hash_builder_output* output)
static void cbor_append_txOutput_map(tx_hash_builder_t* builder, const tx_output_description_t* output)
{
ASSERT(output->format == MAP_BABBAGE);

Expand All @@ -128,9 +130,10 @@ static void cbor_append_txOutput_map(tx_hash_builder_t* builder, const tx_hash_b
{
BUILDER_APPEND_CBOR(CBOR_TYPE_UNSIGNED, TX_OUTPUT_KEY_ADDRESS);

ASSERT(output->addressSize < BUFFER_SIZE_PARANOIA);
BUILDER_APPEND_CBOR(CBOR_TYPE_BYTES, output->addressSize);
BUILDER_APPEND_DATA(output->addressBuffer, output->addressSize);
ASSERT(output->destination.type == DESTINATION_THIRD_PARTY);
ASSERT(output->destination.address.size < BUFFER_SIZE_PARANOIA);
BUILDER_APPEND_CBOR(CBOR_TYPE_BYTES, output->destination.address.size);
BUILDER_APPEND_DATA(output->destination.address.buffer, output->destination.address.size);
}
{
BUILDER_APPEND_CBOR(CBOR_TYPE_UNSIGNED, TX_OUTPUT_KEY_VALUE);
Expand All @@ -154,7 +157,7 @@ static void cbor_append_txOutput_map(tx_hash_builder_t* builder, const tx_hash_b
}
}

static void cbor_append_txOutput(tx_hash_builder_t* builder, const tx_hash_builder_output* output)
static void cbor_append_txOutput(tx_hash_builder_t* builder, const tx_output_description_t* output)
{
switch (output->format) {
case ARRAY_LEGACY:
Expand Down Expand Up @@ -370,7 +373,7 @@ void txHashBuilder_enterOutputs(tx_hash_builder_t* builder)

void txHashBuilder_addOutput_topLevelData(
tx_hash_builder_t* builder,
const tx_hash_builder_output* output
const tx_output_description_t* output
)
{
_TRACE(
Expand Down Expand Up @@ -1703,7 +1706,7 @@ static void txHashBuilder_assertCanLeaveNetworkId(tx_hash_builder_t* builder)

void txHashBuilder_addCollateralReturn(
tx_hash_builder_t* builder,
const tx_hash_builder_output* output
const tx_output_description_t* output
)
{
_TRACE("state = %d", builder->state);
Expand Down
26 changes: 20 additions & 6 deletions src/txHashBuilder.h
Expand Up @@ -161,15 +161,27 @@ typedef struct {

typedef struct {
tx_output_serialization_format_t format;
size_t addressSize;
const uint8_t* addressBuffer;

// consistent with tx_output_destination_t
// but only contains address buffer pointer instead of the actual buffer
// or address params pointer instead of actual params
struct {
tx_output_destination_type_t type;
union {
struct {
uint8_t* buffer;
size_t size;
} address;
addressParams_t* params;
};
} destination;

uint64_t amount;
uint16_t numAssetGroups;

bool includeDatum;
bool includeRefScript;
} tx_hash_builder_output; // TODO rename to "tx_hash_builder_output_init_data" or something like that?
} tx_output_description_t;

void txHashBuilder_init(
tx_hash_builder_t* builder,
Expand Down Expand Up @@ -198,7 +210,7 @@ void txHashBuilder_enterOutputs(tx_hash_builder_t* builder);

void txHashBuilder_addOutput_topLevelData(
tx_hash_builder_t* builder,
const tx_hash_builder_output* output
const tx_output_description_t* output
);

void txHashBuilder_addOutput_tokenGroup(
Expand Down Expand Up @@ -361,8 +373,10 @@ void txHashBuilder_addRequiredSigner(

void txHashBuilder_addNetworkId(tx_hash_builder_t* builder, uint8_t networkId);

void txHashBuilder_addCollateralReturn(tx_hash_builder_t* builder,
const tx_hash_builder_output* output);
void txHashBuilder_addCollateralReturn(
tx_hash_builder_t* builder,
const tx_output_description_t* output
);

void txHashBuilder_addCollateralReturn_tokenGroup(
tx_hash_builder_t* builder,
Expand Down

0 comments on commit 2c92c11

Please sign in to comment.