From cf75263d1da2b326f5e4e152a2b5c131e3f75c18 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 11 May 2020 21:53:56 +0200 Subject: [PATCH] Add a test that validates that a plain message is not read by a remote reader in case payload/submsg/rtps encryption or signing is enabled Signed-off-by: Dennis Potman --- src/security/core/tests/CMakeLists.txt | 1 + .../core/tests/common/cryptography_wrapper.c | 133 ++++++++++++-- .../core/tests/common/cryptography_wrapper.h | 8 +- src/security/core/tests/crypto.c | 170 ++++++++++++++++++ 4 files changed, 298 insertions(+), 14 deletions(-) create mode 100644 src/security/core/tests/crypto.c diff --git a/src/security/core/tests/CMakeLists.txt b/src/security/core/tests/CMakeLists.txt index 299487e..19fc14a 100644 --- a/src/security/core/tests/CMakeLists.txt +++ b/src/security/core/tests/CMakeLists.txt @@ -79,6 +79,7 @@ if(ENABLE_SSL) "authentication.c" "access_control.c" "config.c" + "crypto.c" "handshake.c" "plugin_loading.c" "secure_communication.c" diff --git a/src/security/core/tests/common/cryptography_wrapper.c b/src/security/core/tests/common/cryptography_wrapper.c index 990e2c8..ada7591 100644 --- a/src/security/core/tests/common/cryptography_wrapper.c +++ b/src/security/core/tests/common/cryptography_wrapper.c @@ -33,7 +33,8 @@ enum crypto_plugin_mode { PLUGIN_MODE_ALL_OK, PLUGIN_MODE_MISSING_FUNC, PLUGIN_MODE_WRAPPED, - PLUGIN_MODE_TOKEN_LOG + PLUGIN_MODE_TOKEN_LOG, + PLUGIN_MODE_PLAIN_DATA }; struct dds_security_crypto_key_exchange_impl { @@ -76,6 +77,10 @@ struct dds_security_cryptography_impl { struct ddsrt_circlist token_data_list; ddsrt_mutex_t encode_decode_log_lock; struct ddsrt_circlist encode_decode_log; + bool force_plain_rtps; + bool force_plain_submsg; + bool force_plain_payload; + DDS_Security_DatawriterCryptoHandle force_plain_sender_handle; }; static DDS_Security_ParticipantCryptoHandle g_local_participant_handle = 0; @@ -120,6 +125,16 @@ void set_entity_data_secret(struct dds_security_cryptography_impl * impl, const impl->ep_secret = ep_secret; } +void set_force_plain_data(struct dds_security_cryptography_impl * impl, DDS_Security_DatawriterCryptoHandle handle, bool plain_rtps, bool plain_submsg, bool plain_payload) +{ + assert (impl); + assert (impl->mode == PLUGIN_MODE_PLAIN_DATA); + impl->force_plain_rtps = plain_rtps; + impl->force_plain_submsg = plain_submsg; + impl->force_plain_payload = plain_payload; + impl->force_plain_sender_handle = handle; +} + static bool check_crypto_tokens(const DDS_Security_DataHolderSeq *tokens) { bool result = true; @@ -371,6 +386,20 @@ static bool expect_encrypted_buffer (DDS_Security_ProtectionKind pk) return pk == DDS_SECURITY_PROTECTION_KIND_ENCRYPT || pk == DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION; } +static void copy_octetseq(DDS_Security_OctetSeq *encoded_submsg, const DDS_Security_OctetSeq *plain_submsg) +{ + encoded_submsg->_length = encoded_submsg->_maximum = plain_submsg->_length; + if (plain_submsg->_length > 0) + { + encoded_submsg->_buffer = ddsrt_malloc(encoded_submsg->_length); + memcpy(encoded_submsg->_buffer, plain_submsg->_buffer, encoded_submsg->_length); + } + else + { + encoded_submsg->_buffer = NULL; + } +} + /** * Crypto key exchange */ @@ -386,6 +415,7 @@ static DDS_Security_boolean create_local_participant_crypto_tokens( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: { DDS_Security_boolean ret = impl->instance->create_local_participant_crypto_tokens (impl->instance, local_participant_crypto_tokens, local_participant_crypto, remote_participant_crypto, ex); @@ -410,6 +440,7 @@ static DDS_Security_boolean set_remote_participant_crypto_tokens( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: { DDS_Security_boolean ret = impl->instance->set_remote_participant_crypto_tokens (impl->instance, check_handle (local_participant_crypto), check_handle (remote_participant_crypto), remote_participant_tokens, ex); @@ -434,6 +465,7 @@ static DDS_Security_boolean create_local_datawriter_crypto_tokens( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: { DDS_Security_boolean ret = impl->instance->create_local_datawriter_crypto_tokens (impl->instance, local_datawriter_crypto_tokens, check_handle (local_datawriter_crypto), check_handle (remote_datareader_crypto), ex); @@ -458,6 +490,7 @@ static DDS_Security_boolean set_remote_datawriter_crypto_tokens( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: { DDS_Security_boolean ret = impl->instance->set_remote_datawriter_crypto_tokens (impl->instance, check_handle (local_datareader_crypto), check_handle (remote_datawriter_crypto), remote_datawriter_tokens, ex); @@ -482,6 +515,7 @@ static DDS_Security_boolean create_local_datareader_crypto_tokens( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: { DDS_Security_boolean ret = impl->instance->create_local_datareader_crypto_tokens (impl->instance, local_datareader_cryto_tokens, check_handle (local_datareader_crypto), check_handle (remote_datawriter_crypto), ex); @@ -506,6 +540,7 @@ static DDS_Security_boolean set_remote_datareader_crypto_tokens( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: { DDS_Security_boolean ret = impl->instance->set_remote_datareader_crypto_tokens (impl->instance, check_handle (local_datawriter_crypto), check_handle (remote_datareader_crypto), remote_datareader_tokens, ex); @@ -528,6 +563,7 @@ static DDS_Security_boolean return_crypto_tokens( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return impl->instance->return_crypto_tokens (impl->instance, crypto_tokens, ex); default: return true; @@ -550,6 +586,7 @@ static DDS_Security_ParticipantCryptoHandle register_local_participant( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return check_handle (impl->instance->register_local_participant (impl->instance, check_handle (participant_identity), check_handle (participant_permissions), participant_properties, participant_security_attributes, ex)); default: @@ -570,6 +607,7 @@ static DDS_Security_ParticipantCryptoHandle register_matched_remote_participant( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return check_handle (impl->instance->register_matched_remote_participant (impl->instance, local_participant_crypto_handle, remote_participant_identity, remote_participant_permissions, shared_secret, ex)); default: @@ -589,6 +627,7 @@ static DDS_Security_DatawriterCryptoHandle register_local_datawriter( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return check_handle (impl->instance->register_local_datawriter (impl->instance, check_handle (participant_crypto), datawriter_properties, datawriter_security_attributes, ex)); default: @@ -609,6 +648,7 @@ static DDS_Security_DatareaderCryptoHandle register_matched_remote_datareader( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return check_handle (impl->instance->register_matched_remote_datareader (impl->instance, check_handle (local_datawriter_crypto_handle), check_handle (remote_participant_crypto), check_handle (shared_secret), relay_only, ex)); default: @@ -628,6 +668,7 @@ static DDS_Security_DatareaderCryptoHandle register_local_datareader( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return check_handle (impl->instance->register_local_datareader (impl->instance, check_handle (participant_crypto), datareader_properties, datareader_security_attributes, ex)); default: @@ -647,6 +688,7 @@ static DDS_Security_DatawriterCryptoHandle register_matched_remote_datawriter( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return check_handle (impl->instance->register_matched_remote_datawriter (impl->instance, check_handle (local_datareader_crypto_handle), check_handle (remote_participant_crypt), shared_secret, ex)); default: @@ -664,6 +706,7 @@ static DDS_Security_boolean unregister_participant( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return impl->instance->unregister_participant (impl->instance, check_handle (participant_crypto_handle), ex); default: return true; @@ -680,6 +723,7 @@ static DDS_Security_boolean unregister_datawriter( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return impl->instance->unregister_datawriter (impl->instance, check_handle (datawriter_crypto_handle), ex); default: return true; @@ -696,6 +740,7 @@ static DDS_Security_boolean unregister_datareader( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return impl->instance->unregister_datareader (impl->instance, check_handle (datareader_crypto_handle), ex); default: return true; @@ -716,6 +761,13 @@ static DDS_Security_boolean encode_serialized_payload( struct dds_security_crypto_transform_impl *impl = (struct dds_security_crypto_transform_impl *)instance; switch (impl->parent->mode) { + case PLUGIN_MODE_PLAIN_DATA: + if (impl->parent->force_plain_payload && impl->parent->force_plain_sender_handle == sending_datawriter_crypto) + { + copy_octetseq (encoded_buffer, plain_buffer); + return true; + } + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: { @@ -771,6 +823,15 @@ static DDS_Security_boolean encode_datawriter_submessage( struct dds_security_crypto_transform_impl *impl = (struct dds_security_crypto_transform_impl *)instance; switch (impl->parent->mode) { + case PLUGIN_MODE_PLAIN_DATA: + if (impl->parent->force_plain_submsg && impl->parent->force_plain_sender_handle == sending_datawriter_crypto) + { + copy_octetseq (encoded_rtps_submessage, plain_rtps_submessage); + assert (receiving_datareader_crypto_list->_length <= INT32_MAX); + *receiving_datareader_crypto_list_index = (int32_t) receiving_datareader_crypto_list->_length; + return true; + } + /* fall through */ case PLUGIN_MODE_WRAPPED: log_encode_decode (impl->parent, ENCODE_DATAWRITER_SUBMESSAGE, sending_datawriter_crypto); /* fall-through */ @@ -821,6 +882,13 @@ static DDS_Security_boolean encode_datareader_submessage( struct dds_security_crypto_transform_impl *impl = (struct dds_security_crypto_transform_impl *)instance; switch (impl->parent->mode) { + case PLUGIN_MODE_PLAIN_DATA: + if (impl->parent->force_plain_submsg && impl->parent->force_plain_sender_handle == sending_datareader_crypto) + { + copy_octetseq (encoded_rtps_submessage, plain_rtps_submessage); + return true; + } + /* fall through */ case PLUGIN_MODE_WRAPPED: log_encode_decode (impl->parent, ENCODE_DATAREADER_SUBMESSAGE, sending_datareader_crypto); /* fall-through */ @@ -846,6 +914,15 @@ static DDS_Security_boolean encode_rtps_message( struct dds_security_crypto_transform_impl *impl = (struct dds_security_crypto_transform_impl *)instance; switch (impl->parent->mode) { + case PLUGIN_MODE_PLAIN_DATA: + if (impl->parent->force_plain_rtps) + { + copy_octetseq (encoded_rtps_message, plain_rtps_message); + assert (receiving_participant_crypto_list->_length <= INT32_MAX); + *receiving_participant_crypto_list_index = (int32_t) receiving_participant_crypto_list->_length; + return true; + } + /* fall through */ case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: if (!impl->instance->encode_rtps_message (impl->instance, encoded_rtps_message, @@ -880,6 +957,7 @@ static DDS_Security_boolean decode_rtps_message( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return impl->instance->decode_rtps_message (impl->instance, plain_buffer, encoded_buffer, check_handle (receiving_participant_crypto), check_handle (sending_participant_crypto), ex); default: @@ -902,6 +980,7 @@ static DDS_Security_boolean preprocess_secure_submsg( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return impl->instance->preprocess_secure_submsg (impl->instance, datawriter_crypto, datareader_crypto, secure_submessage_category, encoded_rtps_submessage, check_handle (receiving_participant_crypto), check_handle (sending_participant_crypto), ex); default: @@ -920,6 +999,7 @@ static DDS_Security_boolean decode_datawriter_submessage( struct dds_security_crypto_transform_impl *impl = (struct dds_security_crypto_transform_impl *)instance; switch (impl->parent->mode) { + case PLUGIN_MODE_PLAIN_DATA: case PLUGIN_MODE_WRAPPED: log_encode_decode (impl->parent, DECODE_DATAWRITER_SUBMESSAGE, receiving_datareader_crypto); /* fall-through */ @@ -942,6 +1022,7 @@ static DDS_Security_boolean decode_datareader_submessage( struct dds_security_crypto_transform_impl *impl = (struct dds_security_crypto_transform_impl *)instance; switch (impl->parent->mode) { + case PLUGIN_MODE_PLAIN_DATA: case PLUGIN_MODE_WRAPPED: log_encode_decode (impl->parent, DECODE_DATAREADER_SUBMESSAGE, receiving_datawriter_crypto); /* fall-through */ @@ -967,6 +1048,7 @@ static DDS_Security_boolean decode_serialized_payload( { case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_TOKEN_LOG: + case PLUGIN_MODE_PLAIN_DATA: return impl->instance->decode_serialized_payload(impl->instance, plain_buffer, encoded_buffer, inline_qos, check_handle (receiving_datareader_crypto), check_handle (sending_datawriter_crypto), ex); default: @@ -1075,22 +1157,14 @@ int finalize_test_cryptography_missing_func(void *context) return finalize_test_cryptography_common(impl, false); } -int init_test_cryptography_wrapped(const char *argument, void **context, struct ddsi_domaingv *gv) +static void init_encode_decode_log(struct dds_security_cryptography_impl *impl) { - struct dds_security_cryptography_impl *impl = init_test_cryptography_common(argument, true, gv); - 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; } -int finalize_test_cryptography_wrapped(void *context) +static void fini_encode_decode_log(struct dds_security_cryptography_impl *impl) { - 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)) { @@ -1100,6 +1174,24 @@ int finalize_test_cryptography_wrapped(void *context) } ddsrt_mutex_unlock (&impl->encode_decode_log_lock); ddsrt_mutex_destroy (&impl->encode_decode_log_lock); +} + +int init_test_cryptography_wrapped(const char *argument, void **context, struct ddsi_domaingv *gv) +{ + struct dds_security_cryptography_impl *impl = init_test_cryptography_common(argument, true, gv); + if (!impl) + return DDS_SECURITY_FAILED; + impl->mode = PLUGIN_MODE_WRAPPED; + init_encode_decode_log(impl); + *context = impl; + return DDS_SECURITY_SUCCESS; +} + +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); + fini_encode_decode_log(impl); return finalize_test_cryptography_common(impl, true); } @@ -1141,3 +1233,22 @@ int32_t finalize_test_cryptography_store_tokens(void *context) return finalize_test_cryptography_common(impl, true); } +int init_test_cryptography_plain_data(const char *argument, void **context, struct ddsi_domaingv *gv) +{ + struct dds_security_cryptography_impl *impl = init_test_cryptography_common(argument, true, gv); + if (!impl) + return DDS_SECURITY_FAILED; + impl->mode = PLUGIN_MODE_PLAIN_DATA; + init_encode_decode_log(impl); + *context = impl; + return DDS_SECURITY_SUCCESS; +} + +int finalize_test_cryptography_plain_data(void *context) +{ + struct dds_security_cryptography_impl* impl = (struct dds_security_cryptography_impl*) context; + assert(impl->mode == PLUGIN_MODE_PLAIN_DATA); + fini_encode_decode_log(impl); + return finalize_test_cryptography_common(impl, true); +} + diff --git a/src/security/core/tests/common/cryptography_wrapper.h b/src/security/core/tests/common/cryptography_wrapper.h index d802247..98a6658 100644 --- a/src/security/core/tests/common/cryptography_wrapper.h +++ b/src/security/core/tests/common/cryptography_wrapper.h @@ -62,15 +62,13 @@ SECURITY_EXPORT void set_protection_kinds( DDS_Security_ProtectionKind rtps_protection_kind, DDS_Security_ProtectionKind metadata_protection_kind, DDS_Security_BasicProtectionKind payload_protection_kind); - SECURITY_EXPORT void set_encrypted_secret(struct dds_security_cryptography_impl * impl, const char * secret); - SECURITY_EXPORT void set_disc_protection_kinds( struct dds_security_cryptography_impl * impl, DDS_Security_ProtectionKind disc_protection_kind, DDS_Security_ProtectionKind liveliness_protection_kind); - SECURITY_EXPORT void set_entity_data_secret(struct dds_security_cryptography_impl * impl, const char * pp_secret, const char * groupdata_secret, const char * ep_secret); +SECURITY_EXPORT void set_force_plain_data(struct dds_security_cryptography_impl * impl, DDS_Security_DatawriterCryptoHandle wr_handle, bool plain_rtps, bool plain_submsg, bool plain_payload); 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); @@ -93,4 +91,8 @@ SECURITY_EXPORT int finalize_test_cryptography_wrapped(void *context); SECURITY_EXPORT int32_t init_test_cryptography_store_tokens(const char *argument, void **context, struct ddsi_domaingv *gv); SECURITY_EXPORT int32_t finalize_test_cryptography_store_tokens(void *context); +/* Init in plain-data mode (force plain data for payload, submsg and/or rtps) */ +SECURITY_EXPORT int init_test_cryptography_plain_data(const char *argument, void **context, struct ddsi_domaingv *gv); +SECURITY_EXPORT int finalize_test_cryptography_plain_data(void *context); + #endif /* SECURITY_CORE_TEST_CRYPTO_WRAPPER_H_ */ diff --git a/src/security/core/tests/crypto.c b/src/security/core/tests/crypto.c new file mode 100644 index 0000000..098b0d7 --- /dev/null +++ b/src/security/core/tests/crypto.c @@ -0,0 +1,170 @@ +/* + * Copyright(c) 2006 to 2020 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include + +#include "dds/dds.h" +#include "CUnit/Test.h" +#include "CUnit/Theory.h" + +#include "dds/version.h" +#include "dds/ddsrt/cdtors.h" +#include "dds/ddsrt/environ.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/string.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/security/dds_security_api.h" + +#include "common/config_env.h" +#include "common/cryptography_wrapper.h" +#include "common/test_utils.h" +#include "common/security_config_test_utils.h" +#include "common/test_identity.h" +#include "common/cert_utils.h" + +static const char *config = + "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}" + "" + " " + " 0" + " \\${CYCLONEDDS_PID}" + " " + " " + " " + " " + " data:,${TEST_IDENTITY_CERTIFICATE}" + " data:,${TEST_IDENTITY_PRIVATE_KEY}" + " data:,${TEST_IDENTITY_CA_CERTIFICATE}" + " " + " " + " " + " " + " file:" COMMON_ETC_PATH("default_permissions_ca.pem") "" + " " + " " + " " + " " + " " + " " + ""; + +#define DDS_DOMAINID1 0 +#define DDS_DOMAINID2 1 + +static dds_entity_t g_domain1; +static dds_entity_t g_participant1; +static dds_entity_t g_domain2; +static dds_entity_t g_participant2; + +static uint32_t g_topic_nr = 0; + +static void init_domain_pp (dds_domainid_t domain_id, const char *id_cert, const char * id_key, const char * id_ca, + const char * gov_config, const char * perm_config, const char * crypto_init, const char * crypto_fini, dds_entity_t *domain, dds_entity_t *pp) +{ + struct kvp config_vars[] = + { + { "TEST_IDENTITY_CERTIFICATE", id_cert, 1 }, + { "TEST_IDENTITY_PRIVATE_KEY", id_key, 1 }, + { "TEST_IDENTITY_CA_CERTIFICATE", id_ca, 1 }, + { "PERMISSIONS_CONFIG", perm_config, 1 }, + { "GOVERNANCE_CONFIG", gov_config, 1 }, + { "CRYPTO_INIT", crypto_init, 1 }, + { "CRYPTO_FINI", crypto_fini, 1 }, + { NULL, NULL, 0 } + }; + char *conf = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars); + CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars), 0); + *domain = dds_create_domain (domain_id, conf); + *pp = dds_create_participant (domain_id, NULL, NULL); + CU_ASSERT_FATAL (*pp > 0); + ddsrt_free (conf); +} + +static void crypto_init ( + const char * gov_config1, const char * perm_config1, const char * id_cert1, const char * id_key1, const char * crypto_init1, const char * crypto_fini1, + const char * gov_config2, const char * perm_config2, const char * id_cert2, const char * id_key2, const char * crypto_init2, const char * crypto_fini2, + const char * id_ca) +{ + init_domain_pp (DDS_DOMAINID1, id_cert1, id_key1, id_ca, gov_config1, perm_config1, crypto_init1, crypto_fini1, &g_domain1, &g_participant1); + init_domain_pp (DDS_DOMAINID2, id_cert2, id_key2, id_ca, gov_config2, perm_config2, crypto_init2, crypto_fini2, &g_domain2, &g_participant2); +} + +static void crypto_fini (void * res[], size_t nres) +{ + CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain1), DDS_RETCODE_OK); + CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain2), DDS_RETCODE_OK); + if (res != NULL) + { + for (size_t i = 0; i < nres; i++) + ddsrt_free (res[i]); + } +} + +CU_TheoryDataPoints(ddssec_crypto, inject_plain_data) = { + CU_DataPoints(const char *, + /* */"payload encrypt", + /* | */"payload sign", + /* | | */"submessage encrypt", + /* | | | */"submessage sign", + /* | | | | */"rtps encrypt", + /* | | | | | */"rtps sign"), + CU_DataPoints(DDS_Security_BasicProtectionKind, BPK_E, BPK_S, BPK_N, BPK_N, BPK_N, BPK_N), /* payload protection */ + CU_DataPoints(DDS_Security_ProtectionKind, PK_N, PK_N, PK_E, PK_S, PK_N, PK_N), /* submessage protection */ + CU_DataPoints(DDS_Security_ProtectionKind, PK_N, PK_N, PK_N, PK_N, PK_E, PK_S), /* rtps protection */ +}; +CU_Theory((const char * test_descr, DDS_Security_BasicProtectionKind payload_pk, DDS_Security_ProtectionKind submsg_pk, DDS_Security_ProtectionKind rtps_pk), + ddssec_crypto, inject_plain_data, .timeout=30) +{ + print_test_msg ("running test inject_plain_data: %s\n", test_descr); + + char topic_name[100]; + create_topic_name ("ddssec_crypto_", g_topic_nr++, topic_name, sizeof (topic_name)); + + char *ca, *id1, *id1_subj, *id2, *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); + + char * grants[] = { + get_permissions_default_grant ("id1", id1_subj, topic_name), + get_permissions_default_grant ("id2", id2_subj, topic_name) }; + char * perm_config = get_permissions_config (grants, 2, true); + + char * gov_topic_rule = get_governance_topic_rule (topic_name, false, false, false, false, submsg_pk, payload_pk); + char * gov_config = get_governance_config (false, true, PK_N, PK_N, rtps_pk, gov_topic_rule, true); + + crypto_init ( + gov_config, perm_config, id1, TEST_IDENTITY1_PRIVATE_KEY, "init_test_cryptography_plain_data", "finalize_test_cryptography_plain_data", + gov_config, perm_config, id2, TEST_IDENTITY1_PRIVATE_KEY, "init_test_cryptography_wrapped", "finalize_test_cryptography_wrapped", + ca); + + dds_entity_t pub, sub, pub_tp, sub_tp, wr, rd; + rd_wr_init (g_participant1, &pub, &pub_tp, &wr, g_participant2, &sub, &sub_tp, &rd, topic_name); + + /* set forced plain data for payload/submsg/rtps */ + DDS_Security_DatawriterCryptoHandle wr_handle = get_writer_crypto_handle (wr); + struct dds_security_cryptography_impl * crypto_impl = get_crypto_context (g_participant1); + set_force_plain_data (crypto_impl, wr_handle, rtps_pk != PK_N, submsg_pk != PK_N, payload_pk != BPK_N); + + /* sync and write/take sample */ + sync_writer_to_readers (g_participant1, wr, 1, DDS_SECS (2)); + write_read_for (wr, g_participant2, rd, DDS_MSECS (10), false, true); + + /* reset forced plain data */ + set_force_plain_data (crypto_impl, wr_handle, false, false, false); + + crypto_fini ((void * []) { gov_config, gov_topic_rule, grants[0], grants[1], perm_config, ca, id1_subj, id1, id2_subj, id2 }, 10); +}