Skip to content

Commit

Permalink
Remove optional block PB when adding new optional blocks
Browse files Browse the repository at this point in the history
Let tr31_opt_block_alloc() remove all instances of optional block PB
when adding a new optional block. ANSI X9.143:2021, 6.3.6, states that
the padding block will always be the last optional block in the header.
Therefore, if optional block PB was previously added for whatever
reason, for example via an export header by tr31-tool, it should be
removed before adding further optional blocks. However, if no further
optional blocks are added, an existing optional block PB is
intentionally preserved specifically to allow the caller, or tr31-tool
using an export header, to specify exact content for optional block PB.
  • Loading branch information
leonlynch committed Oct 28, 2023
1 parent acab36f commit 3527f97
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -671,11 +671,21 @@ if(TARGET tr31-tool AND BUILD_TESTING)
PASS_REGULAR_EXPRESSION "D1840S0ES00N0400CT000405D6020002F0MIICLjCCAdSgAwIBAgIIGDrdWBxuNpAwCgYIKoZIzj0EAwIwMTEXMBUGA1UECgwOQWxwaGEgTWVyY2hhbnQxFjAUBgNVBAMMDVNhbXBsZSBFQ0MgQ0EwHhcNMjAwODE1MDIxMDEwWhcNMjEwODE1MDIxMDEwWjBPMRcwFQYDVQQKDA5BbHBoYSBNZXJjaGFudDEfMB0GA1UECwwWVExTIENsaWVudCBDZXJ0aWZpY2F0ZTETMBEGA1UEAwwKMTIzNDU2Nzg5MDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEI/SLrH6fITA9y6Y3BneuoT/5\\+EHSepZxCYeSstGll2sVvmSDZWWSbN6lh5Fb/zagrDjjQ/gZtWIOTf2wL1vSGjgbcwgbQwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFHuvP526vFMywEoVoXZ5aXNfhnfeMB8GA1UdIwQYMBaAFI\\+ZFhOWF\\+oMtcfYwg15vH5WmWccMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwuYWxwaGEtbWVyY2hhbnQuZXhhbXBsZS9TYW1wbGVFQ0NDQS5jcmwwCgYIKoZIzj0EAwIDSAAwRQIhAPuWWvCTmOdvQzUjCUmTX7H4sX4Ebpw\\+CI\\+aOQLu1DqwAiA0eR4FdMtvXV4P6\\+WMz5B10oea5xtLTfSgoBDoTkvKYQ==0002C4MIICDjCCAbOgAwIBAgIIfnOsCbsxHjwwCgYIKoZIzj0EAwIwNjEXMBUGA1UECgwOQWxwaGEgTWVyY2hhbnQxGzAZBgNVBAMMElNhbXBsZSBSb290IEVDQyBDQTAeFw0yMDA4MTUwMjEwMDlaFw0zMDA4MTMwMjEwMDlaMDExFzAVBgNVBAoMDkFscGhhIE1lcmNoYW50MRYwFAYDVQQDDA1TYW1wbGUgRUNDIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHCanM9n\\+Rji\\+3EROj\\+HlogmXMU1Fk1td7N3I/8rfFnre1GwWCUqXSePHxwQ9DRHCV3oht3OUU2kDfitfUIujA6OBrzCBrDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUj5kWE5YX6gy1x9jCDXm8flaZZxwwHwYDVR0jBBgwFoAUvElIifFlt6oeUaopV9Y0lJtyPVQwRgYDVR0fBD8wPTA7oDmgN4Y1aHR0cDovL2NybC5hbHBoYS1tZXJjaGFudC5leGFtcGxlL1NhbXBsZVJvb3RFQ0NDQS5jcmwwCgYIKoZIzj0EAwIDSQAwRgIhALT8\\+DG\\+\\+\\+KuqqUGyBQ4YG4s34fqbujclxZTHxYWVVSNAiEAn3v5Xmct7fkLpkjGexiHsy6D90r0K2LlUqpN/069y5s=010004asdfKP10012331550BC9TS1320200818004100ZPB07"
)

# test export header containing optional blocks and padding, but not adding additional optional blocks
add_test(NAME tr31_tool_test40
COMMAND tr31-tool --kbpk 88E1AB2A2E3DD38C1FA039A536500CC8A87AB9D62DC92C01058FA79F44657DE6 --export 3F419E1CB7079442AA37474C2EFBF8B8 --export-header D1234M7HG00N0200HM0621PB0A5V5E8F
)
set_tests_properties(tr31_tool_test40
PROPERTIES
PASS_REGULAR_EXPRESSION "^D0128M7HG00N0200HM0621PB0A5V5E8F"
PASS_REGULAR_EXPRESSION "^D0128M7HG00N0200HM0621PB0A5V5E8F" # note that optional block padding content is intentionally preserved
)

# test export header containing optional blocks and padding and also adding additional optional blocks
add_test(NAME tr31_tool_test41
COMMAND tr31-tool --kbpk 88E1AB2A2E3DD38C1FA039A536500CC8A87AB9D62DC92C01058FA79F44657DE6 --export 3F419E1CB7079442AA37474C2EFBF8B8 --export-header D1234M7HG00N0200HM0621PB0A5V5E8F --export-opt-block-LB "MyKey"
)
set_tests_properties(tr31_tool_test41
PROPERTIES
PASS_REGULAR_EXPRESSION "^D0144M7HG00N0300HM0621LB09MyKeyPB11"
)
endif()
26 changes: 26 additions & 0 deletions src/tr31.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,18 +679,44 @@ static struct tr31_opt_ctx_t* tr31_opt_block_alloc(
)
{
struct tr31_opt_ctx_t* opt_ctx;
bool opt_blk_pb_found = false;

if (!ctx) {
return NULL;
}

// repeated optional block IDs are not allowed
// and optional block PB must always be last
// see ANSI X9.143:2021, 6.3.6
for (size_t i = 0; i < ctx->opt_blocks_count; ++i) {
if (ctx->opt_blocks[i].id == id) {
// existing optional block found
return NULL;
}

if (ctx->opt_blocks[i].id == TR31_OPT_BLOCK_PB) {
// optional block PB found
opt_blk_pb_found = true;
}
}

// if optional block PB already exists, remove all instances
// NOTE: it will be recreated by tr31_export()
// NOTE: if no new optional blocks are added, PB is intentionally preserved
if (opt_blk_pb_found) {
for (size_t i = 0; i < ctx->opt_blocks_count; ++i) {
if (ctx->opt_blocks[i].id == TR31_OPT_BLOCK_PB) {
free(ctx->opt_blocks[i].data);
ctx->opt_blocks[i].data = NULL;

ctx->opt_blocks_count -= 1;
if (i < ctx->opt_blocks_count) {
size_t remaining_count = ctx->opt_blocks_count - i;
size_t remaining_bytes = sizeof(*ctx->opt_blocks) * remaining_count;
memmove(&ctx->opt_blocks[i], &ctx->opt_blocks[i + 1], remaining_bytes);
}
}
}
}

// grow optional block array
Expand Down

0 comments on commit 3527f97

Please sign in to comment.