Skip to content
11 changes: 9 additions & 2 deletions src/BPSecLib_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ typedef enum

/// Policy Errors start at 100
BSL_ERR_POLICY_FAILED = -100, ///< General error code for errors arising from a Policy Provider
BSL_ERR_POLICY_QUERY = -101, ///< Error code for errors arising from Policy Provider query
BSL_ERR_POLICY_FINAL = -102, ///< Error code for errors arising from Policy Provider finalize

/// Security Context errors start at 200
BSL_ERR_SECURITY_CONTEXT_FAILED = -200, ///< General error code for errors arising from a Security Context.
Expand Down Expand Up @@ -1042,7 +1044,7 @@ void BSL_SecurityAction_InitSet(BSL_SecurityAction_t *self, const BSL_SecurityAc
void BSL_SecurityAction_Deinit(BSL_SecurityAction_t *self);

/**
* Add security operation to security action, with deterministic ordering
* Add security operation to security action
* @param[in,out] self action to add security operation to
* @param[in,out] sec_oper new security operation to add and move from.
* @return 0 if successful
Expand Down Expand Up @@ -1077,6 +1079,10 @@ void BSL_SecurityAction_IncrError(BSL_SecurityAction_t *self);
*/
size_t BSL_SecurityAction_CountErrors(const BSL_SecurityAction_t *self);

/** @brief Returns Policy Provider ID of @param[in] self action
*/
uint64_t BSL_SecurityAction_GetPPID(const BSL_SecurityAction_t *self);

/// @brief Returns size of the struct, helpful for dynamic allocation.
/// @return Size of the struct
size_t BSL_SecurityActionSet_Sizeof(void);
Expand Down Expand Up @@ -1195,7 +1201,8 @@ int BSL_PolicyRegistry_FinalizeActions(const BSL_LibCtx_t *bsl, const BSL_Securi
typedef int (*BSL_PolicyInspect_f)(const void *user_data, BSL_SecurityActionSet_t *output_action_set,
const BSL_BundleRef_t *bundle, BSL_PolicyLocation_e location);

/// @brief Callback interface to query policy provider to populate the action set
/// @brief Callback interface to finalize policy provider over the action set. Finalize should ignore actions from
/// different policy providers
typedef int (*BSL_PolicyFinalize_f)(const void *user_data, const BSL_SecurityActionSet_t *output_action_set,
const BSL_BundleRef_t *bundle, const BSL_SecurityResponseSet_t *response_output);

Expand Down
2 changes: 1 addition & 1 deletion src/BPSecLib_Public.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ int BSL_API_RegisterSecurityContext(BSL_LibCtx_t *lib, uint64_t sec_ctx_id, BSL_
* @param[in] desc Policy Provider callbacks.
*/
BSL_REQUIRE_CHECK
int BSL_API_RegisterPolicyProvider(BSL_LibCtx_t *lib, BSL_PolicyDesc_t desc);
int BSL_API_RegisterPolicyProvider(BSL_LibCtx_t *lib, uint64_t pp_id, BSL_PolicyDesc_t desc);

/** @brief Query BSL to populate a `BSL_SecurityActionSet_t` containing security processing instructions.
*
Expand Down
46 changes: 40 additions & 6 deletions src/backend/PolicyProvider.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,60 @@
#include <BPSecLib_Private.h>

#include "PublicInterfaceImpl.h"
#include "SecurityActionSet.h"

int BSL_PolicyRegistry_InspectActions(const BSL_LibCtx_t *bsl, BSL_SecurityActionSet_t *output_action_set,
const BSL_BundleRef_t *bundle, BSL_PolicyLocation_e location)
{
// TODO - this should just check the policy_registry to see what is there,.
// and if it's present then just call the callbacks and pass through the arguments.
CHK_ARG_NONNULL(bsl);
CHK_ARG_NONNULL(bsl->policy_reg);
CHK_ARG_NONNULL(output_action_set);
CHK_ARG_NONNULL(bundle);
CHK_PRECONDITION(bsl->policy_registry.query_fn != NULL);
return bsl->policy_registry.query_fn(bsl->policy_registry.user_data, output_action_set, bundle, location);

BSL_PolicyDict_it_t policy_reg_it;
for (BSL_PolicyDict_it(policy_reg_it, bsl->policy_reg); !BSL_PolicyDict_end_p(policy_reg_it);
BSL_PolicyDict_next(policy_reg_it))
{
size_t act_ct = BSL_SecurityActionSet_CountActions(output_action_set);

const BSL_PolicyDesc_t *policy = BSL_PolicyDict_cref(policy_reg_it)->value_ptr;
BSL_LOG_INFO("Inspecting PP (id %" PRIu64 ")", *BSL_PolicyDict_cref(policy_reg_it)->key_ptr);
if (BSL_SUCCESS != policy->query_fn(policy->user_data, output_action_set, bundle, location))
{
return BSL_ERR_POLICY_FINAL;
}

size_t new_act_ct = BSL_SecurityActionSet_CountActions(output_action_set);
for (size_t i = act_ct; i < new_act_ct; i++)
{
BSL_SecurityAction_t *act = BSL_SecActionList_get(output_action_set->actions, i);
act->pp_id = *BSL_PolicyDict_cref(policy_reg_it)->key_ptr;
}
}

return BSL_SUCCESS;
}

int BSL_PolicyRegistry_FinalizeActions(const BSL_LibCtx_t *bsl, const BSL_SecurityActionSet_t *policy_actions,
const BSL_BundleRef_t *bundle, const BSL_SecurityResponseSet_t *response_output)
{
CHK_ARG_NONNULL(bsl);
CHK_ARG_NONNULL(bsl->policy_reg);
CHK_ARG_NONNULL(policy_actions);
CHK_ARG_NONNULL(response_output);
CHK_ARG_NONNULL(bundle);
CHK_PRECONDITION(bsl->policy_registry.finalize_fn != NULL);
return bsl->policy_registry.finalize_fn(bsl->policy_registry.user_data, policy_actions, bundle, response_output);

size_t act_ct = BSL_SecurityActionSet_CountActions(policy_actions);
for (size_t i = 0; i < act_ct; i++)
{
BSL_SecurityAction_t *act = BSL_SecActionList_get(policy_actions->actions, i);

const BSL_PolicyDesc_t *policy = BSL_PolicyDict_get(bsl->policy_reg, act->pp_id);
if (BSL_SUCCESS != policy->finalize_fn(policy->user_data, policy_actions, bundle, response_output))
Comment thread
jeronstone marked this conversation as resolved.
{
return BSL_ERR_POLICY_FINAL;
}
}

return BSL_SUCCESS;
}
34 changes: 18 additions & 16 deletions src/backend/PublicInterfaceImpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,31 @@ int BSL_API_InitLib(BSL_LibCtx_t *lib)
CHK_ARG_NONNULL(lib);

BSL_SecCtxDict_init(lib->sc_reg);
BSL_PolicyDict_init(lib->policy_reg);
return BSL_SUCCESS;
}

int BSL_API_DeinitLib(BSL_LibCtx_t *lib)
{
CHK_ARG_NONNULL(lib);

if (lib->policy_registry.deinit_fn != NULL)
BSL_PolicyDict_it_t policy_reg_it;
for (BSL_PolicyDict_it(policy_reg_it, lib->policy_reg); !BSL_PolicyDict_end_p(policy_reg_it);
BSL_PolicyDict_next(policy_reg_it))
{
// Call the policy deinit function
(lib->policy_registry.deinit_fn)(lib->policy_registry.user_data);

// TODO - We should not assume this is dynamically allocated.
BSL_FREE(lib->policy_registry.user_data);
}
else
{
BSL_LOG_WARNING("Policy Provider offered no deinit function");
const BSL_PolicyDesc_t *policy = BSL_PolicyDict_cref(policy_reg_it)->value_ptr;
if (policy->deinit_fn != NULL)
{
// Call the policy deinit function
(policy->deinit_fn)(policy->user_data);
}
else
{
BSL_LOG_WARNING("Policy Provider offered no deinit function");
}
}

BSL_PolicyDict_clear(lib->policy_reg);
BSL_SecCtxDict_clear(lib->sc_reg);
return BSL_SUCCESS;
}
Expand All @@ -88,14 +93,14 @@ int BSL_API_RegisterSecurityContext(BSL_LibCtx_t *lib, uint64_t sec_ctx_id, BSL_
return BSL_SUCCESS;
}

int BSL_API_RegisterPolicyProvider(BSL_LibCtx_t *lib, BSL_PolicyDesc_t desc)
int BSL_API_RegisterPolicyProvider(BSL_LibCtx_t *lib, uint64_t pp_id, BSL_PolicyDesc_t desc)
{
CHK_ARG_NONNULL(lib);
CHK_ARG_EXPR(desc.query_fn != NULL);
CHK_ARG_EXPR(desc.finalize_fn != NULL);
CHK_ARG_EXPR(desc.deinit_fn != NULL);

lib->policy_registry = desc;
BSL_PolicyDict_set_at(lib->policy_reg, pp_id, desc);
return BSL_SUCCESS;
}

Expand All @@ -106,9 +111,8 @@ int BSL_API_QuerySecurity(const BSL_LibCtx_t *bsl, BSL_SecurityActionSet_t *outp
CHK_ARG_NONNULL(output_action_set);
CHK_ARG_NONNULL(bundle);

CHK_PRECONDITION(bsl->policy_registry.query_fn != NULL);

BSL_LOG_INFO("Querying policy provider for security actions...");
BSL_SecurityActionSet_Init(output_action_set);
int query_status = BSL_PolicyRegistry_InspectActions(bsl, output_action_set, bundle, location);
BSL_LOG_INFO("Completed query: status=%d", query_status);

Expand Down Expand Up @@ -185,8 +189,6 @@ int BSL_API_ApplySecurity(const BSL_LibCtx_t *bsl, BSL_SecurityResponseSet_t *re
CHK_ARG_NONNULL(bundle);
CHK_ARG_NONNULL(policy_actions);

CHK_PRECONDITION(bsl->policy_registry.finalize_fn != NULL);

int exec_code = BSL_SecCtx_ExecutePolicyActionSet((BSL_LibCtx_t *)bsl, response_output, bundle, policy_actions);
if (exec_code < BSL_SUCCESS)
{
Expand Down
14 changes: 12 additions & 2 deletions src/backend/PublicInterfaceImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define BSL_CTX_DYN_H_

#include <m-dict.h>
#include <m-bptree.h>

#include <BPSecLib_Private.h>
#include <BPSecLib_Public.h>
Expand All @@ -37,18 +38,27 @@ extern "C" {

// NOLINTBEGIN
/** @struct BSL_SecCtxDict_t
* Stable dict of security context descriptors (key: context id | value: descriptor struct)
* Stable dict of security context descriptors (key: context ID | value: security context descriptor struct.
*/
/// @cond Doxygen_Suppress
DICT_DEF2(BSL_SecCtxDict, uint64_t, M_BASIC_OPLIST, BSL_SecCtxDesc_t, M_POD_OPLIST)
/// @endcond

/**
* @struct BSL_PolicyDict_t
* Stable dict of policy provider descriptors (key: policy provider ID | value: policy provider descriptor struct).
* Policy provider IDs are arbitrary, unique, and control the order of use.
*/
/// @cond Doxygen_Suppress
BPTREE_DEF2(BSL_PolicyDict, 4, uint64_t, M_BASIC_OPLIST, BSL_PolicyDesc_t, M_POD_OPLIST)
/// @endcond
// NOLINTEND

/** Concrete definition of library context.
*/
struct BSL_LibCtx_s
{
BSL_PolicyDesc_t policy_registry;
BSL_PolicyDict_t policy_reg;
BSL_SecCtxDict_t sc_reg;
};

Expand Down
8 changes: 8 additions & 0 deletions src/backend/SecurityAction.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void BSL_SecurityAction_Init(BSL_SecurityAction_t *self)

BSL_SecOperList_init(self->sec_op_list);
self->err_ct = 0;
self->pp_id = 0;
}

void BSL_SecurityAction_InitSet(BSL_SecurityAction_t *self, const BSL_SecurityAction_t *src)
Expand All @@ -46,6 +47,7 @@ void BSL_SecurityAction_InitSet(BSL_SecurityAction_t *self, const BSL_SecurityAc

BSL_SecOperList_init_set(self->sec_op_list, src->sec_op_list);
self->err_ct = src->err_ct;
self->pp_id = src->pp_id;
}

void BSL_SecurityAction_Deinit(BSL_SecurityAction_t *self)
Expand Down Expand Up @@ -90,3 +92,9 @@ BSL_SecOper_t *BSL_SecurityAction_GetSecOperAtIndex(const BSL_SecurityAction_t *
ASSERT_ARG_NONNULL(self->sec_op_list);
return BSL_SecOperList_get(self->sec_op_list, index);
}

uint64_t BSL_SecurityAction_GetPPID(const BSL_SecurityAction_t *self)
{
ASSERT_ARG_NONNULL(self);
return self->pp_id;
}
1 change: 1 addition & 0 deletions src/backend/SecurityAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ struct BSL_SecurityAction_s
{
BSL_SecOperList_t sec_op_list;
size_t err_ct;
uint64_t pp_id;
};
2 changes: 1 addition & 1 deletion src/mock_bpa/mock_bpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ int main(int argc, char **argv)
.query_fn = BSLP_QueryPolicy,
.finalize_fn = BSLP_FinalizePolicy,
.user_data = BSL_CALLOC(1, sizeof(BSLP_PolicyProvider_t)) };
ASSERT_PROPERTY(BSL_SUCCESS == BSL_API_RegisterPolicyProvider(bsl, policy_callbacks));
ASSERT_PROPERTY(BSL_SUCCESS == BSL_API_RegisterPolicyProvider(bsl, 1, policy_callbacks));

BSL_CryptoInit();

Expand Down
14 changes: 12 additions & 2 deletions src/policy_provider/SamplePolicyProvider.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ int BSLP_QueryPolicy(const void *user_data, BSL_SecurityActionSet_t *output_acti
return BSL_ERR_HOST_CALLBACK_FAILED;
}

BSL_SecurityActionSet_Init(output_action_set);

BSL_SecurityAction_t *action = BSL_CALLOC(1, BSL_SecurityAction_Sizeof());
BSL_SecurityAction_Init(action);

BSLP_SecOperPtrList_t secops;
BSLP_SecOperPtrList_init(secops);

Expand Down Expand Up @@ -234,9 +234,18 @@ int BSLP_QueryPolicy(const void *user_data, BSL_SecurityActionSet_t *output_acti
int BSLP_FinalizePolicy(const void *user_data, const BSL_SecurityActionSet_t *output_action_set,
const BSL_BundleRef_t *bundle, const BSL_SecurityResponseSet_t *response_output)
{
const BSLP_PolicyProvider_t *self = user_data;
ASSERT_ARG_EXPR(BSLP_PolicyProvider_IsConsistent(self));

for (size_t i = 0; i < BSL_SecurityActionSet_CountActions(output_action_set); i++)
{
const BSL_SecurityAction_t *action = BSL_SecurityActionSet_GetActionAtIndex(output_action_set, i);

if (BSL_SecurityAction_GetPPID(action) != self->pp_id)
{
continue;
}

for (size_t j = 0; j < BSL_SecurityAction_CountSecOpers(action); j++)
{
const BSL_SecOper_t *secop = BSL_SecurityAction_GetSecOperAtIndex(action, j);
Expand Down Expand Up @@ -296,6 +305,7 @@ void BSLP_Deinit(void *user_data)
BSLP_PolicyPredicate_Deinit(&self->predicates[index]);
}
memset(self, 0, sizeof(*self));
BSL_FREE(user_data);
}

void BSLP_PolicyPredicate_Init(BSLP_PolicyPredicate_t *self, BSL_PolicyLocation_e location,
Expand Down
1 change: 1 addition & 0 deletions src/policy_provider/SamplePolicyProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ typedef struct BSLP_PolicyProvider_s
size_t predicate_count;
BSLP_PolicyRule_t rules[BSLP_POLICYPREDICATE_ARRAY_CAPACITY];
size_t rule_count;
uint64_t pp_id;
} BSLP_PolicyProvider_t;

void BSLP_Deinit(void *user_data);
Expand Down
5 changes: 5 additions & 0 deletions test/bsl_test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,13 @@ extern "C" {
/// @brief Key ID for the Appendix A3 key in OpenSSL
#define RFC9173_EXAMPLE_A3_KEY "9103"

/// @brief Key ID for the Appendix A4 key in OpenSSL
#define RFC9173_EXAMPLE_A4_BCB_KEY "9104"

/// @brief Sample policy provider ID
#define BSL_SAMPLE_PP_ID 1
#define BSL_SAMPLE_PP_ID_2 2

#define quick_data_t(field, tgt) \
field.len = sizeof(tgt); \
field.ptr = ((uint8_t *)tgt)
Expand Down
Loading