diff --git a/src/security/core/tests/access_control.c b/src/security/core/tests/access_control.c
index 3b04fc6..23c32f3 100644
--- a/src/security/core/tests/access_control.c
+++ b/src/security/core/tests/access_control.c
@@ -23,15 +23,20 @@
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/io.h"
#include "dds/ddsrt/string.h"
+#include "dds/ddsi/q_entity.h"
+#include "dds/ddsi/ddsi_entity_index.h"
+#include "dds/ddsi/ddsi_security_omg.h"
#include "dds/ddsi/q_config.h"
#include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_misc.h"
#include "dds/ddsi/ddsi_xqos.h"
+#include "dds__entity.h"
#include "dds/security/dds_security_api.h"
#include "common/config_env.h"
#include "common/access_control_wrapper.h"
+#include "common/cryptography_wrapper.h"
#include "common/security_config_test_utils.h"
#include "common/test_identity.h"
#include "common/test_utils.h"
@@ -59,7 +64,7 @@ static const char *config =
" ${INCL_PERM:+}"
" "
" "
- " "
+ " "
" "
" "
"";
@@ -114,6 +119,41 @@ static void access_control_fini(size_t n)
CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain[i]), DDS_RETCODE_OK);
}
+static DDS_Security_DatawriterCryptoHandle get_builtin_writer_crypto_handle(dds_entity_t participant, unsigned entityid)
+{
+ DDS_Security_DatawriterCryptoHandle crypto_handle;
+ struct dds_entity *pp_entity;
+ struct participant *pp;
+ struct writer *wr;
+ CU_ASSERT_EQUAL_FATAL(dds_entity_pin(participant, &pp_entity), 0);
+ thread_state_awake(lookup_thread_state(), &pp_entity->m_domain->gv);
+ pp = entidx_lookup_participant_guid(pp_entity->m_domain->gv.entity_index, &pp_entity->m_guid);
+ wr = get_builtin_writer(pp, entityid);
+ CU_ASSERT_FATAL(wr != NULL);
+ assert(wr != NULL); /* for Clang's static analyzer */
+ crypto_handle = wr->sec_attr->crypto_handle;
+ thread_state_asleep(lookup_thread_state());
+ dds_entity_unpin(pp_entity);
+ return crypto_handle;
+}
+
+// static DDS_Security_DatawriterCryptoHandle get_writer_crypto_handle(dds_entity_t writer)
+// {
+// DDS_Security_DatawriterCryptoHandle crypto_handle;
+// struct dds_entity *wr_entity;
+// struct writer *wr;
+// CU_ASSERT_EQUAL_FATAL(dds_entity_pin(writer, &wr_entity), 0);
+// thread_state_awake(lookup_thread_state(), &wr_entity->m_domain->gv);
+// wr = entidx_lookup_writer_guid(wr_entity->m_domain->gv.entity_index, &wr_entity->m_guid);
+// CU_ASSERT_FATAL(wr != NULL);
+// assert(wr != NULL); /* for Clang's static analyzer */
+// crypto_handle = wr->sec_attr->crypto_handle;
+// thread_state_asleep(lookup_thread_state());
+// dds_entity_unpin(wr_entity);
+// return crypto_handle;
+// }
+
+
#define GOV_F PF_F COMMON_ETC_PATH("default_governance.p7s")
#define GOV_FNE PF_F COMMON_ETC_PATH("default_governance_non_existing.p7s")
#define GOV_DI PF_D COMMON_ETC_PATH("default_governance.p7s")
@@ -512,11 +552,9 @@ CU_Theory(
get_permissions_grant ("id2", id2_subj, perm_inv_pp2 ? "99" : NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL) };
char * perm_config = get_permissions_config (grants, 2, true);
- struct kvp governance_vars_pp1[] = { { "ENABLE_JOIN_AC", join_ac_pp1 ? "true" : "false", 1 }, { NULL, NULL, 0 } };
- struct kvp governance_vars_pp2[] = { { "ENABLE_JOIN_AC", join_ac_pp2 ? "true" : "false", 1 }, { NULL, NULL, 0 } };
-
- char * gov_config_pp1 = get_governance_config (governance_vars_pp1, true);
- char * gov_config_pp2 = get_governance_config (governance_vars_pp2, true);
+ char * gov_topic_rule = get_governance_topic_rule ("*", false, false, true, true, "NONE", "NONE");
+ char * gov_config_pp1 = get_governance_config (false, join_ac_pp1, NULL, NULL, NULL, gov_topic_rule, true);
+ char * gov_config_pp2 = get_governance_config (false, join_ac_pp2, NULL, NULL, NULL, gov_topic_rule, true);
const char * def_perm_ca = PF_F COMMON_ETC_PATH("default_permissions_ca.pem");
access_control_init (
@@ -536,6 +574,109 @@ CU_Theory(
ddsrt_free (gov_config_pp1);
ddsrt_free (gov_config_pp2);
+ ddsrt_free (gov_topic_rule);
+ ddsrt_free (perm_topic);
+ ddsrt_free (grants[0]);
+ ddsrt_free (grants[1]);
+ ddsrt_free (perm_config);
+ ddsrt_free (ca);
+ ddsrt_free (id1_subj);
+ ddsrt_free (id2_subj);
+ ddsrt_free (id1);
+ ddsrt_free (id2);
+}
+
+#define na false
+#define E ENCRYPT
+CU_TheoryDataPoints(ddssec_access_control, discovery_protection) = {
+ CU_DataPoints(const char *,
+ /* */"disabled",
+ /* | */"enabled, protection kind none",
+ /* | | */"disabled, protection kind encrypt",
+ /* | | | */"enabled, protection kind encrypt",
+ /* | | | | */"enabled, protection kind sign",
+ /* | | | | | */"enabled, protection kind encrypt-with-origin_auth",
+ /* | | | | | | */"enabled for node 1, disabled for node 2",
+ /* | | | | | | | */"node 1 and node 2 different protection kinds"),
+ CU_DataPoints(bool, false, true, false, true, true, true, true, true), /* enable_discovery_protection for pp 1 */
+ CU_DataPoints(bool, false, true, false, true, true, true, false, true), /* enable_discovery_protection for pp 2 */
+ CU_DataPoints(DDS_Security_ProtectionKind, PK_N, PK_N, PK_E, PK_E, PK_S, PK_EOA, PK_E, PK_E), /* discovery_protection_kind pp 1 */
+ CU_DataPoints(DDS_Security_ProtectionKind, PK_N, PK_N, PK_E, PK_E, PK_S, PK_EOA, PK_N, PK_S), /* discovery_protection_kind pp 2 */
+ CU_DataPoints(bool, false, false, false, false, false, false, true, true), /* expect rd-wr match fail */
+ CU_DataPoints(bool, false, false, true, true, true, true, true, true), /* expect SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER of pp 1 to have a crypto handle */
+ CU_DataPoints(bool, na, na, true, true, true, true, false, false), /* expect encode_datawriter_submessage for SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER of pp 1 */
+};
+#undef na
+CU_Theory(
+ (const char * test_descr, bool enable_discovery_protection_pp1, bool enable_discovery_protection_pp2,
+ DDS_Security_ProtectionKind discovery_protection_kind_pp1, DDS_Security_ProtectionKind discovery_protection_kind_pp2,
+ bool exp_rd_wr_match_fail, bool exp_secure_pub_wr_handle, bool exp_secure_pub_wr_encode_decode),
+ ddssec_access_control, discovery_protection, .timeout=30)
+{
+ print_test_msg ("running test discovery_protection: %s\n", test_descr);
+
+ char topic_name[100];
+ create_topic_name ("ddssec_access_control_", g_topic_nr++, topic_name, sizeof (topic_name));
+
+ /* create ca and id1/id2 certs that will not expire during this test */
+ char *ca, *id1, *id2, *id1_subj, *id2_subj;
+ ca = generate_ca ("ca1", TEST_IDENTITY_CA1_PRIVATE_KEY, 0, 3600);
+ id1 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id1", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &id1_subj);
+ id2 = generate_identity (ca, TEST_IDENTITY_CA1_PRIVATE_KEY, "id2", TEST_IDENTITY1_PRIVATE_KEY, 0, 3600, &id2_subj);
+
+ /* localtime will be converted to gmtime in get_permissions_grant */
+ dds_time_t now = dds_time ();
+ char * perm_topic = get_permissions_topic (topic_name);
+ char * grants[] = {
+ get_permissions_grant ("id1", id1_subj, NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL),
+ get_permissions_grant ("id2", id2_subj, NULL, now, now + DDS_SECS(3600), perm_topic, perm_topic, NULL) };
+ char * perm_config = get_permissions_config (grants, 2, true);
+
+ char * gov_topic_rule1 = get_governance_topic_rule (topic_name, enable_discovery_protection_pp1, false, true, true, "ENCRYPT", "NONE");
+ char * gov_topic_rule2 = get_governance_topic_rule (topic_name, enable_discovery_protection_pp2, false, true, true, "ENCRYPT", "NONE");
+ char * gov_config1 = get_governance_config (false, true, pk_to_str (discovery_protection_kind_pp1), NULL, "ENCRYPT", gov_topic_rule1, true);
+ char * gov_config2 = get_governance_config (false, true, pk_to_str (discovery_protection_kind_pp2), NULL, "ENCRYPT", gov_topic_rule2, true);
+ const char * def_perm_ca = PF_F COMMON_ETC_PATH("default_permissions_ca.pem");
+
+ access_control_init (
+ 2,
+ (const char *[]) { id1, id2 },
+ (const char *[]) { TEST_IDENTITY1_PRIVATE_KEY, TEST_IDENTITY1_PRIVATE_KEY },
+ (const char *[]) { ca, ca },
+ (bool []) { false, false }, NULL, NULL,
+ (bool []) { true, true }, (const char *[]) { gov_config1, gov_config2 },
+ (bool []) { true, true }, (const char *[]) { perm_config, perm_config },
+ (bool []) { true, true }, (const char *[]) { def_perm_ca, def_perm_ca });
+ validate_handshake (DDS_DOMAINID, false, NULL, NULL, NULL);
+
+ dds_entity_t pub, sub, pub_tp, sub_tp, wr, rd;
+ rd_wr_init (g_participant[0], &pub, &pub_tp, &wr, g_participant[1], &sub, &sub_tp, &rd, topic_name);
+ sync_writer_to_readers (g_participant[0], wr, exp_rd_wr_match_fail ? 0 : 1);
+ if (!exp_rd_wr_match_fail)
+ write_read_for (wr, g_participant[1], rd, DDS_MSECS (100), false, false);
+
+ DDS_Security_DatawriterCryptoHandle secure_pub_wr_handle = get_builtin_writer_crypto_handle (g_participant[0], NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER);
+ print_test_msg ("crypto handle for SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER: %ld\n", secure_pub_wr_handle);
+ CU_ASSERT_EQUAL_FATAL (exp_secure_pub_wr_handle, secure_pub_wr_handle != 0);
+
+ struct dds_security_cryptography_impl * crypto_context_pub = get_crypto_context (g_participant[0]);
+ CU_ASSERT_FATAL (crypto_context_pub != NULL);
+
+ struct crypto_encode_decode_data *log = get_encode_decode_log (crypto_context_pub, ENCODE_DATAWRITER_SUBMESSAGE, secure_pub_wr_handle);
+ CU_ASSERT_EQUAL_FATAL (exp_secure_pub_wr_handle && exp_secure_pub_wr_encode_decode, log != NULL);
+ if (log != NULL)
+ {
+ print_test_msg ("encode_datawriter_submessage count for SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER: %u\n", log->count);
+ CU_ASSERT_FATAL (log->count > 0);
+ ddsrt_free (log);
+ }
+
+ access_control_fini (2);
+
+ ddsrt_free (gov_config1);
+ ddsrt_free (gov_config2);
+ ddsrt_free (gov_topic_rule1);
+ ddsrt_free (gov_topic_rule2);
ddsrt_free (perm_topic);
ddsrt_free (grants[0]);
ddsrt_free (grants[1]);
diff --git a/src/security/core/tests/authentication.c b/src/security/core/tests/authentication.c
index dbd80be..0af4138 100644
--- a/src/security/core/tests/authentication.c
+++ b/src/security/core/tests/authentication.c
@@ -101,15 +101,8 @@ static void authentication_init(
if (perm_config == NULL)
perm_config = DEF_PERM_CONF;
- struct kvp governance_vars[] = {
- { "DISCOVERY_PROTECTION_KIND", "NONE", 1 },
- { "LIVELINESS_PROTECTION_KIND", "NONE", 1 },
- { "RTPS_PROTECTION_KIND", "NONE", 1 },
- { "METADATA_PROTECTION_KIND", "NONE", 1 },
- { "DATA_PROTECTION_KIND", "NONE", 1 },
- { NULL, NULL, 0 }
- };
- char * gov_config_signed = get_governance_config (governance_vars, true);
+ char * gov_topic_rule = get_governance_topic_rule ("*", false, false, true, true, "NONE", "NONE");
+ char * gov_config_signed = get_governance_config (false, false, NULL, NULL, NULL, gov_topic_rule, true);
struct kvp config_vars1[] = {
{ "TEST_IDENTITY_CERTIFICATE", id1_cert, 1 },
@@ -143,6 +136,7 @@ static void authentication_init(
CU_ASSERT_EQUAL_FATAL (exp_pp2_fail, g_participant2 <= 0);
ddsrt_free (gov_config_signed);
+ ddsrt_free (gov_topic_rule);
ddsrt_free (conf1);
ddsrt_free (conf2);
}
diff --git a/src/security/core/tests/common/cryptography_wrapper.c b/src/security/core/tests/common/cryptography_wrapper.c
index 1856c09..990e2c8 100644
--- a/src/security/core/tests/common/cryptography_wrapper.c
+++ b/src/security/core/tests/common/cryptography_wrapper.c
@@ -74,6 +74,8 @@ struct dds_security_cryptography_impl {
const char * encrypted_secret;
ddsrt_mutex_t token_data_lock;
struct ddsrt_circlist token_data_list;
+ ddsrt_mutex_t encode_decode_log_lock;
+ struct ddsrt_circlist encode_decode_log;
};
static DDS_Security_ParticipantCryptoHandle g_local_participant_handle = 0;
@@ -211,6 +213,12 @@ struct ddsrt_circlist * get_crypto_tokens (struct dds_security_cryptography_impl
ddsrt_circlist_init (tokens);
ddsrt_mutex_lock (&impl->token_data_lock);
+ if (ddsrt_circlist_isempty (&impl->encode_decode_log))
+ {
+ ddsrt_mutex_unlock (&impl->token_data_lock);
+ return tokens;
+ }
+
struct ddsrt_circlist_elem *elem0 = ddsrt_circlist_oldest (&impl->token_data_list), *elem = elem0;
while (elem != NULL)
{
@@ -231,6 +239,11 @@ struct crypto_token_data * find_crypto_token (struct dds_security_cryptography_i
{
assert (data_len <= CRYPTO_TOKEN_SIZE);
ddsrt_mutex_lock (&impl->token_data_lock);
+ if (ddsrt_circlist_isempty (&impl->encode_decode_log))
+ {
+ ddsrt_mutex_unlock (&impl->token_data_lock);
+ return NULL;
+ }
struct ddsrt_circlist_elem *elem0 = ddsrt_circlist_oldest (&impl->token_data_list), *elem = elem0;
while (elem != NULL)
{
@@ -256,6 +269,60 @@ struct crypto_token_data * find_crypto_token (struct dds_security_cryptography_i
return NULL;
}
+static void log_encode_decode (struct dds_security_cryptography_impl * impl, enum crypto_encode_decode_fn function, DDS_Security_long_long handle)
+{
+ ddsrt_mutex_lock (&impl->encode_decode_log_lock);
+ if (!ddsrt_circlist_isempty (&impl->encode_decode_log))
+ {
+ struct ddsrt_circlist_elem *elem0 = ddsrt_circlist_oldest (&impl->encode_decode_log), *elem = elem0;
+ while (elem != NULL)
+ {
+ struct crypto_encode_decode_data *data = DDSRT_FROM_CIRCLIST (struct crypto_encode_decode_data, e, elem);
+ if (data->function == function && data->handle == handle)
+ {
+ data->count++;
+ ddsrt_mutex_unlock (&impl->encode_decode_log_lock);
+ return;
+ }
+ elem = elem->next;
+ if (elem == elem0)
+ break;
+ }
+ }
+ /* add new entry */
+ struct crypto_encode_decode_data *new_data = ddsrt_malloc (sizeof (*new_data));
+ new_data->function = function;
+ new_data->handle = handle;
+ new_data->count = 1;
+ ddsrt_circlist_append(&impl->encode_decode_log, &new_data->e);
+ ddsrt_mutex_unlock (&impl->encode_decode_log_lock);
+}
+
+struct crypto_encode_decode_data * get_encode_decode_log (struct dds_security_cryptography_impl * impl, enum crypto_encode_decode_fn function, DDS_Security_long_long handle)
+{
+ ddsrt_mutex_lock (&impl->encode_decode_log_lock);
+ if (!ddsrt_circlist_isempty (&impl->encode_decode_log))
+ {
+ struct ddsrt_circlist_elem *elem0 = ddsrt_circlist_oldest (&impl->encode_decode_log), *elem = elem0;
+ while (elem != NULL)
+ {
+ struct crypto_encode_decode_data *data = DDSRT_FROM_CIRCLIST (struct crypto_encode_decode_data, e, elem);
+ if (data->function == function && data->handle == handle)
+ {
+ struct crypto_encode_decode_data *result = ddsrt_malloc (sizeof (*result));
+ memcpy (result, data, sizeof (*result));
+ ddsrt_mutex_unlock (&impl->encode_decode_log_lock);
+ return result;
+ }
+ elem = elem->next;
+ if (elem == elem0)
+ break;
+ }
+ }
+ ddsrt_mutex_unlock (&impl->encode_decode_log_lock);
+ return NULL;
+}
+
static unsigned char * find_buffer_match(const unsigned char *input, size_t input_len, const unsigned char *match, size_t match_len)
{
if (match_len <= input_len && match_len > 0 && input_len > 0)
@@ -705,6 +772,8 @@ static DDS_Security_boolean encode_datawriter_submessage(
switch (impl->parent->mode)
{
case PLUGIN_MODE_WRAPPED:
+ log_encode_decode (impl->parent, ENCODE_DATAWRITER_SUBMESSAGE, sending_datawriter_crypto);
+ /* fall-through */
case PLUGIN_MODE_TOKEN_LOG:
if (!impl->instance->encode_datawriter_submessage (impl->instance, encoded_rtps_submessage,
plain_rtps_submessage, check_handle (sending_datawriter_crypto), receiving_datareader_crypto_list, receiving_datareader_crypto_list_index, ex))
@@ -753,6 +822,8 @@ static DDS_Security_boolean encode_datareader_submessage(
switch (impl->parent->mode)
{
case PLUGIN_MODE_WRAPPED:
+ log_encode_decode (impl->parent, ENCODE_DATAREADER_SUBMESSAGE, sending_datareader_crypto);
+ /* fall-through */
case PLUGIN_MODE_TOKEN_LOG:
if (!impl->instance->encode_datareader_submessage (impl->instance, encoded_rtps_submessage,
plain_rtps_submessage, check_handle (sending_datareader_crypto), receiving_datawriter_crypto_list, ex))
@@ -850,6 +921,8 @@ static DDS_Security_boolean decode_datawriter_submessage(
switch (impl->parent->mode)
{
case PLUGIN_MODE_WRAPPED:
+ log_encode_decode (impl->parent, DECODE_DATAWRITER_SUBMESSAGE, receiving_datareader_crypto);
+ /* fall-through */
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->decode_datawriter_submessage (impl->instance, plain_rtps_submessage,
encoded_rtps_submessage, check_handle (receiving_datareader_crypto), check_handle (sending_datawriter_crypto), ex);
@@ -870,6 +943,8 @@ static DDS_Security_boolean decode_datareader_submessage(
switch (impl->parent->mode)
{
case PLUGIN_MODE_WRAPPED:
+ log_encode_decode (impl->parent, DECODE_DATAREADER_SUBMESSAGE, receiving_datawriter_crypto);
+ /* fall-through */
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->decode_datareader_submessage (impl->instance, plain_rtps_submessage,
encoded_rtps_submessage, check_handle (receiving_datawriter_crypto), check_handle (sending_datareader_crypto), ex);
@@ -1006,6 +1081,8 @@ int init_test_cryptography_wrapped(const char *argument, void **context, struct
if (!impl)
return DDS_SECURITY_FAILED;
impl->mode = PLUGIN_MODE_WRAPPED;
+ ddsrt_mutex_init (&impl->encode_decode_log_lock);
+ ddsrt_circlist_init (&impl->encode_decode_log);
*context = impl;
return DDS_SECURITY_SUCCESS;
}
@@ -1014,6 +1091,15 @@ int finalize_test_cryptography_wrapped(void *context)
{
struct dds_security_cryptography_impl* impl = (struct dds_security_cryptography_impl*) context;
assert(impl->mode == PLUGIN_MODE_WRAPPED);
+ ddsrt_mutex_lock (&impl->encode_decode_log_lock);
+ while (!ddsrt_circlist_isempty (&impl->encode_decode_log))
+ {
+ struct ddsrt_circlist_elem *list_elem = ddsrt_circlist_oldest (&impl->encode_decode_log);
+ ddsrt_circlist_remove (&impl->encode_decode_log, list_elem);
+ ddsrt_free (list_elem);
+ }
+ ddsrt_mutex_unlock (&impl->encode_decode_log_lock);
+ ddsrt_mutex_destroy (&impl->encode_decode_log_lock);
return finalize_test_cryptography_common(impl, true);
}
@@ -1043,12 +1129,12 @@ int32_t finalize_test_cryptography_store_tokens(void *context)
while (!ddsrt_circlist_isempty (&impl->token_data_list))
{
struct ddsrt_circlist_elem *list_elem = ddsrt_circlist_oldest (&impl->token_data_list);
- struct crypto_token_data *token_data = DDSRT_FROM_CIRCLIST (struct crypto_token_data, e, list_elem);
ddsrt_circlist_remove (&impl->token_data_list, list_elem);
- ddsrt_free (token_data);
+ ddsrt_free (list_elem);
}
ddsrt_mutex_unlock (&impl->token_data_lock);
ddsrt_mutex_destroy (&impl->token_data_lock);
+
/* don't detroy g_print_token_lock as this will result in multiple
calls to mutex_destroy for this lock in case of multiple domains */
diff --git a/src/security/core/tests/common/cryptography_wrapper.h b/src/security/core/tests/common/cryptography_wrapper.h
index b9384c9..d802247 100644
--- a/src/security/core/tests/common/cryptography_wrapper.h
+++ b/src/security/core/tests/common/cryptography_wrapper.h
@@ -43,6 +43,20 @@ struct crypto_token_data {
size_t data_len[CRYPTO_TOKEN_MAXLEN];
};
+enum crypto_encode_decode_fn {
+ ENCODE_DATAWRITER_SUBMESSAGE,
+ ENCODE_DATAREADER_SUBMESSAGE,
+ DECODE_DATAWRITER_SUBMESSAGE,
+ DECODE_DATAREADER_SUBMESSAGE
+};
+
+struct crypto_encode_decode_data {
+ struct ddsrt_circlist_elem e;
+ enum crypto_encode_decode_fn function;
+ DDS_Security_long_long handle;
+ uint32_t count;
+};
+
SECURITY_EXPORT void set_protection_kinds(
struct dds_security_cryptography_impl * impl,
DDS_Security_ProtectionKind rtps_protection_kind,
@@ -61,6 +75,7 @@ SECURITY_EXPORT void set_entity_data_secret(struct dds_security_cryptography_imp
SECURITY_EXPORT const char *get_crypto_token_type_str (enum crypto_tokens_type type);
SECURITY_EXPORT struct ddsrt_circlist * get_crypto_tokens (struct dds_security_cryptography_impl * impl);
SECURITY_EXPORT struct crypto_token_data * find_crypto_token (struct dds_security_cryptography_impl * impl, enum crypto_tokens_type type, unsigned char * data, size_t data_len);
+SECURITY_EXPORT struct crypto_encode_decode_data * get_encode_decode_log (struct dds_security_cryptography_impl * impl, enum crypto_encode_decode_fn function, DDS_Security_long_long handle);
/* Init in all-ok mode: all functions return success without calling the actual plugin */
SECURITY_EXPORT int init_test_cryptography_all_ok(const char *argument, void **context, struct ddsi_domaingv *gv);
diff --git a/src/security/core/tests/common/security_config_test_utils.c b/src/security/core/tests/common/security_config_test_utils.c
index d66ff2d..74f3e5e 100644
--- a/src/security/core/tests/common/security_config_test_utils.c
+++ b/src/security/core/tests/common/security_config_test_utils.c
@@ -29,6 +29,17 @@
#include "common/config_env.h"
#include "security_config_test_utils.h"
+static const char *topic_rule =
+ " "
+ " ${TOPIC_EXPRESSION}"
+ " ${ENABLE_DISC_PROTECTION}"
+ " ${ENABLE_LIVELINESS_PROTECTION}"
+ " ${ENABLE_READ_AC}"
+ " ${ENABLE_WRITE_AC}"
+ " ${METADATA_PROTECTION_KIND}"
+ " ${DATA_PROTECTION_KIND}"
+ " ";
+
static const char *governance_xml =
""
""
@@ -46,15 +57,7 @@ static const char *governance_xml =
" ${LIVELINESS_PROTECTION_KIND:-NONE}"
" ${RTPS_PROTECTION_KIND:-NONE}"
" "
- " "
- " *"
- " ${ENABLE_DISC_PROTECTION:-false}"
- " ${ENABLE_LIVELINESS_PROTECTION:-false}"
- " ${ENABLE_READ_AC:-true}"
- " ${ENABLE_WRITE_AC:-true}"
- " ${METADATA_PROTECTION_KIND:-NONE}"
- " ${DATA_PROTECTION_KIND:-NONE}"
- " "
+ " ${TOPIC_RULES}"
" "
" "
" "
@@ -207,11 +210,48 @@ static char * prefix_data (char * config_signed, bool add_prefix)
return config_signed;
}
-char * get_governance_config(struct kvp *config_vars, bool add_prefix)
+static void print_config_vars(struct kvp *vars)
{
- char * config = ddsrt_expand_vars (governance_xml, &expand_lookup_vars, config_vars);
+ for (uint32_t i = 0; vars[i].key != NULL; i++)
+ printf("%s=%s; ", vars[i].key, vars[i].value);
+}
+
+char * get_governance_topic_rule(const char * topic_expr, bool discovery_protection, bool liveliness_protection,
+ bool read_ac, bool write_ac, const char * metadata_protection_kind, const char * data_protection_kind)
+{
+ struct kvp vars[] = {
+ { "TOPIC_EXPRESSION", topic_expr != NULL ? topic_expr : "*", 1 },
+ { "ENABLE_DISC_PROTECTION", discovery_protection ? "true" : "false", 1 },
+ { "ENABLE_LIVELINESS_PROTECTION", liveliness_protection ? "true" : "false", 1 },
+ { "ENABLE_READ_AC", read_ac ? "true" : "false", 1 },
+ { "ENABLE_WRITE_AC", write_ac ? "true" : "false", 1 },
+ { "METADATA_PROTECTION_KIND", metadata_protection_kind != NULL ? metadata_protection_kind : "NONE", 1 },
+ { "DATA_PROTECTION_KIND", data_protection_kind != NULL ? data_protection_kind : "NONE", 1 },
+ { NULL, NULL, 0 }
+ };
+ return ddsrt_expand_vars (topic_rule, &expand_lookup_vars, vars);
+}
+
+char * get_governance_config(bool allow_unauth_pp, bool enable_join_ac, const char * discovery_protection_kind, const char * liveliness_protection_kind,
+ const char * rtps_protection_kind, const char * topic_rules, bool add_prefix)
+{
+ struct kvp vars[] = {
+ { "ALLOW_UNAUTH_PP", allow_unauth_pp ? "true" : "false", 1 },
+ { "ENABLE_JOIN_AC", enable_join_ac ? "true" : "false", 1 },
+ { "DISCOVERY_PROTECTION_KIND", discovery_protection_kind != NULL ? discovery_protection_kind : "NONE", 1 },
+ { "LIVELINESS_PROTECTION_KIND", liveliness_protection_kind != NULL ? liveliness_protection_kind : "NONE", 1 },
+ { "RTPS_PROTECTION_KIND", rtps_protection_kind != NULL ? rtps_protection_kind : "NONE", 1 },
+ { "TOPIC_RULES", topic_rules != NULL ? topic_rules : get_governance_topic_rule (NULL, false, false, false, false, NULL, NULL), 1 },
+ { NULL, NULL, 0 }
+ };
+ char * config = ddsrt_expand_vars (governance_xml, &expand_lookup_vars, vars);
char * config_signed = get_signed_data (config);
ddsrt_free (config);
+
+ printf("Governance configuration: ");
+ print_config_vars(vars);
+ printf("\n");
+
return prefix_data (config_signed, add_prefix);
}
diff --git a/src/security/core/tests/common/security_config_test_utils.h b/src/security/core/tests/common/security_config_test_utils.h
index 3cf20de..770c979 100644
--- a/src/security/core/tests/common/security_config_test_utils.h
+++ b/src/security/core/tests/common/security_config_test_utils.h
@@ -25,7 +25,11 @@ const char * expand_lookup_vars (const char *name, void * data);
const char * expand_lookup_vars_env (const char *name, void * data);
int32_t expand_lookup_unmatched (const struct kvp * lookup_table);
-char * get_governance_config (struct kvp *config_vars, bool add_prefix);
+char * get_governance_topic_rule(const char * topic_expr, bool discovery_protection, bool liveliness_protection,
+ bool read_ac, bool write_ac, const char * metadata_protection_kind, const char * data_protection_kind);
+char * get_governance_config(bool allow_unauth_pp, bool enable_join_ac, const char * discovery_protection_kind, const char * liveliness_protection_kind,
+ const char * rtps_protection_kind, const char * topic_rules, bool add_prefix);
+
char * get_permissions_topic(const char * name);
char * get_permissions_grant(const char * name, const char * subject, const char * domain_id,
dds_time_t not_before, dds_time_t not_after, const char * pub_topics, const char * sub_topics, const char * default_policy);
diff --git a/src/security/core/tests/common/test_utils.c b/src/security/core/tests/common/test_utils.c
index 3f94a85..99a4eaf 100644
--- a/src/security/core/tests/common/test_utils.c
+++ b/src/security/core/tests/common/test_utils.c
@@ -38,6 +38,12 @@ int numRemote = 0;
struct Handshake handshakeList[MAX_HANDSHAKES];
int numHandshake = 0;
+const char * g_pk_none = "NONE";
+const char * g_pk_sign = "SIGN";
+const char * g_pk_encrypt = "ENCRYPT";
+const char * g_pk_sign_oa = "SIGN_WITH_ORIGIN_AUTHENTICATION";
+const char * g_pk_encrypt_oa = "ENCRYPT_WITH_ORIGIN_AUTHENTICATION";
+
static char * get_validation_result_str (DDS_Security_ValidationResult_t result)
{
switch (result)
@@ -471,3 +477,29 @@ struct dds_security_cryptography_impl * get_crypto_context(dds_entity_t particip
dds_entity_unlock (pp_entity);
return context;
}
+
+const char * pk_to_str(DDS_Security_ProtectionKind pk)
+{
+ switch (pk)
+ {
+ case DDS_SECURITY_PROTECTION_KIND_NONE: return g_pk_none;
+ case DDS_SECURITY_PROTECTION_KIND_SIGN: return g_pk_sign;
+ case DDS_SECURITY_PROTECTION_KIND_ENCRYPT: return g_pk_encrypt;
+ case DDS_SECURITY_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION: return g_pk_sign_oa;
+ case DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION: return g_pk_encrypt_oa;
+ }
+ assert (false);
+ return NULL;
+}
+
+const char * bpk_to_str(DDS_Security_BasicProtectionKind bpk)
+{
+ switch (bpk)
+ {
+ case DDS_SECURITY_BASICPROTECTION_KIND_NONE: return g_pk_none;
+ case DDS_SECURITY_BASICPROTECTION_KIND_SIGN: return g_pk_sign;
+ case DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT: return g_pk_encrypt;
+ }
+ assert (false);
+ return NULL;
+}
diff --git a/src/security/core/tests/common/test_utils.h b/src/security/core/tests/common/test_utils.h
index 919affe..5fb9ccb 100644
--- a/src/security/core/tests/common/test_utils.h
+++ b/src/security/core/tests/common/test_utils.h
@@ -17,6 +17,15 @@
#include "dds/security/dds_security_api.h"
+#define PK_N DDS_SECURITY_PROTECTION_KIND_NONE
+#define PK_S DDS_SECURITY_PROTECTION_KIND_SIGN
+#define PK_SOA DDS_SECURITY_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION
+#define PK_E DDS_SECURITY_PROTECTION_KIND_ENCRYPT
+#define PK_EOA DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION
+#define BPK_N DDS_SECURITY_BASICPROTECTION_KIND_NONE
+#define BPK_S DDS_SECURITY_BASICPROTECTION_KIND_SIGN
+#define BPK_E DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT
+
#define MAX_LOCAL_IDENTITIES 8
#define MAX_REMOTE_IDENTITIES 8
#define MAX_HANDSHAKES 32
@@ -70,5 +79,7 @@ void rd_wr_init_fail(
bool exp_subtp_fail, bool exp_rd_fail);
void write_read_for(dds_entity_t wr, dds_entity_t pp_rd, dds_entity_t rd, dds_duration_t dur, bool exp_write_fail, bool exp_read_fail);
struct dds_security_cryptography_impl * get_crypto_context(dds_entity_t participant);
+const char * pk_to_str(DDS_Security_ProtectionKind pk);
+const char * bpk_to_str(DDS_Security_BasicProtectionKind bpk);
#endif /* SECURITY_CORE_TEST_UTILS_H_ */
diff --git a/src/security/core/tests/secure_communication.c b/src/security/core/tests/secure_communication.c
index 186944c..fb7386f 100644
--- a/src/security/core/tests/secure_communication.c
+++ b/src/security/core/tests/secure_communication.c
@@ -37,15 +37,6 @@
#include "SecurityCoreTests.h"
-#define PK_N DDS_SECURITY_PROTECTION_KIND_NONE
-#define PK_S DDS_SECURITY_PROTECTION_KIND_SIGN
-#define PK_SOA DDS_SECURITY_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION
-#define PK_E DDS_SECURITY_PROTECTION_KIND_ENCRYPT
-#define PK_EOA DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION
-#define BPK_N DDS_SECURITY_BASICPROTECTION_KIND_NONE
-#define BPK_S DDS_SECURITY_BASICPROTECTION_KIND_SIGN
-#define BPK_E DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT
-
static const char *config =
"${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
""
@@ -80,16 +71,6 @@ static const char *config =
#define MAX_DOMAINS 10
#define MAX_PARTICIPANTS 10
-const char * g_pk_none = "NONE";
-const char * g_pk_sign = "SIGN";
-const char * g_pk_encrypt = "ENCRYPT";
-const char * g_pk_sign_oa = "SIGN_WITH_ORIGIN_AUTHENTICATION";
-const char * g_pk_encrypt_oa = "ENCRYPT_WITH_ORIGIN_AUTHENTICATION";
-
-const char * g_pp_secret = "ppsecret";
-const char * g_groupdata_secret = "groupsecret";
-const char * g_ep_secret = "epsecret";
-
uint32_t g_topic_nr = 0;
static dds_entity_t g_pub_domains[MAX_DOMAINS];
@@ -116,37 +97,9 @@ typedef void (*set_crypto_params_fn)(struct dds_security_cryptography_impl *, co
typedef dds_entity_t (*pubsub_create_fn)(dds_entity_t, const dds_qos_t *qos, const dds_listener_t *listener);
typedef dds_entity_t (*ep_create_fn)(dds_entity_t, dds_entity_t, const dds_qos_t *qos, const dds_listener_t *listener);
-static const char * pk_to_str(DDS_Security_ProtectionKind pk)
-{
- switch (pk)
- {
- case DDS_SECURITY_PROTECTION_KIND_NONE: return g_pk_none;
- case DDS_SECURITY_PROTECTION_KIND_SIGN: return g_pk_sign;
- case DDS_SECURITY_PROTECTION_KIND_ENCRYPT: return g_pk_encrypt;
- case DDS_SECURITY_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION: return g_pk_sign_oa;
- case DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION: return g_pk_encrypt_oa;
- }
- assert (false);
- return NULL;
-}
-
-static const char * bpk_to_str(DDS_Security_BasicProtectionKind bpk)
-{
- switch (bpk)
- {
- case DDS_SECURITY_BASICPROTECTION_KIND_NONE: return g_pk_none;
- case DDS_SECURITY_BASICPROTECTION_KIND_SIGN: return g_pk_sign;
- case DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT: return g_pk_encrypt;
- }
- assert (false);
- return NULL;
-}
-
-static void print_config_vars(struct kvp *vars)
-{
- for (uint32_t i = 0; vars[i].key != NULL; i++)
- printf("%s=%s; ", vars[i].key, vars[i].value);
-}
+const char * g_pp_secret = "ppsecret";
+const char * g_groupdata_secret = "groupsecret";
+const char * g_ep_secret = "epsecret";
static dds_qos_t *get_qos()
{
@@ -201,20 +154,9 @@ static void test_init(const struct domain_sec_config * domain_config, size_t n_s
assert (n_pub_domains < MAX_DOMAINS);
assert (n_pub_participants < MAX_PARTICIPANTS);
- struct kvp governance_vars[] = {
- { "DISCOVERY_PROTECTION_KIND", pk_to_str (domain_config->discovery_pk), 1 },
- { "LIVELINESS_PROTECTION_KIND", pk_to_str (domain_config->liveliness_pk), 1 },
- { "RTPS_PROTECTION_KIND", pk_to_str (domain_config->rtps_pk), 1 },
- { "METADATA_PROTECTION_KIND", pk_to_str (domain_config->metadata_pk), 1 },
- { "DATA_PROTECTION_KIND", bpk_to_str (domain_config->payload_pk), 1 },
- { NULL, NULL, 0 }
- };
-
- printf("Governance configuration: ");
- print_config_vars(governance_vars);
- printf("\n");
-
- char * gov_config_signed = get_governance_config (governance_vars, false);
+ char * gov_topic_rule = get_governance_topic_rule ("*", false, false, true, true, pk_to_str (domain_config->metadata_pk), bpk_to_str (domain_config->payload_pk));
+ char * gov_config_signed = get_governance_config (false, false, pk_to_str (domain_config->discovery_pk), pk_to_str (domain_config->liveliness_pk),
+ pk_to_str (domain_config->rtps_pk), gov_topic_rule, false);
struct kvp config_vars[] = {
{ "GOVERNANCE_DATA", gov_config_signed, 1 },
@@ -232,6 +174,7 @@ static void test_init(const struct domain_sec_config * domain_config, size_t n_s
dds_free (conf_sub);
dds_free (gov_config_signed);
+ dds_free (gov_topic_rule);
}
static void test_fini(size_t n_sub_domain, size_t n_pub_domain)