Add crypto token exchange test

Introduced a test that checks if all crypto tokens send by a node are
received correctly by the remote node. To support this test, the crypto
wrapper plugin is extended with a token_log mode, that stores all tokens
that are exchanged after the security handshake is finished.

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
This commit is contained in:
Dennis Potman 2020-04-22 16:59:29 +02:00 committed by eboasson
parent 82af49172d
commit fd27604a26
7 changed files with 412 additions and 107 deletions

View file

@ -34,7 +34,6 @@
#include "common/security_config_test_utils.h" #include "common/security_config_test_utils.h"
#include "common/test_identity.h" #include "common/test_identity.h"
#include "common/cert_utils.h" #include "common/cert_utils.h"
#include "common/security_config_test_utils.h"
#define ID1 TEST_IDENTITY1_CERTIFICATE #define ID1 TEST_IDENTITY1_CERTIFICATE
#define ID1K TEST_IDENTITY1_PRIVATE_KEY #define ID1K TEST_IDENTITY1_PRIVATE_KEY

View file

@ -13,6 +13,7 @@
#include <stdio.h> #include <stdio.h>
#include "CUnit/Test.h" #include "CUnit/Test.h"
#include "dds/dds.h" #include "dds/dds.h"
#include "dds/ddsrt/circlist.h"
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/sync.h" #include "dds/ddsrt/sync.h"
#include "dds/ddsrt/string.h" #include "dds/ddsrt/string.h"
@ -22,13 +23,17 @@
#include "dds/security/core/dds_security_utils.h" #include "dds/security/core/dds_security_utils.h"
#include "cryptography_wrapper.h" #include "cryptography_wrapper.h"
int init_crypto(const char *argument, void **context, struct ddsi_domaingv *gv); #define CRYPTO_TOKEN_CLASS_ID "DDS:Crypto:AES_GCM_GMAC"
int finalize_crypto(void *context); #define CRYPTO_TOKEN_PROPERTY_NAME "dds.cryp.keymat"
int32_t init_crypto(const char *argument, void **context, struct ddsi_domaingv *gv);
int32_t finalize_crypto(void *context);
enum crypto_plugin_mode { enum crypto_plugin_mode {
PLUGIN_MODE_ALL_OK, PLUGIN_MODE_ALL_OK,
PLUGIN_MODE_MISSING_FUNC, PLUGIN_MODE_MISSING_FUNC,
PLUGIN_MODE_WRAPPED PLUGIN_MODE_WRAPPED,
PLUGIN_MODE_TOKEN_LOG
}; };
struct dds_security_crypto_key_exchange_impl { struct dds_security_crypto_key_exchange_impl {
@ -67,9 +72,13 @@ struct dds_security_cryptography_impl {
const char * groupdata_secret; const char * groupdata_secret;
const char * ep_secret; const char * ep_secret;
const char * encrypted_secret; const char * encrypted_secret;
ddsrt_mutex_t token_data_lock;
struct ddsrt_circlist token_data_list;
}; };
static DDS_Security_ParticipantCryptoHandle g_local_participant_handle = 0; static DDS_Security_ParticipantCryptoHandle g_local_participant_handle = 0;
static ddsrt_once_t lock_inited = DDSRT_ONCE_INIT;
static ddsrt_mutex_t g_print_token_lock;
void set_protection_kinds( void set_protection_kinds(
struct dds_security_cryptography_impl * impl, struct dds_security_cryptography_impl * impl,
@ -109,6 +118,144 @@ void set_entity_data_secret(struct dds_security_cryptography_impl * impl, const
impl->ep_secret = ep_secret; impl->ep_secret = ep_secret;
} }
static bool check_crypto_tokens(const DDS_Security_DataHolderSeq *tokens)
{
bool result = true;
if (tokens->_length == 0 || tokens->_buffer == NULL)
return false;
for (uint32_t i = 0; result && (i < tokens->_length); i++)
{
result = (tokens->_buffer[i].class_id != NULL &&
strcmp(CRYPTO_TOKEN_CLASS_ID, tokens->_buffer[i].class_id) == 0 &&
tokens->_buffer[i].binary_properties._length == 1 &&
tokens->_buffer[i].binary_properties._buffer != NULL &&
tokens->_buffer[i].binary_properties._buffer[0].name != NULL &&
strcmp(CRYPTO_TOKEN_PROPERTY_NAME, tokens->_buffer[i].binary_properties._buffer[0].name) == 0 &&
tokens->_buffer[i].binary_properties._buffer[0].value._length > 0 &&
tokens->_buffer[i].binary_properties._buffer[0].value._buffer != NULL);
}
return result;
}
const char *get_crypto_token_type_str (enum crypto_tokens_type type)
{
switch (type)
{
case LOCAL_PARTICIPANT_TOKENS: return "LOCAL_PARTICIPANT_TOKENS";
case LOCAL_WRITER_TOKENS: return "LOCAL_WRITER_TOKENS";
case LOCAL_READER_TOKENS: return "LOCAL_READER_TOKENS";
case REMOTE_PARTICIPANT_TOKENS: return "REMOTE_PARTICIPANT_TOKENS";
case REMOTE_WRITER_TOKENS: return "REMOTE_WRITER_TOKENS";
case REMOTE_READER_TOKENS: return "REMOTE_READER_TOKENS";
default: assert (0); return "";
}
}
static void print_tokens (enum crypto_tokens_type type, const DDS_Security_ParticipantCryptoHandle lch, const DDS_Security_ParticipantCryptoHandle rch,
const DDS_Security_ParticipantCryptoTokenSeq *tokens)
{
ddsrt_mutex_lock (&g_print_token_lock);
printf ("Token type %s, local %"PRIx64" / remote %"PRIx64", count: %u\n", get_crypto_token_type_str (type), lch, rch, tokens->_length);
for (uint32_t i = 0; i < tokens->_length; i++)
{
printf ("- token: ");
for (uint32_t j = 0; j < tokens->_buffer[i].binary_properties._buffer[0].value._length && j < 32; j++)
printf ("%02x", tokens->_buffer[i].binary_properties._buffer[0].value._buffer[j]);
printf ("\n");
}
printf ("\n");
ddsrt_mutex_unlock (&g_print_token_lock);
}
static void add_tokens (struct ddsrt_circlist *list, enum crypto_tokens_type type,
const DDS_Security_ParticipantCryptoHandle lch, const DDS_Security_ParticipantCryptoHandle rch,
const DDS_Security_ParticipantCryptoTokenSeq *tokens)
{
struct crypto_token_data *token_data = ddsrt_malloc (sizeof (*token_data));
token_data->type = type;
token_data->local_handle = lch;
token_data->remote_handle = rch;
token_data->n_tokens = tokens->_length;
assert (tokens->_length <= CRYPTO_TOKEN_MAXLEN);
for (uint32_t i = 0; i < tokens->_length; i++)
{
size_t len = tokens->_buffer[i].binary_properties._buffer[0].value._length;
assert (len <= CRYPTO_TOKEN_SIZE);
memcpy (token_data->data[i], tokens->_buffer[i].binary_properties._buffer[0].value._buffer, len);
token_data->data_len[i] = len;
}
ddsrt_circlist_append(list, &token_data->e);
}
static void store_tokens (struct dds_security_crypto_key_exchange_impl *impl, enum crypto_tokens_type type, const DDS_Security_ParticipantCryptoHandle lch,
const DDS_Security_ParticipantCryptoHandle rch, const DDS_Security_ParticipantCryptoTokenSeq *tokens)
{
if (!check_crypto_tokens ((const DDS_Security_DataHolderSeq *) tokens))
{
printf ("%d ERROR\n", type);
return;
}
ddsrt_mutex_lock (&impl->parent->token_data_lock);
add_tokens (&impl->parent->token_data_list, type, lch, rch, tokens);
ddsrt_mutex_unlock (&impl->parent->token_data_lock);
print_tokens (type, lch, rch, tokens);
}
struct ddsrt_circlist * get_crypto_tokens (struct dds_security_cryptography_impl * impl)
{
struct ddsrt_circlist *tokens = ddsrt_malloc (sizeof (*tokens));
ddsrt_circlist_init (tokens);
ddsrt_mutex_lock (&impl->token_data_lock);
struct ddsrt_circlist_elem *elem0 = ddsrt_circlist_oldest (&impl->token_data_list), *elem = elem0;
while (elem != NULL)
{
struct crypto_token_data *elem_data = DDSRT_FROM_CIRCLIST (struct crypto_token_data, e, elem);
struct crypto_token_data *token_data = ddsrt_malloc (sizeof (*token_data));
memcpy (token_data, elem_data, sizeof (*token_data));
ddsrt_circlist_append (tokens, &token_data->e);
elem = elem->next;
if (elem == elem0)
break;
}
ddsrt_mutex_unlock (&impl->token_data_lock);
return tokens;
}
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)
{
assert (data_len <= CRYPTO_TOKEN_SIZE);
ddsrt_mutex_lock (&impl->token_data_lock);
struct ddsrt_circlist_elem *elem0 = ddsrt_circlist_oldest (&impl->token_data_list), *elem = elem0;
while (elem != NULL)
{
struct crypto_token_data *elem_data = DDSRT_FROM_CIRCLIST (struct crypto_token_data, e, elem);
if (elem_data->type == type)
{
for (uint32_t i = 0; i < elem_data->n_tokens; i++)
{
size_t len = elem_data->data_len[i];
assert (len <= CRYPTO_TOKEN_SIZE);
if (!memcmp (data, elem_data->data[i], data_len < len ? data_len : len))
{
ddsrt_mutex_unlock (&impl->token_data_lock);
return elem_data;
}
}
}
elem = elem->next;
if (elem == elem0)
break;
}
ddsrt_mutex_unlock (&impl->token_data_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) 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) if (match_len <= input_len && match_len > 0 && input_len > 0)
@ -171,8 +318,14 @@ static DDS_Security_boolean create_local_participant_crypto_tokens(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
return impl->instance->create_local_participant_crypto_tokens (impl->instance, local_participant_crypto_tokens, case PLUGIN_MODE_TOKEN_LOG:
{
DDS_Security_boolean ret = impl->instance->create_local_participant_crypto_tokens (impl->instance, local_participant_crypto_tokens,
local_participant_crypto, remote_participant_crypto, ex); local_participant_crypto, remote_participant_crypto, ex);
if (ret && impl->parent->mode == PLUGIN_MODE_TOKEN_LOG)
store_tokens (impl, LOCAL_PARTICIPANT_TOKENS, local_participant_crypto, remote_participant_crypto, local_participant_crypto_tokens);
return ret;
}
default: default:
return true; return true;
} }
@ -189,8 +342,14 @@ static DDS_Security_boolean set_remote_participant_crypto_tokens(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
return impl->instance->set_remote_participant_crypto_tokens (impl->instance, check_handle (local_participant_crypto), case PLUGIN_MODE_TOKEN_LOG:
{
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); check_handle (remote_participant_crypto), remote_participant_tokens, ex);
if (ret && impl->parent->mode == PLUGIN_MODE_TOKEN_LOG)
store_tokens (impl, REMOTE_PARTICIPANT_TOKENS, local_participant_crypto, remote_participant_crypto, remote_participant_tokens);
return ret;
}
default: default:
return true; return true;
} }
@ -207,8 +366,14 @@ static DDS_Security_boolean create_local_datawriter_crypto_tokens(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
return impl->instance->create_local_datawriter_crypto_tokens (impl->instance, local_datawriter_crypto_tokens, case PLUGIN_MODE_TOKEN_LOG:
{
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); check_handle (local_datawriter_crypto), check_handle (remote_datareader_crypto), ex);
if (ret && impl->parent->mode == PLUGIN_MODE_TOKEN_LOG)
store_tokens (impl, LOCAL_WRITER_TOKENS, local_datawriter_crypto, remote_datareader_crypto, local_datawriter_crypto_tokens);
return ret;
}
default: default:
return true; return true;
} }
@ -225,8 +390,14 @@ static DDS_Security_boolean set_remote_datawriter_crypto_tokens(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
return impl->instance->set_remote_datawriter_crypto_tokens (impl->instance, check_handle (local_datareader_crypto), case PLUGIN_MODE_TOKEN_LOG:
{
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); check_handle (remote_datawriter_crypto), remote_datawriter_tokens, ex);
if (ret && impl->parent->mode == PLUGIN_MODE_TOKEN_LOG)
store_tokens (impl, REMOTE_WRITER_TOKENS, local_datareader_crypto, remote_datawriter_crypto, remote_datawriter_tokens);
return ret;
}
default: default:
return true; return true;
} }
@ -243,8 +414,14 @@ static DDS_Security_boolean create_local_datareader_crypto_tokens(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
return impl->instance->create_local_datareader_crypto_tokens (impl->instance, local_datareader_cryto_tokens, case PLUGIN_MODE_TOKEN_LOG:
{
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); check_handle (local_datareader_crypto), check_handle (remote_datawriter_crypto), ex);
if (ret && impl->parent->mode == PLUGIN_MODE_TOKEN_LOG)
store_tokens (impl, LOCAL_READER_TOKENS, local_datareader_crypto, remote_datawriter_crypto, local_datareader_cryto_tokens);
return ret;
}
default: default:
return true; return true;
} }
@ -261,8 +438,14 @@ static DDS_Security_boolean set_remote_datareader_crypto_tokens(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
return impl->instance->set_remote_datareader_crypto_tokens (impl->instance, check_handle (local_datawriter_crypto), case PLUGIN_MODE_TOKEN_LOG:
{
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); check_handle (remote_datareader_crypto), remote_datareader_tokens, ex);
if (ret && impl->parent->mode == PLUGIN_MODE_TOKEN_LOG)
store_tokens (impl, REMOTE_READER_TOKENS, local_datawriter_crypto, remote_datareader_crypto, remote_datareader_tokens);
return ret;
}
default: default:
return true; return true;
} }
@ -277,6 +460,7 @@ static DDS_Security_boolean return_crypto_tokens(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->return_crypto_tokens (impl->instance, crypto_tokens, ex); return impl->instance->return_crypto_tokens (impl->instance, crypto_tokens, ex);
default: default:
return true; return true;
@ -298,6 +482,7 @@ static DDS_Security_ParticipantCryptoHandle register_local_participant(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return check_handle (impl->instance->register_local_participant (impl->instance, check_handle (participant_identity), return check_handle (impl->instance->register_local_participant (impl->instance, check_handle (participant_identity),
check_handle (participant_permissions), participant_properties, participant_security_attributes, ex)); check_handle (participant_permissions), participant_properties, participant_security_attributes, ex));
default: default:
@ -317,6 +502,7 @@ static DDS_Security_ParticipantCryptoHandle register_matched_remote_participant(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return check_handle (impl->instance->register_matched_remote_participant (impl->instance, local_participant_crypto_handle, return check_handle (impl->instance->register_matched_remote_participant (impl->instance, local_participant_crypto_handle,
remote_participant_identity, remote_participant_permissions, shared_secret, ex)); remote_participant_identity, remote_participant_permissions, shared_secret, ex));
default: default:
@ -335,6 +521,7 @@ static DDS_Security_DatawriterCryptoHandle register_local_datawriter(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return check_handle (impl->instance->register_local_datawriter (impl->instance, check_handle (participant_crypto), return check_handle (impl->instance->register_local_datawriter (impl->instance, check_handle (participant_crypto),
datawriter_properties, datawriter_security_attributes, ex)); datawriter_properties, datawriter_security_attributes, ex));
default: default:
@ -354,6 +541,7 @@ static DDS_Security_DatareaderCryptoHandle register_matched_remote_datareader(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return check_handle (impl->instance->register_matched_remote_datareader (impl->instance, check_handle (local_datawriter_crypto_handle), 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)); check_handle (remote_participant_crypto), check_handle (shared_secret), relay_only, ex));
default: default:
@ -372,6 +560,7 @@ static DDS_Security_DatareaderCryptoHandle register_local_datareader(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return check_handle (impl->instance->register_local_datareader (impl->instance, check_handle (participant_crypto), return check_handle (impl->instance->register_local_datareader (impl->instance, check_handle (participant_crypto),
datareader_properties, datareader_security_attributes, ex)); datareader_properties, datareader_security_attributes, ex));
default: default:
@ -390,6 +579,7 @@ static DDS_Security_DatawriterCryptoHandle register_matched_remote_datawriter(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return check_handle (impl->instance->register_matched_remote_datawriter (impl->instance, check_handle (local_datareader_crypto_handle), 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)); check_handle (remote_participant_crypt), shared_secret, ex));
default: default:
@ -406,6 +596,7 @@ static DDS_Security_boolean unregister_participant(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->unregister_participant (impl->instance, check_handle (participant_crypto_handle), ex); return impl->instance->unregister_participant (impl->instance, check_handle (participant_crypto_handle), ex);
default: default:
return true; return true;
@ -421,6 +612,7 @@ static DDS_Security_boolean unregister_datawriter(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->unregister_datawriter (impl->instance, check_handle (datawriter_crypto_handle), ex); return impl->instance->unregister_datawriter (impl->instance, check_handle (datawriter_crypto_handle), ex);
default: default:
return true; return true;
@ -436,6 +628,7 @@ static DDS_Security_boolean unregister_datareader(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->unregister_datareader (impl->instance, check_handle (datareader_crypto_handle), ex); return impl->instance->unregister_datareader (impl->instance, check_handle (datareader_crypto_handle), ex);
default: default:
return true; return true;
@ -457,6 +650,7 @@ static DDS_Security_boolean encode_serialized_payload(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
{ {
if (!impl->instance->encode_serialized_payload (impl->instance, encoded_buffer, if (!impl->instance->encode_serialized_payload (impl->instance, encoded_buffer,
extra_inline_qos, plain_buffer, check_handle (sending_datawriter_crypto), ex)) extra_inline_qos, plain_buffer, check_handle (sending_datawriter_crypto), ex))
@ -511,6 +705,7 @@ static DDS_Security_boolean encode_datawriter_submessage(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
if (!impl->instance->encode_datawriter_submessage (impl->instance, encoded_rtps_submessage, 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)) plain_rtps_submessage, check_handle (sending_datawriter_crypto), receiving_datareader_crypto_list, receiving_datareader_crypto_list_index, ex))
return false; return false;
@ -558,6 +753,7 @@ static DDS_Security_boolean encode_datareader_submessage(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
if (!impl->instance->encode_datareader_submessage (impl->instance, encoded_rtps_submessage, if (!impl->instance->encode_datareader_submessage (impl->instance, encoded_rtps_submessage,
plain_rtps_submessage, check_handle (sending_datareader_crypto), receiving_datawriter_crypto_list, ex)) plain_rtps_submessage, check_handle (sending_datareader_crypto), receiving_datawriter_crypto_list, ex))
return false; return false;
@ -580,6 +776,7 @@ static DDS_Security_boolean encode_rtps_message(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
if (!impl->instance->encode_rtps_message (impl->instance, encoded_rtps_message, if (!impl->instance->encode_rtps_message (impl->instance, encoded_rtps_message,
plain_rtps_message, check_handle (sending_participant_crypto), receiving_participant_crypto_list, receiving_participant_crypto_list_index, ex)) plain_rtps_message, check_handle (sending_participant_crypto), receiving_participant_crypto_list, receiving_participant_crypto_list_index, ex))
return false; return false;
@ -611,6 +808,7 @@ static DDS_Security_boolean decode_rtps_message(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->decode_rtps_message (impl->instance, plain_buffer, encoded_buffer, return impl->instance->decode_rtps_message (impl->instance, plain_buffer, encoded_buffer,
check_handle (receiving_participant_crypto), check_handle (sending_participant_crypto), ex); check_handle (receiving_participant_crypto), check_handle (sending_participant_crypto), ex);
default: default:
@ -632,6 +830,7 @@ static DDS_Security_boolean preprocess_secure_submsg(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->preprocess_secure_submsg (impl->instance, datawriter_crypto, datareader_crypto, 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); secure_submessage_category, encoded_rtps_submessage, check_handle (receiving_participant_crypto), check_handle (sending_participant_crypto), ex);
default: default:
@ -651,6 +850,7 @@ static DDS_Security_boolean decode_datawriter_submessage(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->decode_datawriter_submessage (impl->instance, plain_rtps_submessage, 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); encoded_rtps_submessage, check_handle (receiving_datareader_crypto), check_handle (sending_datawriter_crypto), ex);
default: default:
@ -670,6 +870,7 @@ static DDS_Security_boolean decode_datareader_submessage(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->decode_datareader_submessage (impl->instance, plain_rtps_submessage, 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); encoded_rtps_submessage, check_handle (receiving_datawriter_crypto), check_handle (sending_datareader_crypto), ex);
default: default:
@ -690,6 +891,7 @@ static DDS_Security_boolean decode_serialized_payload(
switch (impl->parent->mode) switch (impl->parent->mode)
{ {
case PLUGIN_MODE_WRAPPED: case PLUGIN_MODE_WRAPPED:
case PLUGIN_MODE_TOKEN_LOG:
return impl->instance->decode_serialized_payload(impl->instance, plain_buffer, encoded_buffer, 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); inline_qos, check_handle (receiving_datareader_crypto), check_handle (sending_datawriter_crypto), ex);
default: default:
@ -815,3 +1017,41 @@ int finalize_test_cryptography_wrapped(void *context)
return finalize_test_cryptography_common(impl, true); return finalize_test_cryptography_common(impl, true);
} }
static void init_print_lock(void)
{
ddsrt_mutex_init (&g_print_token_lock);
}
int32_t init_test_cryptography_store_tokens(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_TOKEN_LOG;
ddsrt_once (&lock_inited, &init_print_lock);
ddsrt_mutex_init (&impl->token_data_lock);
ddsrt_circlist_init (&impl->token_data_list);
*context = impl;
return DDS_SECURITY_SUCCESS;
}
int32_t finalize_test_cryptography_store_tokens(void *context)
{
struct dds_security_cryptography_impl* impl = (struct dds_security_cryptography_impl*) context;
assert(impl->mode == PLUGIN_MODE_TOKEN_LOG);
ddsrt_mutex_lock (&impl->token_data_lock);
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_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 */
return finalize_test_cryptography_common(impl, true);
}

View file

@ -12,13 +12,37 @@
#ifndef SECURITY_CORE_TEST_CRYPTO_WRAPPER_H_ #ifndef SECURITY_CORE_TEST_CRYPTO_WRAPPER_H_
#define SECURITY_CORE_TEST_CRYPTO_WRAPPER_H_ #define SECURITY_CORE_TEST_CRYPTO_WRAPPER_H_
#include "dds/ddsrt/circlist.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#include "dds/security/dds_security_api.h" #include "dds/security/dds_security_api.h"
#include "dds/security/dds_security_api_defs.h" #include "dds/security/dds_security_api_defs.h"
#include "dds/security/cryptography_wrapper_export.h" #include "dds/security/cryptography_wrapper_export.h"
#define CRYPTO_TOKEN_MAXLEN 10
#define CRYPTO_TOKEN_SIZE 256
struct dds_security_cryptography_impl; struct dds_security_cryptography_impl;
enum crypto_tokens_type {
LOCAL_PARTICIPANT_TOKENS,
LOCAL_WRITER_TOKENS,
LOCAL_READER_TOKENS,
REMOTE_PARTICIPANT_TOKENS,
REMOTE_WRITER_TOKENS,
REMOTE_READER_TOKENS,
TOKEN_TYPE_INVALID
};
struct crypto_token_data {
struct ddsrt_circlist_elem e;
enum crypto_tokens_type type;
DDS_Security_ParticipantCryptoHandle local_handle;
DDS_Security_ParticipantCryptoHandle remote_handle;
uint32_t n_tokens;
unsigned char data[CRYPTO_TOKEN_MAXLEN][CRYPTO_TOKEN_SIZE];
size_t data_len[CRYPTO_TOKEN_MAXLEN];
};
SECURITY_EXPORT void set_protection_kinds( SECURITY_EXPORT void set_protection_kinds(
struct dds_security_cryptography_impl * impl, struct dds_security_cryptography_impl * impl,
DDS_Security_ProtectionKind rtps_protection_kind, DDS_Security_ProtectionKind rtps_protection_kind,
@ -34,6 +58,10 @@ SECURITY_EXPORT void set_disc_protection_kinds(
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_entity_data_secret(struct dds_security_cryptography_impl * impl, const char * pp_secret, const char * groupdata_secret, const char * ep_secret);
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);
/* Init in all-ok mode: all functions return success without calling the actual plugin */ /* 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); SECURITY_EXPORT int init_test_cryptography_all_ok(const char *argument, void **context, struct ddsi_domaingv *gv);
SECURITY_EXPORT int finalize_test_cryptography_all_ok(void *context); SECURITY_EXPORT int finalize_test_cryptography_all_ok(void *context);
@ -46,4 +74,8 @@ SECURITY_EXPORT int finalize_test_cryptography_missing_func(void *context);
SECURITY_EXPORT int init_test_cryptography_wrapped(const char *argument, void **context, struct ddsi_domaingv *gv); SECURITY_EXPORT int init_test_cryptography_wrapped(const char *argument, void **context, struct ddsi_domaingv *gv);
SECURITY_EXPORT int finalize_test_cryptography_wrapped(void *context); SECURITY_EXPORT int finalize_test_cryptography_wrapped(void *context);
/* Init in store-token mode (stores all exchanged security tokens) */
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);
#endif /* SECURITY_CORE_TEST_CRYPTO_WRAPPER_H_ */ #endif /* SECURITY_CORE_TEST_CRYPTO_WRAPPER_H_ */

View file

@ -18,6 +18,10 @@
#include "dds/ddsrt/string.h" #include "dds/ddsrt/string.h"
#include "dds/ddsrt/threads.h" #include "dds/ddsrt/threads.h"
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/ddsi_entity_index.h"
#include "dds/ddsi/ddsi_security_omg.h"
#include "dds__entity.h"
#include "dds/security/dds_security_api.h" #include "dds/security/dds_security_api.h"
#include "authentication_wrapper.h" #include "authentication_wrapper.h"
#include "test_utils.h" #include "test_utils.h"
@ -449,3 +453,21 @@ void write_read_for(dds_entity_t wr, dds_entity_t pp_rd, dds_entity_t rd, dds_du
CU_ASSERT_EQUAL_FATAL (write_fail, exp_write_fail); CU_ASSERT_EQUAL_FATAL (write_fail, exp_write_fail);
CU_ASSERT_EQUAL_FATAL (read_fail, exp_read_fail); CU_ASSERT_EQUAL_FATAL (read_fail, exp_read_fail);
} }
struct dds_security_cryptography_impl * get_crypto_context(dds_entity_t participant)
{
struct dds_entity *pp_entity = NULL;
struct participant *pp;
struct dds_security_cryptography_impl *context;
dds_return_t ret;
ret = dds_entity_lock (participant, DDS_KIND_PARTICIPANT, &pp_entity);
CU_ASSERT_EQUAL_FATAL (ret, 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);
CU_ASSERT_FATAL (pp != NULL);
context = (struct dds_security_cryptography_impl *) q_omg_participant_get_cryptography (pp);
thread_state_asleep (lookup_thread_state ());
dds_entity_unlock (pp_entity);
return context;
}

View file

@ -69,5 +69,6 @@ void rd_wr_init_fail(
bool exp_pubtp_fail, bool exp_wr_fail, bool exp_pubtp_fail, bool exp_wr_fail,
bool exp_subtp_fail, bool exp_rd_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); 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);
#endif /* SECURITY_CORE_TEST_UTILS_H_ */ #endif /* SECURITY_CORE_TEST_UTILS_H_ */

View file

@ -20,6 +20,7 @@
#include "dds/ddsrt/environ.h" #include "dds/ddsrt/environ.h"
#include "dds/ddsrt/heap.h" #include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h" #include "dds/ddsrt/string.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsi/q_config.h" #include "dds/ddsi/q_config.h"
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
@ -29,9 +30,11 @@
#include "common/config_env.h" #include "common/config_env.h"
#include "common/authentication_wrapper.h" #include "common/authentication_wrapper.h"
#include "common/cryptography_wrapper.h"
#include "common/plugin_wrapper_msg_q.h" #include "common/plugin_wrapper_msg_q.h"
#include "common/test_utils.h" #include "common/test_utils.h"
#include "common/test_identity.h" #include "common/test_identity.h"
#include "common/security_config_test_utils.h"
static const char *config = static const char *config =
"${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}" "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
@ -42,7 +45,7 @@ static const char *config =
" </Discovery>" " </Discovery>"
" <DDSSecurity>" " <DDSSecurity>"
" <Authentication>" " <Authentication>"
" <Library finalizeFunction=\"finalize_test_authentication_wrapped\" initFunction=\"init_test_authentication_wrapped\" path=\"" WRAPPERLIB_PATH("dds_security_authentication_wrapper") "\"/>" " <Library initFunction=\"${AUTH_INIT}\" finalizeFunction=\"${AUTH_FINI}\" path=\"" WRAPPERLIB_PATH("dds_security_authentication_wrapper") "\"/>"
" <IdentityCertificate>data:,"TEST_IDENTITY1_CERTIFICATE"</IdentityCertificate>" " <IdentityCertificate>data:,"TEST_IDENTITY1_CERTIFICATE"</IdentityCertificate>"
" <PrivateKey>data:,"TEST_IDENTITY1_PRIVATE_KEY"</PrivateKey>" " <PrivateKey>data:,"TEST_IDENTITY1_PRIVATE_KEY"</PrivateKey>"
" <IdentityCA>data:,"TEST_IDENTITY_CA1_CERTIFICATE"</IdentityCA>" " <IdentityCA>data:,"TEST_IDENTITY_CA1_CERTIFICATE"</IdentityCA>"
@ -54,43 +57,120 @@ static const char *config =
" <Permissions>file:" COMMON_ETC_PATH("default_permissions.p7s") "</Permissions>" " <Permissions>file:" COMMON_ETC_PATH("default_permissions.p7s") "</Permissions>"
" </AccessControl>" " </AccessControl>"
" <Cryptographic>" " <Cryptographic>"
" <Library finalizeFunction=\"finalize_crypto\" initFunction=\"init_crypto\"/>" " <Library initFunction=\"${CRYPTO_INIT}\" finalizeFunction=\"${CRYPTO_FINI}\" path=\"" WRAPPERLIB_PATH("dds_security_cryptography_wrapper") "\"/>"
" </Cryptographic>" " </Cryptographic>"
" </DDSSecurity>" " </DDSSecurity>"
"</Domain>"; "</Domain>";
#define DDS_DOMAINID_PART1 0 #define DDS_DOMAINID1 0
#define DDS_DOMAINID_PART2 1 #define DDS_DOMAINID2 1
static dds_entity_t g_part1_domain = 0; static dds_entity_t g_domain1 = 0;
static dds_entity_t g_part1_participant = 0; static dds_entity_t g_participant1 = 0;
static dds_entity_t g_part2_domain = 0; static dds_entity_t g_domain2 = 0;
static dds_entity_t g_part2_participant = 0; static dds_entity_t g_participant2 = 0;
static void handshake_init(void) static uint32_t g_topic_nr = 0;
static dds_entity_t g_pub = 0, g_pub_tp = 0, g_wr = 0, g_sub = 0, g_sub_tp = 0, g_rd = 0;
static void handshake_init(const char * auth_init, const char * auth_fini, const char * crypto_init, const char * crypto_fini)
{ {
char *conf_part1 = ddsrt_expand_envvars_sh (config, DDS_DOMAINID_PART1); struct kvp config_vars[] = {
char *conf_part2 = ddsrt_expand_envvars_sh (config, DDS_DOMAINID_PART2); { "AUTH_INIT", auth_init, 1},
g_part1_domain = dds_create_domain (DDS_DOMAINID_PART1, conf_part1); { "AUTH_FINI", auth_fini, 1},
g_part2_domain = dds_create_domain (DDS_DOMAINID_PART2, conf_part2); { "CRYPTO_INIT", crypto_init, 1 },
dds_free (conf_part1); { "CRYPTO_FINI", crypto_fini, 1 },
dds_free (conf_part2); { NULL, NULL, 0 }
};
CU_ASSERT_FATAL ((g_part1_participant = dds_create_participant (DDS_DOMAINID_PART1, NULL, NULL)) > 0); char *conf = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars);
CU_ASSERT_FATAL ((g_part2_participant = dds_create_participant (DDS_DOMAINID_PART2, NULL, NULL)) > 0); int32_t unmatched = expand_lookup_unmatched (config_vars);
CU_ASSERT_EQUAL_FATAL (unmatched, 0);
g_domain1 = dds_create_domain (DDS_DOMAINID1, conf);
g_domain2 = dds_create_domain (DDS_DOMAINID2, conf);
dds_free (conf);
g_participant1 = dds_create_participant (DDS_DOMAINID1, NULL, NULL);
CU_ASSERT_FATAL (g_participant1 > 0);
g_participant2 = dds_create_participant (DDS_DOMAINID2, NULL, NULL);
CU_ASSERT_FATAL (g_participant2 > 0);
} }
static void handshake_fini(void) static void handshake_fini(void)
{ {
CU_ASSERT_EQUAL_FATAL (dds_delete (g_part1_participant), DDS_RETCODE_OK); dds_return_t ret = dds_delete (g_domain1);
CU_ASSERT_EQUAL_FATAL (dds_delete (g_part2_participant), DDS_RETCODE_OK); CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
CU_ASSERT_EQUAL_FATAL (dds_delete (g_part1_domain), DDS_RETCODE_OK); ret = dds_delete (g_domain2);
CU_ASSERT_EQUAL_FATAL (dds_delete (g_part2_domain), DDS_RETCODE_OK); CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
} }
CU_Test(ddssec_handshake, happy_day, .init = handshake_init, .fini = handshake_fini) CU_Test(ddssec_handshake, happy_day)
{ {
validate_handshake_nofail (DDS_DOMAINID_PART1); handshake_init (
validate_handshake_nofail (DDS_DOMAINID_PART2); "init_test_authentication_wrapped", "finalize_test_authentication_wrapped",
"init_test_cryptography_wrapped", "finalize_test_cryptography_wrapped");
validate_handshake_nofail (DDS_DOMAINID1);
validate_handshake_nofail (DDS_DOMAINID2);
handshake_fini ();
}
CU_Test(ddssec_handshake, check_tokens)
{
handshake_init (
"init_test_authentication_wrapped", "finalize_test_authentication_wrapped",
"init_test_cryptography_store_tokens", "finalize_test_cryptography_store_tokens");
validate_handshake_nofail (DDS_DOMAINID1);
validate_handshake_nofail (DDS_DOMAINID2);
char topic_name[100];
create_topic_name("ddssec_authentication_", g_topic_nr++, topic_name, sizeof (topic_name));
rd_wr_init (g_participant1, &g_pub, &g_pub_tp, &g_wr, g_participant2, &g_sub, &g_sub_tp, &g_rd, topic_name);
write_read_for (g_wr, g_participant2, g_rd, DDS_MSECS (100), false, false);
// Get subscriber and publisher crypto tokens
struct dds_security_cryptography_impl * crypto_context_pub = get_crypto_context (g_participant1);
CU_ASSERT_FATAL (crypto_context_pub != NULL);
struct ddsrt_circlist *pub_tokens = get_crypto_tokens (crypto_context_pub);
struct dds_security_cryptography_impl * crypto_context_sub = get_crypto_context (g_participant2);
CU_ASSERT_FATAL (crypto_context_sub != NULL);
struct ddsrt_circlist *sub_tokens = get_crypto_tokens (crypto_context_sub);
// Find all publisher tokens in subscribers token store
while (!ddsrt_circlist_isempty (pub_tokens))
{
struct ddsrt_circlist_elem *list_elem = ddsrt_circlist_oldest (pub_tokens);
struct crypto_token_data *token_data = DDSRT_FROM_CIRCLIST (struct crypto_token_data, e, list_elem);
enum crypto_tokens_type exp_type = TOKEN_TYPE_INVALID;
for (size_t n = 0; n < token_data->n_tokens; n++)
{
switch (token_data->type)
{
case LOCAL_PARTICIPANT_TOKENS: exp_type = REMOTE_PARTICIPANT_TOKENS; break;
case REMOTE_PARTICIPANT_TOKENS: exp_type = LOCAL_PARTICIPANT_TOKENS; break;
case LOCAL_WRITER_TOKENS: exp_type = REMOTE_WRITER_TOKENS; break;
case REMOTE_WRITER_TOKENS: exp_type = LOCAL_WRITER_TOKENS; break;
case LOCAL_READER_TOKENS: exp_type = REMOTE_READER_TOKENS; break;
case REMOTE_READER_TOKENS: exp_type = LOCAL_READER_TOKENS; break;
default: CU_FAIL ("Unexpected token type");
}
printf("- find token %s #%"PRIuSIZE", len %"PRIuSIZE"\n", get_crypto_token_type_str (token_data->type), n, token_data->data_len[n]);
struct crypto_token_data *st = find_crypto_token (crypto_context_sub, exp_type, token_data->data[n], token_data->data_len[n]);
CU_ASSERT_FATAL (st != NULL);
}
ddsrt_circlist_remove (pub_tokens, list_elem);
ddsrt_free (token_data);
}
// Cleanup
while (!ddsrt_circlist_isempty (sub_tokens))
{
struct ddsrt_circlist_elem *list_elem = ddsrt_circlist_oldest (sub_tokens);
ddsrt_circlist_remove (sub_tokens, list_elem);
ddsrt_free (list_elem);
}
ddsrt_free (sub_tokens);
ddsrt_free (pub_tokens);
handshake_fini ();
} }

View file

@ -27,14 +27,11 @@
#include "dds/ddsi/ddsi_domaingv.h" #include "dds/ddsi/ddsi_domaingv.h"
#include "dds/ddsi/q_misc.h" #include "dds/ddsi/q_misc.h"
#include "dds/ddsi/ddsi_xqos.h" #include "dds/ddsi/ddsi_xqos.h"
#include "dds/ddsi/q_entity.h"
#include "dds/ddsi/ddsi_entity_index.h"
#include "dds/ddsi/ddsi_security_omg.h"
#include "dds__entity.h"
#include "dds/security/dds_security_api.h" #include "dds/security/dds_security_api.h"
#include "common/config_env.h" #include "common/config_env.h"
#include "common/test_identity.h" #include "common/test_identity.h"
#include "common/test_utils.h"
#include "common/security_config_test_utils.h" #include "common/security_config_test_utils.h"
#include "common/cryptography_wrapper.h" #include "common/cryptography_wrapper.h"
@ -119,25 +116,6 @@ 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 (*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); typedef dds_entity_t (*ep_create_fn)(dds_entity_t, dds_entity_t, const dds_qos_t *qos, const dds_listener_t *listener);
static struct dds_security_cryptography_impl * get_crypto_context(dds_entity_t participant)
{
struct dds_entity *pp_entity = NULL;
struct participant *pp;
struct dds_security_cryptography_impl *context;
dds_return_t ret;
ret = dds_entity_lock (participant, DDS_KIND_PARTICIPANT, &pp_entity);
CU_ASSERT_EQUAL_FATAL (ret, 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);
CU_ASSERT_FATAL (pp != NULL);
context = (struct dds_security_cryptography_impl *) q_omg_participant_get_cryptography (pp);
thread_state_asleep (lookup_thread_state ());
dds_entity_unlock (pp_entity);
return context;
}
static const char * pk_to_str(DDS_Security_ProtectionKind pk) static const char * pk_to_str(DDS_Security_ProtectionKind pk)
{ {
switch (pk) switch (pk)
@ -181,14 +159,6 @@ static dds_qos_t *get_qos()
return qos; return qos;
} }
static char *create_topic_name(const char *prefix, uint32_t nr, char *name, size_t size)
{
ddsrt_pid_t pid = ddsrt_getpid ();
ddsrt_tid_t tid = ddsrt_gettid ();
(void)snprintf(name, size, "%s%d_pid%" PRIdPID "_tid%" PRIdTID "", prefix, nr, pid, tid);
return name;
}
static dds_entity_t create_pp (dds_domainid_t domain_id, const struct domain_sec_config * domain_config, set_crypto_params_fn set_crypto_params) static dds_entity_t create_pp (dds_domainid_t domain_id, const struct domain_sec_config * domain_config, set_crypto_params_fn set_crypto_params)
{ {
dds_qos_t *qos = dds_create_qos (); dds_qos_t *qos = dds_create_qos ();
@ -280,45 +250,6 @@ static void test_fini(size_t n_sub_domain, size_t n_pub_domain)
printf("Test finished\n"); printf("Test finished\n");
} }
static void sync_writer_to_readers(dds_entity_t pub_participant, dds_entity_t writer, size_t n_exp_rd)
{
dds_attach_t triggered;
dds_return_t ret;
dds_entity_t waitset_wr = dds_create_waitset (pub_participant);
CU_ASSERT_FATAL (waitset_wr > 0);
dds_publication_matched_status_t pub_matched;
/* Sync writer to reader. */
ret = dds_waitset_attach (waitset_wr, writer, writer);
CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
while (true)
{
ret = dds_waitset_wait (waitset_wr, &triggered, 1, DDS_SECS(5));
CU_ASSERT_FATAL (ret >= 1);
CU_ASSERT_EQUAL_FATAL (writer, (dds_entity_t)(intptr_t) triggered);
ret = dds_get_publication_matched_status(writer, &pub_matched);
CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
if (pub_matched.total_count >= n_exp_rd)
break;
};
dds_delete (waitset_wr);
}
static void reader_wait_for_data(dds_entity_t sub_participant, dds_entity_t reader)
{
dds_attach_t triggered;
dds_return_t ret;
dds_entity_t waitset_rd = dds_create_waitset (sub_participant);
CU_ASSERT_FATAL (waitset_rd > 0);
ret = dds_waitset_attach (waitset_rd, reader, reader);
CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK);
ret = dds_waitset_wait (waitset_rd, &triggered, 1, DDS_SECS(5));
CU_ASSERT_EQUAL_FATAL (ret, 1);
CU_ASSERT_EQUAL_FATAL (reader, (dds_entity_t)(intptr_t)triggered);
dds_delete (waitset_rd);
}
static void create_eps (dds_entity_t **endpoints, dds_entity_t **topics, size_t n_dom, size_t n_pp, size_t n_eps, const char * topic_name, const dds_topic_descriptor_t *topic_descriptor, static void create_eps (dds_entity_t **endpoints, dds_entity_t **topics, size_t n_dom, size_t n_pp, size_t n_eps, const char * topic_name, const dds_topic_descriptor_t *topic_descriptor,
const dds_entity_t * pps, const dds_qos_t * qos, ep_create_fn ep_create, unsigned status_mask) const dds_entity_t * pps, const dds_qos_t * qos, ep_create_fn ep_create, unsigned status_mask)
{ {
@ -381,7 +312,7 @@ static void test_write_read(struct domain_sec_config *domain_config,
for (size_t w = 0; w < n_writers; w++) for (size_t w = 0; w < n_writers; w++)
{ {
size_t wr_index = pp_index * n_writers + w; size_t wr_index = pp_index * n_writers + w;
sync_writer_to_readers (g_pub_participants[pp_index], writers[wr_index], n_sub_domains * n_sub_participants * n_readers); sync_writer_to_readers (g_pub_participants[pp_index], writers[wr_index], (uint32_t)(n_sub_domains * n_sub_participants * n_readers));
sample.id = (int32_t) wr_index; sample.id = (int32_t) wr_index;
printf("writer %"PRId32" writing sample %d\n", writers[wr_index], sample.id); printf("writer %"PRId32" writing sample %d\n", writers[wr_index], sample.id);
ret = dds_write (writers[wr_index], &sample); ret = dds_write (writers[wr_index], &sample);
@ -404,7 +335,7 @@ static void test_write_read(struct domain_sec_config *domain_config,
ret = dds_take (readers[rd_index], samples, info, 1, 1); ret = dds_take (readers[rd_index], samples, info, 1, 1);
if (ret == 0) if (ret == 0)
{ {
reader_wait_for_data (g_sub_participants[pp_index], readers[rd_index]); reader_wait_for_data (g_sub_participants[pp_index], readers[rd_index], DDS_SECS(5));
continue; continue;
} }
printf("reader %"PRId32" received sample %d\n", readers[rd_index], rd_sample.id); printf("reader %"PRId32" received sample %d\n", readers[rd_index], rd_sample.id);
@ -500,7 +431,7 @@ static void test_payload_secret(DDS_Security_ProtectionKind rtps_pk, DDS_Securit
{ {
if ((ret = dds_take (readers[0], samples, info, 1, 1)) == 0) if ((ret = dds_take (readers[0], samples, info, 1, 1)) == 0)
{ {
reader_wait_for_data (g_sub_participants[0], readers[0]); reader_wait_for_data (g_sub_participants[0], readers[0], DDS_SECS(5));
continue; continue;
} }
CU_ASSERT_EQUAL_FATAL (ret, 1); CU_ASSERT_EQUAL_FATAL (ret, 1);