Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ cmake_minimum_required(VERSION 3.10)

option(BUILD_LIB "Build the library itself" ON)
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
option(BUILD_DOCS_API "Enable API documentation building" ON)
option(BUILD_DOCS_API "Enable API documentation building" OFF)
option(BUILD_DOCS_MAN "Enable manpage building" OFF)
option(BUILD_TESTING "Enable building unit tests" ON)
option(TEST_MEMCHECK "Enable test runtime memory checking" ON)
Expand Down
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,35 @@ git submodule update --init --recursive

This will take about a minute to build and run the unit tests, there should be 100% success.

Note: On earlier versions of CMake (<3.20), `./build.sh check` target may not run correctly.

#### Optional Additional Build Targets

Code Coverage
```
./build.sh coverage
```

# To open coverage report in a browser...
xdg-open build/default/coverage/index.html
The output HTML can be opened in a browser using:
```
xdg-open build/default/coverage-html/index.html
```

Doxygen Documentation
```
./build.sh prep -DBUILD_DOCS_API=ON
./build.sh docs
```

# To open in a browser...
The output HTML can be opened in a browser using:
```
xdg-open build/default/docs/api/html/index.html
```

Note: On earlier versions of CMake (<3.20), `./build.sh check` target may not run correctly.
To check for misspelling in the Doxygen output use the following, substituting the word/phrase you are looking for in the grep command
```
xmlstarlet tr build/default/docs/api/xml/combine.xslt build/default/docs/api/xml/index.xml | xmlstarlet tr docs/api/spellcheck.xsl | cat -n | grep -E 'bsl'
```

## Testing with the Mock BPA

Expand Down
28 changes: 24 additions & 4 deletions mock-bpa-test/helpers/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
from typing import List
import queue

# Set up logging
LOGGER = logging.getLogger(__name__)
''' Logger for this module. '''


def compose_args(args: List[str]) -> List[str]:
Expand Down Expand Up @@ -145,14 +145,29 @@ def _write_stdin(self, stream):
stream.flush()
LOGGER.debug('Stopping stdin thread')

def wait_for_line(self, timeout=5):
def wait_for_line(self, timeout:float=5) -> str:
''' Wait for any received stdout line.

:param timeout: The total time to wait for this line.
:return The matching line.
:raise TimeoutError: If the line was not seen in time.
'''
try:
text = self._stdout_lines.get(timeout=timeout)
except queue.Empty:
raise TimeoutError('no lines received before timeout')
return text

def wait_for_text(self, pattern, timeout=5):
def wait_for_text(self, pattern:str, timeout:float=5) -> str:
''' Iterate through the received stdout lines until a specific
full matching line is seen.

:param pattern: The pattern which must match the full line.
Use prefix or suffix ".*" as needed.
:param timeout: The total time to wait for this line.
:return The matching line.
:raise TimeoutError: If the line was not seen in time.
'''
expr = re.compile(pattern)
LOGGER.debug('Waiting for pattern "%s" ...', pattern)

Expand All @@ -170,5 +185,10 @@ def wait_for_text(self, pattern, timeout=5):
if expr.match(text) is not None:
return text

def send_stdin(self, text):
def send_stdin(self, text:str):
''' Send an exact line of text to the process stdin.

:param text: The line to send, which should include a newline
at the endd.
'''
self._stdin_lines.put(text)
4 changes: 2 additions & 2 deletions mock-bpa-test/requirements_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,14 @@ def __init__(self):
# Bundle with a BIB targeting primary block
input_data=[
[7, 0, 0, [2, [1, 2]], [2, [2, 1]], [2, [2, 1]], [0, 40], 1000000],
[11, 2, 0, 0, bytes.fromhex('810001018202820201828201078203008181820158405d9bdd1e2f043cf971588111f2fe1b847666cfacb7fb403c2468ef92dda8ec93df80b41620df5bc639d0c355e1cce6217e17d3b8c5560edc14aba3d005196b046e')],
[11, 2, 0, 0, bytes.fromhex('810001018202820201828201078203008181820158405d9bdd1e2f043cf971588111f2fe1b847666cfacb7fb403c2468ef92dda8ec93df80b41620df5bc6c355e1cce6217e17d3b8c5560edc14aba3d005196b046e')],
[1, 1, 0, 0, bytes.fromhex('526561647920746F2067656E657261746520612033322D62797465207061796C6F6164')]
],
# No output because it was deleted, logs to indicate deletion.
expected_output=(NO_OUTPUT, DELETION),
policy_config='0x62',
is_implemented=True,
is_working=False,
is_working=True,
expect_success=False,
input_data_format=DataFormat.BUNDLEARRAY,
expected_output_format=DataFormat.NONE
Expand Down
23 changes: 21 additions & 2 deletions mock-bpa-test/test_bpa.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,17 @@ def _single_test(self, testcase: _TestCase):
self._wait_for(self._ul_sock)

LOGGER.info('\nTransferred data:\n%s\n', binascii.hexlify(tx_data))
self.fail('Validate output')

LOGGER.warning('Check log output to validate reason for no data!!')

# Currently hard-coded for test case 19 but no other instances of DataFormat.NONE
case_19_str = r".*Delete bundle due to failed security operation"

LOGGER.debug("Searching test runner logger for failure string: %s", case_19_str)
found = self._agent.wait_for_text(case_19_str)
LOGGER.debug("\nFOUND OCCURENCE: %s", found)
self.assertTrue(found != "")

elif (testcase.expected_output_format == DataFormat.ERR):
Comment thread
jeronstone marked this conversation as resolved.
self._ul_sock.send(tx_data)
LOGGER.debug('waiting')
Expand All @@ -183,7 +193,16 @@ def _single_test(self, testcase: _TestCase):
self._wait_for(self._ul_sock)

LOGGER.info('\nTransferred data:\n%s\n', binascii.hexlify(tx_data))
self.fail('TODO handle err codes')

LOGGER.warning('Check log output to validate expected error')

# TBD - this logic is not used yet
err_case_str = r"tbd"

LOGGER.debug("Searching test runner logger for error string: %s", err_case_str)
found = self._agent.wait_for_text(err_case_str)
LOGGER.debug("\nFOUND OCCURENCE: %s", found)
self.assertTrue(found != "")


# Below utilizes setattr to add methods to a child class of the TestAgent, which will in-turn give us unit tests
Expand Down
9 changes: 8 additions & 1 deletion src/BPSecLib_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,13 @@ int BSL_BundleCtx_CreateBlock(BSL_BundleRef_t *bundle, uint64_t block_type_code,
*/
int BSL_BundleCtx_RemoveBlock(BSL_BundleRef_t *bundle, uint64_t block_num);

/** @brief Requests dropping of bundle
*
* @param[in] bundle Context bundle
* @return 0 on success, negative on failure.
*/
int BSL_BundleCtx_DeleteBundle(BSL_BundleRef_t *bundle);
Comment thread
BrianSipos marked this conversation as resolved.

/** @brief Requests the re-allocation of a block's BTSD, useful for BCB.
*
* @note Uses semantics similar to @c memcpy().
Expand Down Expand Up @@ -1225,4 +1232,4 @@ struct BSL_SecCtxDesc_s
BSL_SecCtx_Execute_f execute;
};

#endif /* BSL_BPSECLIB_PRIVATE_H_ */
#endif /* BSL_BPSECLIB_PRIVATE_H_ */
3 changes: 3 additions & 0 deletions src/BPSecLib_Public.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ typedef struct
/// @brief Host BPA function to reallocate a canonical block's BTSD, keeping existing data in-place.
int (*block_realloc_btsd_fn)(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t bytesize);

/// @brief Host BPA function to delete Bundle
int (*bundle_delete_fn)(BSL_BundleRef_t *bundle_ref);

/// @brief Host BPA function to encode an EID to CBOR.
int (*eid_to_cbor)(void *encoder, const BSL_HostEID_t *eid);

Expand Down
8 changes: 8 additions & 0 deletions src/backend/HostInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ int BSL_BundleCtx_RemoveBlock(BSL_BundleRef_t *bundle, uint64_t block_num)
return (result == 0) ? BSL_SUCCESS : BSL_ERR_HOST_CALLBACK_FAILED;
}

int BSL_BundleCtx_DeleteBundle(BSL_BundleRef_t *bundle)
{
CHK_ARG_NONNULL(bundle);
CHK_PRECONDITION(HostDescriptorTable.bundle_delete_fn != NULL);
int result = HostDescriptorTable.bundle_delete_fn(bundle);
return (result == 0) ? BSL_SUCCESS : BSL_ERR_HOST_CALLBACK_FAILED;
}

int BSL_BundleCtx_ReallocBTSD(BSL_BundleRef_t *bundle, uint64_t block_num, size_t bytesize)
{
CHK_ARG_NONNULL(bundle);
Expand Down
6 changes: 4 additions & 2 deletions src/backend/PublicInterfaceImpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ int BSL_API_ApplySecurity(const BSL_LibCtx_t *bsl, BSL_SecurityResponseSet_t *re
}
case BSL_POLICYACTION_DROP_BUNDLE:
{
BSL_LOG_WARNING("Dropping bundle due to block target num %lu security failure",
BSL_LOG_WARNING("Deleting bundle due to block target num %lu security failure",
policy_actions->sec_operations[oper_index].target_block_num);
must_drop = true;
break;
Expand All @@ -247,7 +247,9 @@ int BSL_API_ApplySecurity(const BSL_LibCtx_t *bsl, BSL_SecurityResponseSet_t *re

if (must_drop)
{
BSL_LOG_ERR("TODO Drop bundle using host interface");
// Drop the bundle and return operation error
BSL_LOG_WARNING("***** Delete bundle due to failed security operation *******");
BSL_BundleCtx_DeleteBundle(bundle);
}

// TODO CHK_POSTCONDITION
Expand Down
16 changes: 16 additions & 0 deletions src/mock_bpa/bsl_mock_bpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,21 @@ int MockBPA_RemoveBlock(BSL_BundleRef_t *bundle_ref, uint64_t block_num)
return 0;
}

int MockBPA_DeleteBundle(BSL_BundleRef_t *bundle_ref)
{
if (!bundle_ref || !bundle_ref->data)
{
return -1;
}

MockBPA_Bundle_t *bundle = bundle_ref->data;

// Mark the bundle for deletion
bundle->retain = false;

return 0;
}

int bsl_mock_bpa_init(void)
{
uint8_t *state = BSL_MALLOC(999);
Expand All @@ -259,6 +274,7 @@ int bsl_mock_bpa_init(void)
.bundle_get_block_ids = MockBPA_GetBlockNums,
.block_create_fn = MockBPA_CreateBlock,
.block_remove_fn = MockBPA_RemoveBlock,
.bundle_delete_fn = MockBPA_DeleteBundle,
.block_realloc_btsd_fn = MockBPA_ReallocBTSD,

// Old-style callbacks
Expand Down
2 changes: 2 additions & 0 deletions src/mock_bpa/bsl_mock_bpa.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef struct MockBPA_CanonicalBlock_s
typedef struct MockBPA_Bundle_s
{
uint64_t id;
bool retain;
MockBPA_PrimaryBlock_t primary_block;
MockBPA_CanonicalBlock_t blocks[MockBPA_BUNDLE_MAXBLOCKS];
size_t block_count;
Expand All @@ -91,6 +92,7 @@ int MockBPA_GetBlockMetadata(const BSL_BundleRef_t *bundle_ref, uint64_t block_n
int MockBPA_ReallocBTSD(BSL_BundleRef_t *bundle_ref, uint64_t block_num, size_t bytesize);
int MockBPA_CreateBlock(BSL_BundleRef_t *bundle_ref, uint64_t block_type_code, uint64_t *result_block_num);
int MockBPA_RemoveBlock(BSL_BundleRef_t *bundle_ref, uint64_t block_num);
int MockBPA_DeleteBundle(BSL_BundleRef_t *bundle_ref);

/** Register this mock BPA for the current process.
* @return Zero if successful.
Expand Down
8 changes: 1 addition & 7 deletions src/mock_bpa/bsl_mock_bpa_policy_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,16 @@ extern "C" {
* | | | |
* Policy Action: 00 - nothing, 01 - drop block, -| | | |
* 10 - drop bundle, 11: undefined -| | | |
<<<<<<< HEAD
* | | |
* Target Block Type: 00 - primary, 01 payload -| | |
* 10 - bib, 11 - bundle age -| | |
* | |
=======
* Target Block Type: -| | |
>>>>>>> main
* Policy Location: 0 - CLOUT, 1 - CLIN -| |
* |
* Sec Block Type: 0 - BIB, 1 - BCB -|
<<<<<<< HEAD
*
*
=======
* @endcode
>>>>>>> main
*/
typedef uint32_t bsl_mock_policy_configuration_t;

Expand All @@ -87,6 +80,7 @@ void mock_bpa_handle_policy_config_from_json(const char *pp_cfg_file_path, BSLP_
int mock_bpa_key_registry_init(const char *pp_cfg_file_path);

int mock_bpa_hexchar_to_int(char c);

int mock_bpa_hexstring_to_bytes(const char *hexstr, uint8_t *out, size_t out_size);
int bsl_mock_bpa_rfc9173_bcb_cek(unsigned char *buf, int len);

Expand Down
32 changes: 32 additions & 0 deletions src/mock_bpa/mock_bpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ static void *work_over_rx(void *arg _U_)
continue;
}

MockBPA_Bundle_t *bundle = item.bundle_ref.data;
if (!bundle->retain)
{
BSL_LOG_ERR("bundle was marked to delete by BSL");
mock_bpa_ctr_deinit(&item);
continue;
}

// loopback
data_queue_push(deliver, item);
}
Expand Down Expand Up @@ -240,6 +248,14 @@ static void *work_under_rx(void *arg _U_)
continue;
}

MockBPA_Bundle_t *bundle = item.bundle_ref.data;
if (!bundle->retain)
{
BSL_LOG_ERR("bundle was marked to delete by BSL");
mock_bpa_ctr_deinit(&item);
continue;
}

// loopback
data_queue_push(forward, item);
}
Expand Down Expand Up @@ -269,6 +285,14 @@ static void *work_deliver(void *arg _U_)
continue;
}

MockBPA_Bundle_t *bundle = item.bundle_ref.data;
if (!bundle->retain)
{
BSL_LOG_ERR("bundle was marked to delete by BSL");
mock_bpa_ctr_deinit(&item);
continue;
}

mock_bpa_encode(&item);
data_queue_push(over_tx, item);
{
Expand Down Expand Up @@ -306,6 +330,14 @@ static void *work_forward(void *arg _U_)
continue;
}

MockBPA_Bundle_t *bundle = item.bundle_ref.data;
if (!bundle->retain)
{
BSL_LOG_ERR("bundle was marked to delete by BSL");
mock_bpa_ctr_deinit(&item);
continue;
}

mock_bpa_encode(&item);
data_queue_push(under_tx, item);
{
Expand Down
5 changes: 5 additions & 0 deletions src/mock_bpa/mock_bpa_ctr.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ void mock_bpa_ctr_init(mock_bpa_ctr_t *ctr)
memset(ctr, 0, sizeof(*ctr));
BSL_Data_Init(&(ctr->encoded));
ctr->bundle_ref.data = calloc(1, sizeof(MockBPA_Bundle_t));
// TODO : Just make a MockBPA_Bundle_Init function.
// HostEID_t's are initialized deeper into the decode function.

MockBPA_Bundle_t *bundle = ctr->bundle_ref.data;
bundle->retain = true;
}

void mock_bpa_ctr_init_move(mock_bpa_ctr_t *ctr, mock_bpa_ctr_t *src)
Expand Down