Add index on receiver specific key to improve verification of origin authentication signing

Signed-off-by: Marcel Jordense <marcel.jordense@adlinktech.com>
This commit is contained in:
Marcel Jordense 2020-03-24 19:15:36 +01:00 committed by eboasson
parent d82b7fdd73
commit a77fe10a04
19 changed files with 753 additions and 359 deletions

View file

@ -389,7 +389,16 @@ static void proxypp_pp_match_free(struct dds_security_context *sc, struct proxyp
if (pm->permissions_handle != DDS_SECURITY_HANDLE_NIL)
{
if (!sc->access_control_context->return_permissions_handle(sc->access_control_context, pm->permissions_handle, &exception))
{
/* FIXME: enable exception warning when access control is updated to return a permission handle for each
* matching local and remote participant.
*/
#if 0
EXCEPTION_ERROR(sc, &exception, "Failed to return remote permissions handle");
#else
DDS_Security_Exception_reset(&exception);
#endif
}
}
ddsrt_free(pm);
}
@ -1011,6 +1020,8 @@ static void cleanup_participant_sec_attributes(void *arg)
if ((attr = participant_index_remove(sc, info->crypto_handle)) == NULL)
return;
GVTRACE("cleanup participant "PGUIDFMT" security attributes\n", PGUID(attr->pp_guid));
pm = ddsrt_avl_cfind_min(&pp_proxypp_treedef, &attr->proxy_participants);
while (pm)
{
@ -1041,7 +1052,8 @@ static void cleanup_participant_sec_attributes(void *arg)
EXCEPTION_ERROR(sc, &exception, "Failed to return participant security attributes");
}
(void)sc->crypto_context->crypto_key_factory->unregister_participant(sc->crypto_context->crypto_key_factory, attr->crypto_handle, NULL);
if (!sc->crypto_context->crypto_key_factory->unregister_participant(sc->crypto_context->crypto_key_factory, attr->crypto_handle, &exception))
EXCEPTION_ERROR(sc, &exception, "Failed to unregister participant");
ddsrt_avl_cfree(&pp_proxypp_treedef, &attr->proxy_participants, NULL);
ddsrt_mutex_unlock(&attr->lock);
@ -1702,7 +1714,7 @@ bool q_omg_security_register_remote_participant(struct participant *pp, struct p
proxypp->sec_attr->crypto_handle = crypto_handle;
GVTRACE("match pp->crypto=%"PRId64" proxypp->crypto=%"PRId64"\n", pp->sec_attr->crypto_handle, crypto_handle);
GVTRACE("match pp->crypto=%"PRId64" proxypp->crypto=%"PRId64" permissions=%"PRId64"\n", pp->sec_attr->crypto_handle, crypto_handle, permissions_handle);
match_proxypp_pp(pp, proxypp, permissions_handle, shared_secret);
GVTRACE("create proxypp-pp match pp="PGUIDFMT" proxypp="PGUIDFMT" lidh=%"PRId64, PGUID(pp->e.guid), PGUID(proxypp->e.guid), pp->sec_attr->local_identity_handle);
@ -2031,7 +2043,7 @@ static bool q_omg_security_register_remote_writer_match(struct proxy_writer *pwr
match = find_or_create_entity_match(gv->security_matches, &pwr->e.guid, &rd->e.guid);
if (match->matched)
*crypto_handle = match->crypto_handle;
else
else if (match->crypto_handle == 0)
{
/* Generate writer crypto info. */
match->crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datawriter(
@ -2382,7 +2394,7 @@ static bool q_omg_security_register_remote_reader_match(struct proxy_reader *prd
match = find_or_create_entity_match(gv->security_matches, &prd->e.guid, &wr->e.guid);
if (match->matched)
*crypto_handle = match->crypto_handle;
else
else if (match->crypto_handle == 0)
{
/* Generate writer crypto info. */
match->crypto_handle = sc->crypto_context->crypto_key_factory->register_matched_remote_datareader(

View file

@ -2381,6 +2381,7 @@ check_and_create_remote_participant_rights(
permissions = ddsrt_malloc(sizeof(remote_permissions));
permissions->ref_cnt = 0;
permissions->permissions_tree = NULL;
permissions->remote_permissions_token_class_id = NULL;
if (!ac_parse_permissions_xml(permissions_xml, &(permissions->permissions_tree), ex))
{
ddsrt_free(permissions);

View file

@ -270,10 +270,13 @@ ac_remote_participant_access_rights_new(
rights->local_rights = (local_participant_access_rights *)ACCESS_CONTROL_OBJECT_KEEP(local_rights);
if (rights->permissions)
{
rights->permissions->remote_permissions_token_class_id = ddsrt_strdup(remote_permissions_token->class_id);
rights->permissions->ref_cnt++;
if (rights->permissions->remote_permissions_token_class_id == NULL)
{
rights->permissions->remote_permissions_token_class_id = ddsrt_strdup(remote_permissions_token->class_id);
rights->identity_subject_name = ddsrt_strdup(identity_subject);
}
}
else
{
assert(identity_subject == NULL);

View file

@ -12,8 +12,10 @@
#ifndef CRYPTO_DEFS_H
#define CRYPTO_DEFS_H
#include "dds/security/core/dds_security_types.h"
#include "dds/security/dds_security_api.h"
#define DDS_CRYPTO_PLUGIN_CONTEXT "Cryptographic"
#define CRYPTO_HMAC_SIZE 16
@ -111,4 +113,10 @@ typedef enum RTPS_Message_Type
RTPS_Message_Type_SRTPS_POSTFIX = 0x34
} RTPS_Message_Type;
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
crypto_hmac_t receiver_mac;
};
#endif /* CRYPTO_DEFS_H */

View file

@ -238,66 +238,38 @@ attribute_to_data_protection_kind(
return kind;
}
static void
remove_relation_from_keymaterial(
const participant_key_material *key_material,
CryptoObject *local_crypto,
CryptoObject *remote_crypto)
{
endpoint_relation *relation;
relation = crypto_endpoint_relation_find_by_crypto(key_material->endpoint_relations, local_crypto, remote_crypto);
if (relation)
{
crypto_object_table_remove_object(key_material->endpoint_relations, (CryptoObject *)relation);
CRYPTO_OBJECT_RELEASE(relation);
}
}
static void
remove_remote_writer_relation(
dds_security_crypto_key_factory_impl *implementation,
remote_datawriter_crypto *remote_writer)
remote_datawriter_crypto *rmt_wr)
{
remote_participant_crypto *remote_participant;
participant_key_material *key_material;
remote_participant_crypto *rmt_pp;
DDSRT_UNUSED_ARG(implementation);
assert(remote_writer);
remote_participant = remote_writer->participant;
assert(remote_participant);
assert(rmt_wr);
rmt_pp = rmt_wr->participant;
assert(rmt_pp);
key_material = (participant_key_material *)crypto_object_table_find(
remote_participant->key_material, CRYPTO_OBJECT_HANDLE(remote_writer->local_reader->participant));
if (key_material)
{
remove_relation_from_keymaterial(key_material, (CryptoObject *)remote_writer->local_reader, (CryptoObject *)remote_writer);
CRYPTO_OBJECT_RELEASE(key_material);
}
if (rmt_wr->writer2reader_key_material[0])
crypto_remove_endpoint_relation(rmt_pp, (CryptoObject *)rmt_wr->local_reader, rmt_wr->writer2reader_key_material[0]->sender_key_id);
}
static void
remove_remote_reader_relation(
dds_security_crypto_key_factory_impl *implementation,
remote_datareader_crypto *remote_reader)
remote_datareader_crypto *rmt_rd)
{
remote_participant_crypto *remote_participant;
participant_key_material *key_material;
remote_participant_crypto *rmt_pp;
DDSRT_UNUSED_ARG(implementation);
assert(remote_reader);
remote_participant = remote_reader->participant;
assert(remote_participant);
assert(rmt_rd);
rmt_pp = rmt_rd->participant;
assert(rmt_pp);
key_material = (participant_key_material *)crypto_object_table_find(
remote_participant->key_material, CRYPTO_OBJECT_HANDLE(remote_reader->local_writer->participant));
if (key_material)
{
remove_relation_from_keymaterial(key_material, (CryptoObject *)remote_reader->local_writer, (CryptoObject *)remote_reader);
CRYPTO_OBJECT_RELEASE(key_material);
}
if (rmt_rd->reader2writer_key_material)
crypto_remove_endpoint_relation(rmt_pp, (CryptoObject *)rmt_rd->local_writer, rmt_rd->reader2writer_key_material->sender_key_id);
}
/**
@ -388,8 +360,8 @@ register_matched_remote_participant(
{
/* declarations */
dds_security_crypto_key_factory_impl *implementation = (dds_security_crypto_key_factory_impl *)instance;
remote_participant_crypto *participant_crypto;
local_participant_crypto *local_participant_crypto_ref;
remote_participant_crypto *rmt_pp_crypto;
local_participant_crypto *loc_pp_crypto;
DDS_Security_SecurityException exception;
participant_key_material *key_material;
@ -414,8 +386,8 @@ register_matched_remote_participant(
/* Check if local_participant_crypto_handle exists in the map */
local_participant_crypto_ref = (local_participant_crypto *)crypto_object_table_find(implementation->crypto_objects, local_participant_crypto_handle);
if (local_participant_crypto_ref == NULL)
loc_pp_crypto = (local_participant_crypto *)crypto_object_table_find(implementation->crypto_objects, local_participant_crypto_handle);
if (loc_pp_crypto == NULL)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
@ -428,23 +400,22 @@ register_matched_remote_participant(
crypto_object_table_walk(implementation->crypto_objects, resolve_remote_participant_by_id, &arg);
if (arg.pprmte)
{
participant_crypto = arg.pprmte;
rmt_pp_crypto = arg.pprmte;
}
else
{
participant_crypto = crypto_remote_participant_crypto__new(remote_participant_identity);
crypto_object_table_insert(implementation->crypto_objects, (CryptoObject *)participant_crypto);
rmt_pp_crypto = crypto_remote_participant_crypto__new(remote_participant_identity);
crypto_object_table_insert(implementation->crypto_objects, (CryptoObject *)rmt_pp_crypto);
}
}
key_material = (participant_key_material *)crypto_object_table_find(participant_crypto->key_material, local_participant_crypto_ref->_parent.handle);
key_material = crypto_remote_participant_lookup_keymat(rmt_pp_crypto, PARTICIPANT_CRYPTO_HANDLE(loc_pp_crypto));
if (!key_material)
{
key_material = crypto_participant_key_material_new(local_participant_crypto_ref);
key_material = crypto_participant_key_material_new(loc_pp_crypto, rmt_pp_crypto);
/* set remote participant keymaterial with local keymaterial values */
crypto_master_key_material_set(key_material->local_P2P_key_material, local_participant_crypto_ref->key_material);
crypto_master_key_material_set(key_material->local_P2P_key_material, loc_pp_crypto->key_material);
if (!calculate_kx_keys(shared_secret, key_material->P2P_kx_key_material, &exception))
goto fail_calc_key;
@ -453,8 +424,8 @@ register_matched_remote_participant(
key_material->P2P_reader_session = crypto_session_key_material_new(key_material->P2P_kx_key_material);
/* if we do not have OriginAuthentication, receiver specific info remains empty/NULL */
if ((local_participant_crypto_ref->rtps_protection_kind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION) ||
(local_participant_crypto_ref->rtps_protection_kind == DDS_SECURITY_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION))
if ((loc_pp_crypto->rtps_protection_kind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION) ||
(loc_pp_crypto->rtps_protection_kind == DDS_SECURITY_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION))
{
if (RAND_bytes(key_material->local_P2P_key_material->master_receiver_specific_key, (int)CRYPTO_KEY_SIZE_BYTES(key_material->local_P2P_key_material->transformation_kind)) < 0)
{
@ -464,25 +435,26 @@ register_matched_remote_participant(
}
key_material->local_P2P_key_material->receiver_specific_key_id = ddsrt_atomic_inc32_ov(&implementation->next_key_id);
}
participant_crypto->session = (session_key_material *)CRYPTO_OBJECT_KEEP(local_participant_crypto_ref->session);
rmt_pp_crypto->session = (session_key_material *)CRYPTO_OBJECT_KEEP(loc_pp_crypto->session);
crypto_object_table_insert(participant_crypto->key_material, (CryptoObject *)key_material);
crypto_local_participant_add_keymat(loc_pp_crypto, key_material);
crypto_remote_participant_add_keymat(rmt_pp_crypto, key_material);
}
participant_crypto->rtps_protection_kind = local_participant_crypto_ref->rtps_protection_kind; /* Same as local */
rmt_pp_crypto->rtps_protection_kind = loc_pp_crypto->rtps_protection_kind; /* Same as local */
CRYPTO_OBJECT_RELEASE(key_material);
CRYPTO_OBJECT_RELEASE(participant_crypto);
CRYPTO_OBJECT_RELEASE(local_participant_crypto_ref);
CRYPTO_OBJECT_RELEASE(rmt_pp_crypto);
CRYPTO_OBJECT_RELEASE(loc_pp_crypto);
return PARTICIPANT_CRYPTO_HANDLE(participant_crypto);
return PARTICIPANT_CRYPTO_HANDLE(rmt_pp_crypto);
/* error cases*/
err_random_generation:
fail_calc_key:
CRYPTO_OBJECT_RELEASE(key_material);
CRYPTO_OBJECT_RELEASE(participant_crypto);
CRYPTO_OBJECT_RELEASE(local_participant_crypto_ref);
CRYPTO_OBJECT_RELEASE(rmt_pp_crypto);
CRYPTO_OBJECT_RELEASE(loc_pp_crypto);
err_invalid_argument:
return DDS_SECURITY_HANDLE_NIL;
}
@ -502,8 +474,6 @@ register_local_datawriter(
DDS_Security_ProtectionKind metadata_protection;
DDS_Security_BasicProtectionKind data_protection;
memset(ex, 0, sizeof(*ex));
if (participant_crypto_handle == DDS_SECURITY_HANDLE_NIL)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
@ -582,8 +552,6 @@ register_matched_remote_datareader(
DDS_Security_ProtectionKind metadata_protectionKind;
DDS_Security_BasicProtectionKind data_protectionKind;
memset(ex, 0, sizeof(*ex));
DDSRT_UNUSED_ARG(shared_secret);
DDSRT_UNUSED_ARG(relay_only);
@ -620,9 +588,7 @@ register_matched_remote_datareader(
/* check if the writer is BuiltinParticipantVolatileMessageSecureWriter */
if (local_writer->is_builtin_participant_volatile_message_secure_writer)
{
participant_key_material *key_material;
key_material = (participant_key_material *)crypto_object_table_find(remote_participant->key_material, CRYPTO_OBJECT_HANDLE(local_writer->participant));
participant_key_material *key_material = crypto_remote_participant_lookup_keymat(remote_participant, CRYPTO_OBJECT_HANDLE(local_writer->participant));
assert(key_material);
reader_crypto->reader2writer_key_material = (master_key_material *)CRYPTO_OBJECT_KEEP(key_material->P2P_kx_key_material);
@ -729,6 +695,11 @@ register_local_datareader(
reader_crypto->reader_session = crypto_session_key_material_new(reader_crypto->reader_key_material);
}
}
else
{
participant_crypto->builtin_reader = reader_crypto;
}
crypto_object_table_insert(implementation->crypto_objects, (CryptoObject *)reader_crypto);
CRYPTO_OBJECT_RELEASE(participant_crypto);
@ -789,10 +760,7 @@ register_matched_remote_datawriter(
/* check if the writer is BuiltinParticipantVolatileMessageSecureWriter */
if (local_reader->is_builtin_participant_volatile_message_secure_reader)
{
participant_key_material *key_material;
endpoint_relation *relation;
key_material = (participant_key_material *)crypto_object_table_find(remote_participant->key_material, CRYPTO_OBJECT_HANDLE(local_reader->participant));
participant_key_material *key_material = crypto_remote_participant_lookup_keymat(remote_participant, CRYPTO_OBJECT_HANDLE(local_reader->participant));
assert(key_material);
writer_crypto->reader2writer_key_material = (master_key_material *)CRYPTO_OBJECT_KEEP(key_material->P2P_kx_key_material);
@ -801,8 +769,9 @@ register_matched_remote_datawriter(
writer_crypto->reader_session = (session_key_material *)CRYPTO_OBJECT_KEEP(key_material->P2P_reader_session);
writer_crypto->is_builtin_participant_volatile_message_secure_writer = true;
relation = crypto_endpoint_relation_new(DDS_SECURITY_DATAWRITER_SUBMESSAGE, 0, (CryptoObject *)local_reader, (CryptoObject *)writer_crypto);
crypto_object_table_insert(key_material->endpoint_relations, (CryptoObject *)relation);
key_relation * relation = crypto_key_relation_new(DDS_SECURITY_DATAWRITER_SUBMESSAGE, 0, (CryptoObject *)local_reader, (CryptoObject *)writer_crypto, NULL);
crypto_insert_endpoint_relation(remote_participant, relation);
CRYPTO_OBJECT_RELEASE(relation);
CRYPTO_OBJECT_RELEASE(key_material);
}
@ -847,29 +816,81 @@ unregister_participant(
const DDS_Security_ParticipantCryptoHandle participant_crypto_handle,
DDS_Security_SecurityException *ex)
{
dds_security_crypto_key_factory_impl *implementation = (dds_security_crypto_key_factory_impl *)instance;
DDS_Security_boolean result = false;
CryptoObject *obj;
dds_security_crypto_key_factory_impl *implementation = (dds_security_crypto_key_factory_impl *)instance;
local_participant_crypto *loc_pp_crypto;
remote_participant_crypto *rmt_pp_crypto;
participant_key_material *keymat;
DDS_Security_ParticipantCryptoHandle *handles = NULL;
size_t num, i;
if ((obj = crypto_object_table_find(implementation->crypto_objects, participant_crypto_handle)) != NULL)
{
if ((obj->kind == CRYPTO_OBJECT_KIND_LOCAL_CRYPTO) || (obj->kind == CRYPTO_OBJECT_KIND_REMOTE_CRYPTO))
switch (obj->kind)
{
case CRYPTO_OBJECT_KIND_LOCAL_CRYPTO:
{
loc_pp_crypto = (local_participant_crypto *)obj;
num = crypto_local_participnant_get_matching(loc_pp_crypto, &handles);
for (i = 0; i < num; i++)
{
if ((keymat = crypto_local_participant_remove_keymat(loc_pp_crypto, handles[i])) != NULL)
CRYPTO_OBJECT_RELEASE(keymat);
if ((rmt_pp_crypto = (remote_participant_crypto *)crypto_object_table_find(implementation->crypto_objects, handles[i])) != NULL)
{
if ((keymat = crypto_remote_participant_remove_keymat(rmt_pp_crypto, participant_crypto_handle)) != NULL)
{
if (keymat->remote_key_material && keymat->remote_key_material->receiver_specific_key_id != 0)
crypto_remove_specific_key_relation(rmt_pp_crypto, keymat->remote_key_material->receiver_specific_key_id);
CRYPTO_OBJECT_RELEASE(keymat);
}
CRYPTO_OBJECT_RELEASE(rmt_pp_crypto);
}
}
ddsrt_free(handles);
crypto_object_table_remove_object(implementation->crypto_objects, obj);
result = true;
}
else
break;
case CRYPTO_OBJECT_KIND_REMOTE_CRYPTO:
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
rmt_pp_crypto = (remote_participant_crypto *)obj;
num = crypto_remote_participnant_get_matching(rmt_pp_crypto, &handles);
for (i = 0; i < num; i++)
{
if ((keymat = crypto_remote_participant_remove_keymat(rmt_pp_crypto, handles[i])) != NULL)
{
if (keymat->remote_key_material && keymat->remote_key_material->receiver_specific_key_id != 0)
crypto_remove_specific_key_relation(rmt_pp_crypto, keymat->remote_key_material->receiver_specific_key_id);
CRYPTO_OBJECT_RELEASE(keymat);
}
if ((loc_pp_crypto = (local_participant_crypto *)crypto_object_table_find(implementation->crypto_objects, handles[i])) != NULL)
{
if ((keymat = crypto_local_participant_remove_keymat(loc_pp_crypto, participant_crypto_handle)) != NULL)
CRYPTO_OBJECT_RELEASE(keymat);
CRYPTO_OBJECT_RELEASE(loc_pp_crypto);
}
}
ddsrt_free(handles);
crypto_object_table_remove_object(implementation->crypto_objects, obj);
result = true;
}
break;
default:
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
}
break;
}
CRYPTO_OBJECT_RELEASE(obj);
}
else
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
}
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
return result;
}
@ -887,25 +908,30 @@ unregister_datawriter(
/* check if the handle is applicable*/
if ((obj = crypto_object_table_find(implementation->crypto_objects, datawriter_crypto_handle)) != NULL)
{
if ((obj->kind == CRYPTO_OBJECT_KIND_LOCAL_WRITER_CRYPTO) || (obj->kind == CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO))
switch (obj->kind)
{
if (obj->kind == CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO)
remove_remote_writer_relation(implementation, (remote_datawriter_crypto *)obj);
case CRYPTO_OBJECT_KIND_LOCAL_WRITER_CRYPTO:
crypto_object_table_remove_object(implementation->crypto_objects, obj);
result = true;
break;
case CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO:
{
remote_datawriter_crypto *rmt_wr = (remote_datawriter_crypto *)obj;
remove_remote_writer_relation(implementation, rmt_wr);
if (rmt_wr->writer2reader_key_material[0] && rmt_wr->writer2reader_key_material[0]->receiver_specific_key_id != 0)
crypto_remove_specific_key_relation(rmt_wr->participant, rmt_wr->writer2reader_key_material[0]->receiver_specific_key_id);
crypto_object_table_remove_object(implementation->crypto_objects, obj);
result = true;
}
else
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
break;
default:
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
break;
}
CRYPTO_OBJECT_RELEASE(obj);
}
else
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
}
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
return result;
}
@ -923,25 +949,30 @@ unregister_datareader(
/* check if the handle is applicable*/
if ((obj = crypto_object_table_find(implementation->crypto_objects, datareader_crypto_handle)) != NULL)
{
if ((obj->kind == CRYPTO_OBJECT_KIND_LOCAL_READER_CRYPTO) || (obj->kind == CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO))
switch (obj->kind)
{
if (obj->kind == CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO)
remove_remote_reader_relation(implementation, (remote_datareader_crypto *)obj);
case CRYPTO_OBJECT_KIND_LOCAL_READER_CRYPTO:
crypto_object_table_remove_object(implementation->crypto_objects, obj);
result = true;
break;
case CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO:
{
remote_datareader_crypto *rmt_rd = (remote_datareader_crypto *)obj;
remove_remote_reader_relation(implementation, rmt_rd);
if (rmt_rd->reader2writer_key_material && rmt_rd->reader2writer_key_material->receiver_specific_key_id != 0)
crypto_remove_specific_key_relation(rmt_rd->participant, rmt_rd->reader2writer_key_material->receiver_specific_key_id);
crypto_object_table_remove_object(implementation->crypto_objects, obj);
result = true;
}
else
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
break;
default:
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
break;
}
CRYPTO_OBJECT_RELEASE(obj);
}
else
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
}
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
return result;
}
@ -1040,6 +1071,7 @@ crypto_factory_get_participant_crypto_tokens(
dds_security_crypto_key_factory_impl *impl = (dds_security_crypto_key_factory_impl *)factory;
remote_participant_crypto *remote_crypto = (remote_participant_crypto *)crypto_object_table_find(impl->crypto_objects, remote_id);
bool result = false;
if (!remote_crypto)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
@ -1053,7 +1085,7 @@ crypto_factory_get_participant_crypto_tokens(
goto err_remote;
}
if (!(*pp_key_material = (participant_key_material *)crypto_object_table_find(remote_crypto->key_material, local_id)))
if (!(*pp_key_material = (participant_key_material *)crypto_remote_participant_lookup_keymat(remote_crypto, local_id)))
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
@ -1096,12 +1128,26 @@ crypto_factory_set_participant_crypto_tokens(
goto err_inv_remote;
}
key_material = (participant_key_material *)crypto_object_table_find(remote_crypto->key_material, local_id);
key_material = crypto_remote_participant_lookup_keymat(remote_crypto, local_id);
if (key_material)
{
if (!key_material->remote_key_material)
key_material->remote_key_material = crypto_master_key_material_new(CRYPTO_TRANSFORMATION_KIND_NONE);
crypto_token_copy(key_material->remote_key_material, remote_key_mat);
uint32_t specific_key = key_material->remote_key_material->receiver_specific_key_id;
if (specific_key != 0)
{
key_relation *relation = crypto_find_specific_key_relation(remote_crypto, specific_key);
if (!relation)
{
local_participant_crypto *local_crypto = (local_participant_crypto *)crypto_object_table_find(impl->crypto_objects, local_id);
relation = crypto_key_relation_new(0, specific_key, CRYPTO_OBJECT(local_crypto), CRYPTO_OBJECT(remote_crypto), key_material->remote_key_material);
crypto_insert_specific_key_relation(remote_crypto, relation);
CRYPTO_OBJECT_RELEASE(local_crypto);
}
CRYPTO_OBJECT_RELEASE(relation);
}
CRYPTO_OBJECT_RELEASE(key_material);
}
else
@ -1189,8 +1235,7 @@ crypto_factory_set_datawriter_crypto_tokens(
remote_datawriter_crypto *remote_writer_crypto;
local_datareader_crypto *local_reader_crypto;
master_key_material *writer_master_key[2] = {NULL, NULL};
participant_key_material *keys;
endpoint_relation *relation;
key_relation *relation;
uint32_t key_id, i;
assert (num_key_mat > 0);
@ -1246,16 +1291,24 @@ crypto_factory_set_datawriter_crypto_tokens(
else
remote_writer_crypto->writer2reader_key_material[1] = (master_key_material *)CRYPTO_OBJECT_KEEP(writer_master_key[0]);
keys = (participant_key_material *)crypto_object_table_find(
remote_writer_crypto->participant->key_material, CRYPTO_OBJECT_HANDLE(local_reader_crypto->participant));
assert(keys);
key_id = remote_writer_crypto->writer2reader_key_material[0]->sender_key_id;
relation = crypto_endpoint_relation_new(DDS_SECURITY_DATAWRITER_SUBMESSAGE, key_id, (CryptoObject *)local_reader_crypto, (CryptoObject *)remote_writer_crypto);
crypto_object_table_insert(keys->endpoint_relations, (CryptoObject *)relation);
relation = crypto_key_relation_new(DDS_SECURITY_DATAWRITER_SUBMESSAGE, key_id, (CryptoObject *)local_reader_crypto, (CryptoObject *)remote_writer_crypto, NULL);
crypto_insert_endpoint_relation(remote_writer_crypto->participant, relation);
CRYPTO_OBJECT_RELEASE(relation);
CRYPTO_OBJECT_RELEASE(keys);
uint32_t specific_key = remote_writer_crypto->writer2reader_key_material[0]->receiver_specific_key_id;
if (specific_key != 0)
{
relation = crypto_find_specific_key_relation(remote_writer_crypto->participant, specific_key);
if (!relation)
{
relation = crypto_key_relation_new(0, specific_key, CRYPTO_OBJECT(local_reader_crypto), CRYPTO_OBJECT(remote_writer_crypto), remote_writer_crypto->writer2reader_key_material[0]);
crypto_insert_specific_key_relation(remote_writer_crypto->participant, relation);
}
CRYPTO_OBJECT_RELEASE(relation);
}
result = true;
err_inv_local:
@ -1328,8 +1381,7 @@ crypto_factory_set_datareader_crypto_tokens(
bool result = false;
remote_datareader_crypto *remote_reader_crypto;
local_datawriter_crypto *local_writer_crypto;
participant_key_material *keys;
endpoint_relation *relation;
key_relation *relation;
uint32_t key_id;
remote_reader_crypto = (remote_datareader_crypto *)crypto_object_table_find(impl->crypto_objects, remote_reader_handle);
@ -1373,23 +1425,30 @@ crypto_factory_set_datareader_crypto_tokens(
remote_reader_crypto->reader2writer_key_material = crypto_master_key_material_new(CRYPTO_TRANSFORMATION_KIND_NONE);
crypto_token_copy(remote_reader_crypto->reader2writer_key_material, key_mat);
keys = (participant_key_material *)crypto_object_table_find(
remote_reader_crypto->participant->key_material, CRYPTO_OBJECT_HANDLE(local_writer_crypto->participant));
assert(keys);
key_id = remote_reader_crypto->reader2writer_key_material->sender_key_id;
relation = crypto_endpoint_relation_new(DDS_SECURITY_DATAREADER_SUBMESSAGE, key_id, (CryptoObject *)local_writer_crypto, (CryptoObject *)remote_reader_crypto);
crypto_object_table_insert(keys->endpoint_relations, (CryptoObject *)relation);
relation = crypto_key_relation_new(DDS_SECURITY_DATAREADER_SUBMESSAGE, key_id, (CryptoObject *)local_writer_crypto, (CryptoObject *)remote_reader_crypto, NULL);
crypto_insert_endpoint_relation(remote_reader_crypto->participant, relation);
CRYPTO_OBJECT_RELEASE(relation);
CRYPTO_OBJECT_RELEASE(keys);
uint32_t specific_key = remote_reader_crypto->reader2writer_key_material->receiver_specific_key_id;
if (specific_key != 0)
{
relation = crypto_find_specific_key_relation(remote_reader_crypto->participant, specific_key);
if (!relation)
{
relation = crypto_key_relation_new(0, specific_key, CRYPTO_OBJECT(local_writer_crypto), CRYPTO_OBJECT(remote_reader_crypto), remote_reader_crypto->reader2writer_key_material);
crypto_insert_specific_key_relation(remote_reader_crypto->participant, relation);
}
CRYPTO_OBJECT_RELEASE(relation);
}
result = true;
err_inv_local:
CRYPTO_OBJECT_RELEASE(local_writer_crypto);
err_inv_remote:
CRYPTO_OBJECT_RELEASE(remote_reader_crypto);
return result;
}
@ -1494,7 +1553,7 @@ crypto_factory_get_local_participant_data_key_material(
result = true;
err_inv_crypto:
CRYPTO_OBJECT_RELEASE(CRYPTO_OBJECT(participant_crypto));
CRYPTO_OBJECT_RELEASE(participant_crypto);
err_no_crypto:
return result;
}
@ -1587,9 +1646,7 @@ crypto_factory_get_reader_key_material(
result = true;
}
else
{
result = get_local_volatile_sec_reader_key_material(impl, writer_id, session_key, protection_kind, ex);
}
err_inv_crypto:
CRYPTO_OBJECT_RELEASE(reader_crypto);
@ -1656,6 +1713,7 @@ crypto_factory_get_remote_writer_key_material(
err_inv_crypto:
CRYPTO_OBJECT_RELEASE(writer_crypto);
err_no_crypto:
return result;
}
@ -1805,25 +1863,6 @@ err_no_crypto:
return result;
}
struct collect_remote_participant_keys_args
{
uint32_t key_id;
endpoint_relation *relation;
};
/* Currently only collecting the first only */
static int
collect_remote_participant_keys(
CryptoObject *obj,
void *arg)
{
participant_key_material *keys = (participant_key_material *)obj;
struct collect_remote_participant_keys_args *info = arg;
info->relation = crypto_endpoint_relation_find_by_key(keys->endpoint_relations, info->key_id);
return (info->relation) ? 0 : 1;
}
bool
crypto_factory_get_endpoint_relation(
const dds_security_crypto_key_factory *factory,
@ -1837,20 +1876,20 @@ crypto_factory_get_endpoint_relation(
{
bool result = false;
dds_security_crypto_key_factory_impl *impl = (dds_security_crypto_key_factory_impl *)factory;
remote_participant_crypto *remote_pp_crypto;
local_participant_crypto *local_pp_crypto = NULL;
participant_key_material *keys = NULL;
endpoint_relation *relation = NULL;
remote_participant_crypto *rmt_pp;
local_participant_crypto *loc_pp = NULL;
local_datareader_crypto *loc_rd = NULL;
key_relation *relation = NULL;
remote_pp_crypto = (remote_participant_crypto *)crypto_object_table_find(impl->crypto_objects, remote_participant_handle);
if (!remote_pp_crypto)
rmt_pp = (remote_participant_crypto *)crypto_object_table_find(impl->crypto_objects, remote_participant_handle);
if (!rmt_pp)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
goto invalid_handle;
}
else if (!CRYPTO_OBJECT_VALID(remote_pp_crypto, CRYPTO_OBJECT_KIND_REMOTE_CRYPTO))
else if (!CRYPTO_OBJECT_VALID(rmt_pp, CRYPTO_OBJECT_KIND_REMOTE_CRYPTO))
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
@ -1858,40 +1897,27 @@ crypto_factory_get_endpoint_relation(
goto invalid_handle;
}
if (local_participant_handle != DDS_SECURITY_HANDLE_NIL)
if (key_id == 0 && local_participant_handle != DDS_SECURITY_HANDLE_NIL)
{
local_pp_crypto = (local_participant_crypto *)crypto_object_table_find(impl->crypto_objects, local_participant_handle);
if (!local_pp_crypto)
loc_pp = (local_participant_crypto *)crypto_object_table_find(impl->crypto_objects, local_participant_handle);
if (!loc_pp)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
goto invalid_handle;
}
else if (!CRYPTO_OBJECT_VALID(local_pp_crypto, CRYPTO_OBJECT_KIND_LOCAL_CRYPTO))
else if (!CRYPTO_OBJECT_VALID(loc_pp, CRYPTO_OBJECT_KIND_LOCAL_CRYPTO))
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE, 0,
DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE);
goto invalid_handle;
}
keys = (participant_key_material *)crypto_object_table_find(remote_pp_crypto->key_material, local_participant_handle);
}
if (keys)
{
relation = crypto_endpoint_relation_find_by_key(keys->endpoint_relations, key_id);
CRYPTO_OBJECT_RELEASE(keys);
}
else
{
struct collect_remote_participant_keys_args args = {key_id, NULL};
/* FIXME: Returning arbitrary local-remote relation will not work in Cyclone,
* because participants can have different security settings */
crypto_object_table_walk(remote_pp_crypto->key_material, collect_remote_participant_keys, &args);
relation = args.relation;
loc_rd = loc_pp->builtin_reader;
}
relation = crypto_find_endpoint_relation(rmt_pp, CRYPTO_OBJECT(loc_rd), key_id);
if (!relation)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT,
@ -1900,6 +1926,8 @@ crypto_factory_get_endpoint_relation(
goto invalid_handle;
}
assert(key_id == relation->key_id);
*category = relation->kind;
*remote_handle = CRYPTO_OBJECT_HANDLE(relation->remote_crypto);
*local_handle = CRYPTO_OBJECT_HANDLE(relation->local_crypto);
@ -1907,8 +1935,66 @@ crypto_factory_get_endpoint_relation(
invalid_handle:
CRYPTO_OBJECT_RELEASE(relation);
CRYPTO_OBJECT_RELEASE(local_pp_crypto);
CRYPTO_OBJECT_RELEASE(remote_pp_crypto);
CRYPTO_OBJECT_RELEASE(loc_pp);
CRYPTO_OBJECT_RELEASE(rmt_pp);
return result;
}
bool
crypto_factory_get_specific_keymat(
const dds_security_crypto_key_factory *factory,
CryptoObjectKind_t kind,
DDS_Security_Handle rmt_handle,
const struct receiver_specific_mac * const mac_list,
uint32_t num_mac,
uint32_t *index,
master_key_material **key_mat)
{
dds_security_crypto_key_factory_impl *impl = (dds_security_crypto_key_factory_impl *)factory;
CryptoObject *obj;
remote_participant_crypto *rmt_pp = NULL;
remote_datawriter_crypto *rmt_wr = NULL;
remote_datareader_crypto *rmt_rd = NULL;
key_relation *relation = NULL;
bool result = false;
obj = crypto_object_table_find(impl->crypto_objects, rmt_handle);
if (!obj)
return false;
switch (kind)
{
case CRYPTO_OBJECT_KIND_REMOTE_CRYPTO:
rmt_pp = (remote_participant_crypto *)obj;
break;
case CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO:
rmt_wr = (remote_datawriter_crypto *)obj;
rmt_pp = rmt_wr->participant;
break;
case CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO:
rmt_rd = (remote_datareader_crypto *)obj;
rmt_pp = rmt_rd->participant;
break;
default:
goto invalid_handle;
break;
}
for (uint32_t i = 0; i < num_mac; i++)
{
uint32_t key_id = CRYPTO_TRANSFORM_ID(mac_list[i].receiver_mac_key_id);
relation = crypto_find_specific_key_relation(rmt_pp, key_id);
if (relation)
{
*index = i;
*key_mat = CRYPTO_OBJECT_KEEP(relation->key_material);
result = true;
break;
}
}
invalid_handle:
CRYPTO_OBJECT_RELEASE(relation);
CRYPTO_OBJECT_RELEASE(obj);
return result;
}

View file

@ -148,4 +148,14 @@ bool crypto_factory_get_endpoint_relation(
DDS_Security_SecureSubmessageCategory_t *category,
DDS_Security_SecurityException *ex);
bool
crypto_factory_get_specific_keymat(
const dds_security_crypto_key_factory *factory,
CryptoObjectKind_t kind,
DDS_Security_Handle rmt_handle,
const struct receiver_specific_mac * const mac_list,
uint32_t num_mac,
uint32_t *index,
master_key_material **key_mat);
#endif /* CRYPTO_KEY_FACTORY_H */

View file

@ -18,6 +18,64 @@
#include "crypto_objects.h"
#include "crypto_utils.h"
static int compare_participant_handle(const void *va, const void *vb);
static int compare_endpoint_relation (const void *va, const void *vb);
static int compare_relation_key (const void *va, const void *vb);
static void key_relation_free(CryptoObject *obj);
const ddsrt_avl_ctreedef_t loc_pp_keymat_treedef =
DDSRT_AVL_CTREEDEF_INITIALIZER (offsetof (struct participant_key_material, loc_avlnode), offsetof (struct participant_key_material, rmt_pp_handle), compare_participant_handle, 0);
const ddsrt_avl_ctreedef_t rmt_pp_keymat_treedef =
DDSRT_AVL_CTREEDEF_INITIALIZER (offsetof (struct participant_key_material, rmt_avlnode), offsetof (struct participant_key_material, loc_pp_handle), compare_participant_handle, 0);
const ddsrt_avl_treedef_t endpoint_relation_treedef =
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct key_relation, avlnode), 0, compare_endpoint_relation, 0);
const ddsrt_avl_treedef_t specific_key_treedef =
DDSRT_AVL_TREEDEF_INITIALIZER (offsetof (struct key_relation, avlnode), offsetof (struct key_relation, key_id), compare_relation_key, 0);
static int compare_participant_handle(const void *va, const void *vb)
{
const DDS_Security_ParticipantCryptoHandle *ha = va;
const DDS_Security_ParticipantCryptoHandle *hb = vb;
if (*ha > *hb)
return 1;
else if (*ha < *hb)
return -1;
return 0;
}
static int compare_endpoint_relation (const void *va, const void *vb)
{
const key_relation *ra = va;
const key_relation *rb = vb;
int r;
r = (int)(ra->key_id - rb->key_id);
if (r != 0 || ra->local_crypto == 0 || rb->local_crypto == 0)
{
return r;
}
if (ra->local_crypto > rb->local_crypto)
return 1;
else if (ra->local_crypto < rb->local_crypto)
return -1;
else
return 0;
}
static int compare_relation_key (const void *va, const void *vb)
{
const uint32_t *ka = va;
const uint32_t *kb = vb;
return (int)(*ka - *kb);
}
bool crypto_object_valid(CryptoObject *obj, CryptoObjectKind_t kind)
{
return (obj && obj->kind == kind && obj->handle == (int64_t)(uintptr_t)obj);
@ -57,16 +115,15 @@ static void crypto_object_deinit(CryptoObject *obj)
void crypto_object_free(CryptoObject *obj)
{
if (obj && obj->destructor)
obj->destructor(obj);
}
CryptoObject * crypto_object_keep(CryptoObject *obj)
void * crypto_object_keep(CryptoObject *obj)
{
if (obj)
{
ddsrt_atomic_inc32(&obj->refcount);
}
return obj;
}
@ -76,26 +133,6 @@ void crypto_object_release(CryptoObject *obj)
crypto_object_free(obj);
}
static uint32_t participant_key_material_hash(const void *obj)
{
const participant_key_material *object = obj;
return (uint32_t)object->pp_local_handle;
}
static int participant_key_material_equal(const void *ha, const void *hb)
{
const participant_key_material *la = ha;
const participant_key_material *lb = hb;
return la->pp_local_handle == lb->pp_local_handle;
}
static CryptoObject * participant_key_material_find(const struct CryptoObjectTable *table, const void *arg)
{
struct participant_key_material template;
template.pp_local_handle = *(int64_t *)arg;
return crypto_object_table_find_by_template(table, &template);
}
CryptoObject * crypto_object_table_find_by_template(const struct CryptoObjectTable *table, const void *template)
{
return (CryptoObject *)ddsrt_hh_lookup(table->htab, template);
@ -301,7 +338,7 @@ session_key_material * crypto_session_key_material_new(master_key_material *mast
session->init_vector_suffix = crypto_get_random_uint64();
session->max_blocks_per_session = INT64_MAX; /* FIXME: should be a config parameter */
session->block_counter = session->max_blocks_per_session;
session->master_key_material = (master_key_material *)CRYPTO_OBJECT_KEEP(master_key);
session->master_key_material = CRYPTO_OBJECT_KEEP(master_key);
return session;
}
@ -321,7 +358,9 @@ static void local_participant_crypto__free(CryptoObject *obj)
CHECK_CRYPTO_OBJECT_KIND (obj, CRYPTO_OBJECT_KIND_LOCAL_CRYPTO);
CRYPTO_OBJECT_RELEASE (participant_crypto->session);
CRYPTO_OBJECT_RELEASE (participant_crypto->key_material);
ddsrt_avl_cfree(&loc_pp_keymat_treedef, &participant_crypto->key_material_table, 0);
crypto_object_deinit ((CryptoObject *)participant_crypto);
ddsrt_mutex_init(&participant_crypto->lock);
ddsrt_free (participant_crypto);
}
}
@ -333,6 +372,9 @@ local_participant_crypto * crypto_local_participant_crypto__new(DDS_Security_Ide
local_participant_crypto *participant_crypto = ddsrt_calloc (1, sizeof(*participant_crypto));
participant_crypto->identity_handle = participant_identity;
crypto_object_init ((CryptoObject *)participant_crypto, CRYPTO_OBJECT_KIND_LOCAL_CRYPTO, local_participant_crypto__free);
ddsrt_mutex_init(&participant_crypto->lock);
ddsrt_avl_cinit(&loc_pp_keymat_treedef, &participant_crypto->key_material_table);
return participant_crypto;
}
@ -344,8 +386,11 @@ static void remote_participant_crypto__free(CryptoObject *obj)
if (participant_crypto)
{
CRYPTO_OBJECT_RELEASE (participant_crypto->session);
crypto_object_table_free (participant_crypto->key_material);
ddsrt_avl_cfree(&rmt_pp_keymat_treedef, &participant_crypto->key_material_table, 0);
crypto_object_deinit ((CryptoObject *)participant_crypto);
ddsrt_avl_free(&endpoint_relation_treedef, &participant_crypto->relation_index, 0);
ddsrt_avl_free(&specific_key_treedef, &participant_crypto->specific_key_index, 0);
ddsrt_mutex_destroy(&participant_crypto->lock);
ddsrt_free(participant_crypto);
}
}
@ -356,7 +401,10 @@ remote_participant_crypto * crypto_remote_participant_crypto__new(DDS_Security_I
remote_participant_crypto *participant_crypto = ddsrt_calloc (1, sizeof(*participant_crypto));
crypto_object_init ((CryptoObject *)participant_crypto, CRYPTO_OBJECT_KIND_REMOTE_CRYPTO, remote_participant_crypto__free);
participant_crypto->identity_handle = participant_identity;
participant_crypto->key_material = crypto_object_table_new (participant_key_material_hash, participant_key_material_equal, participant_key_material_find);
ddsrt_avl_cinit(&rmt_pp_keymat_treedef, &participant_crypto->key_material_table);
ddsrt_mutex_init(&participant_crypto->lock);
ddsrt_avl_init(&endpoint_relation_treedef, &participant_crypto->relation_index);
ddsrt_avl_init(&specific_key_treedef, &participant_crypto->specific_key_index);
return participant_crypto;
}
@ -373,29 +421,129 @@ static void participant_key_material_free(CryptoObject *obj)
CRYPTO_OBJECT_RELEASE(keymaterial->P2P_kx_key_material);
CRYPTO_OBJECT_RELEASE(keymaterial->local_P2P_key_material);
CRYPTO_OBJECT_RELEASE(keymaterial->remote_key_material);
crypto_object_table_free(keymaterial->endpoint_relations);
crypto_object_deinit((CryptoObject *)keymaterial);
ddsrt_free(keymaterial);
}
}
participant_key_material * crypto_participant_key_material_new(const local_participant_crypto *pplocal)
participant_key_material * crypto_participant_key_material_new(const local_participant_crypto *loc_pp_crypto, const remote_participant_crypto *rmt_pp_crypto)
{
participant_key_material *keymaterial = ddsrt_calloc(1, sizeof(*keymaterial));
crypto_object_init((CryptoObject *)keymaterial, CRYPTO_OBJECT_KIND_PARTICIPANT_KEY_MATERIAL, participant_key_material_free);
keymaterial->pp_local_handle = pplocal->_parent.handle;
keymaterial->endpoint_relations = crypto_object_table_new(NULL, NULL, NULL);
keymaterial->loc_pp_handle = PARTICIPANT_CRYPTO_HANDLE(loc_pp_crypto);
keymaterial->rmt_pp_handle = PARTICIPANT_CRYPTO_HANDLE(rmt_pp_crypto);
keymaterial->local_P2P_key_material = crypto_master_key_material_new(CRYPTO_TRANSFORMATION_KIND_NONE);
keymaterial->P2P_kx_key_material = crypto_master_key_material_new(CRYPTO_TRANSFORMATION_KIND_AES256_GCM); /* as defined in table 67 of the DDS Security spec v1.1 */
return keymaterial;
}
static void endpoint_relation_free(CryptoObject *obj)
void crypto_local_participant_add_keymat(local_participant_crypto *loc_pp_crypto, participant_key_material *keymat)
{
endpoint_relation *relation = (endpoint_relation *)obj;
ddsrt_mutex_lock(&loc_pp_crypto->lock);
ddsrt_avl_cinsert(&loc_pp_keymat_treedef, &loc_pp_crypto->key_material_table, CRYPTO_OBJECT_KEEP(keymat));
ddsrt_mutex_unlock(&loc_pp_crypto->lock);
}
participant_key_material * crypto_local_participant_remove_keymat(local_participant_crypto *loc_pp_crypto, DDS_Security_ParticipantCryptoHandle rmt_pp_handle)
{
participant_key_material *keymat;
ddsrt_avl_dpath_t dpath;
ddsrt_mutex_lock(&loc_pp_crypto->lock);
keymat = ddsrt_avl_clookup_dpath(&loc_pp_keymat_treedef, &loc_pp_crypto->key_material_table, &rmt_pp_handle, &dpath);
if (keymat)
ddsrt_avl_cdelete_dpath(&loc_pp_keymat_treedef, &loc_pp_crypto->key_material_table, keymat, &dpath);
ddsrt_mutex_unlock(&loc_pp_crypto->lock);
return keymat;
}
participant_key_material * crypto_local_participant_lookup_keymat(local_participant_crypto *loc_pp_crypto, DDS_Security_ParticipantCryptoHandle rmt_pp_handle)
{
participant_key_material *keymat;
ddsrt_mutex_lock(&loc_pp_crypto->lock);
keymat = CRYPTO_OBJECT_KEEP(ddsrt_avl_clookup(&loc_pp_keymat_treedef, &loc_pp_crypto->key_material_table, &rmt_pp_handle));
ddsrt_mutex_unlock(&loc_pp_crypto->lock);
return keymat;
}
void crypto_remote_participant_add_keymat(remote_participant_crypto *rmt_pp_crypto, participant_key_material *keymat)
{
ddsrt_mutex_lock(&rmt_pp_crypto->lock);
ddsrt_avl_cinsert(&rmt_pp_keymat_treedef, &rmt_pp_crypto->key_material_table, CRYPTO_OBJECT_KEEP(keymat));
ddsrt_mutex_unlock(&rmt_pp_crypto->lock);
}
participant_key_material * crypto_remote_participant_remove_keymat(remote_participant_crypto *rmt_pp_crypto, DDS_Security_ParticipantCryptoHandle loc_pp_handle)
{
participant_key_material *keymat;
ddsrt_avl_dpath_t dpath;
ddsrt_mutex_lock(&rmt_pp_crypto->lock);
keymat = ddsrt_avl_clookup_dpath(&rmt_pp_keymat_treedef, &rmt_pp_crypto->key_material_table, &loc_pp_handle, &dpath);
if (keymat)
ddsrt_avl_cdelete_dpath(&rmt_pp_keymat_treedef, &rmt_pp_crypto->key_material_table, keymat, &dpath);
ddsrt_mutex_unlock(&rmt_pp_crypto->lock);
return keymat;
}
participant_key_material * crypto_remote_participant_lookup_keymat(remote_participant_crypto *rmt_pp_crypto, DDS_Security_ParticipantCryptoHandle loc_pp_handle)
{
participant_key_material *keymat;
ddsrt_mutex_lock(&rmt_pp_crypto->lock);
keymat = CRYPTO_OBJECT_KEEP(ddsrt_avl_clookup(&rmt_pp_keymat_treedef, &rmt_pp_crypto->key_material_table, &loc_pp_handle));
ddsrt_mutex_unlock(&rmt_pp_crypto->lock);
return keymat;
}
size_t crypto_local_participnant_get_matching(local_participant_crypto *loc_pp_crypto, DDS_Security_ParticipantCryptoHandle **handles)
{
participant_key_material *keymat;
ddsrt_avl_citer_t it;
size_t num, i;
ddsrt_mutex_lock(&loc_pp_crypto->lock);
num = ddsrt_avl_ccount(&loc_pp_crypto->key_material_table);
if (num > 0)
{
*handles = ddsrt_malloc(num * sizeof(DDS_Security_ParticipantCryptoHandle));
for (i = 0, keymat = ddsrt_avl_citer_first(&loc_pp_keymat_treedef, &loc_pp_crypto->key_material_table, &it); i < num && keymat; i++, keymat = ddsrt_avl_citer_next(&it))
(*handles)[i] = keymat->rmt_pp_handle;
}
ddsrt_mutex_unlock(&loc_pp_crypto->lock);
return num;
}
size_t crypto_remote_participnant_get_matching(remote_participant_crypto *rmt_pp_crypto, DDS_Security_ParticipantCryptoHandle **handles)
{
participant_key_material *keymat;
ddsrt_avl_citer_t it;
size_t num, i;
ddsrt_mutex_lock(&rmt_pp_crypto->lock);
num = ddsrt_avl_ccount(&rmt_pp_crypto->key_material_table);
if (num > 0)
{
*handles = ddsrt_malloc(num * sizeof(DDS_Security_ParticipantCryptoHandle));
for (i = 0, keymat = ddsrt_avl_citer_first(&rmt_pp_keymat_treedef, &rmt_pp_crypto->key_material_table, &it); i < num && keymat; i++, keymat = ddsrt_avl_citer_next(&it))
(*handles)[i] = keymat->loc_pp_handle;
}
ddsrt_mutex_unlock(&rmt_pp_crypto->lock);
return num;
}
static void key_relation_free(CryptoObject *obj)
{
key_relation *relation = (key_relation *)obj;
if (relation)
{
CRYPTO_OBJECT_RELEASE(relation->key_material);
CRYPTO_OBJECT_RELEASE(relation->local_crypto);
CRYPTO_OBJECT_RELEASE(relation->remote_crypto);
crypto_object_deinit((CryptoObject *)relation);
@ -403,16 +551,17 @@ static void endpoint_relation_free(CryptoObject *obj)
}
}
endpoint_relation * crypto_endpoint_relation_new(DDS_Security_SecureSubmessageCategory_t kind,
uint32_t key_id, CryptoObject *local_crypto, CryptoObject *remote_crypto)
key_relation * crypto_key_relation_new(DDS_Security_SecureSubmessageCategory_t kind,
uint32_t key_id, CryptoObject *local_crypto, CryptoObject *remote_crypto, master_key_material *keymat)
{
endpoint_relation *relation = ddsrt_malloc(sizeof(*relation));
crypto_object_init((CryptoObject *)relation, CRYPTO_OBJECT_KIND_ENDPOINT_RELATION, endpoint_relation_free);
key_relation *relation = ddsrt_malloc(sizeof(*relation));
crypto_object_init((CryptoObject *)relation, CRYPTO_OBJECT_KIND_RELATION, key_relation_free);
relation->kind = kind;
relation->key_id = key_id;
relation->local_crypto = CRYPTO_OBJECT_KEEP(local_crypto);
relation->remote_crypto = CRYPTO_OBJECT_KEEP(remote_crypto);
relation->key_material = (master_key_material *)CRYPTO_OBJECT_KEEP(keymat);
return relation;
}
@ -539,60 +688,90 @@ remote_datareader_crypto *crypto_remote_datareader_crypto__new(const remote_part
return reader_crypto;
}
typedef struct endpoint_relation_find_arg
void crypto_insert_endpoint_relation(
remote_participant_crypto *rpc,
key_relation *relation)
{
CryptoObject *found;
CryptoObject *local_crypto;
CryptoObject *remote_crypto;
uint32_t key_id;
} endpoint_relation_find_arg;
ddsrt_mutex_lock(&rpc->lock);
ddsrt_avl_insert(&endpoint_relation_treedef, &rpc->relation_index, CRYPTO_OBJECT_KEEP(relation));
ddsrt_mutex_unlock(&rpc->lock);
}
static int endpoint_relation_cmp_key(CryptoObject *obj, void *arg)
void crypto_remove_endpoint_relation(
remote_participant_crypto *rpc,
CryptoObject *lch,
uint32_t key_id)
{
const endpoint_relation *rel = (const endpoint_relation *)obj;
endpoint_relation_find_arg *find_arg = (endpoint_relation_find_arg *)arg;
key_relation template;
key_relation *relation;
ddsrt_avl_dpath_t dpath;
if (rel->key_id == find_arg->key_id)
template.key_id = key_id;
template.local_crypto = lch;
ddsrt_mutex_lock(&rpc->lock);
relation = ddsrt_avl_lookup_dpath(&endpoint_relation_treedef, &rpc->relation_index, &template, &dpath);
if (relation)
{
find_arg->found = crypto_object_keep(obj);
return 0;
ddsrt_avl_delete_dpath(&endpoint_relation_treedef, &rpc->relation_index, relation, &dpath);
CRYPTO_OBJECT_RELEASE(relation);
}
return 1;
ddsrt_mutex_unlock(&rpc->lock);
}
static int endpoint_relation_cmp_crypto(CryptoObject *obj, void *arg)
key_relation * crypto_find_endpoint_relation(
remote_participant_crypto *rpc,
CryptoObject *lch,
uint32_t key_id)
{
const endpoint_relation *rel = (const endpoint_relation *)obj;
endpoint_relation_find_arg *find_arg = (endpoint_relation_find_arg *)arg;
key_relation template;
key_relation *relation;
if ((rel->local_crypto == find_arg->local_crypto) &&
(rel->remote_crypto == find_arg->remote_crypto))
template.key_id = key_id;
template.local_crypto = lch;
ddsrt_mutex_lock(&rpc->lock);
relation = CRYPTO_OBJECT_KEEP(ddsrt_avl_lookup(&endpoint_relation_treedef, &rpc->relation_index, &template));
ddsrt_mutex_unlock(&rpc->lock);
return relation;
}
void crypto_insert_specific_key_relation(
remote_participant_crypto *rpc,
key_relation *relation)
{
ddsrt_mutex_lock(&rpc->lock);
ddsrt_avl_insert(&specific_key_treedef, &rpc->specific_key_index, CRYPTO_OBJECT_KEEP(relation));
ddsrt_mutex_unlock(&rpc->lock);
}
void crypto_remove_specific_key_relation(
remote_participant_crypto *rpc,
uint32_t key_id)
{
key_relation *relation;
ddsrt_avl_dpath_t dpath;
ddsrt_mutex_lock(&rpc->lock);
relation = ddsrt_avl_lookup_dpath(&specific_key_treedef, &rpc->specific_key_index, &key_id, &dpath);
if (relation)
{
find_arg->found = crypto_object_keep(obj);
return 0;
ddsrt_avl_delete_dpath(&specific_key_treedef, &rpc->specific_key_index, relation, &dpath);
CRYPTO_OBJECT_RELEASE(relation);
}
return 1;
ddsrt_mutex_unlock(&rpc->lock);
}
endpoint_relation * crypto_endpoint_relation_find_by_key(struct CryptoObjectTable *table, uint32_t key_id)
key_relation * crypto_find_specific_key_relation(
remote_participant_crypto *rpc,
uint32_t key_id)
{
endpoint_relation_find_arg find_arg;
find_arg.found = NULL;
find_arg.key_id = key_id;
find_arg.local_crypto = NULL;
find_arg.remote_crypto = NULL;
crypto_object_table_walk(table, endpoint_relation_cmp_key, &find_arg);
return (endpoint_relation *)(find_arg.found);
}
key_relation *relation;
endpoint_relation * crypto_endpoint_relation_find_by_crypto(struct CryptoObjectTable *table, CryptoObject *local_crypto, CryptoObject *remote_crypto)
{
endpoint_relation_find_arg find_arg;
find_arg.found = NULL;
find_arg.key_id = 0;
find_arg.local_crypto = local_crypto;
find_arg.remote_crypto = remote_crypto;
crypto_object_table_walk(table, endpoint_relation_cmp_crypto, &find_arg);
return (endpoint_relation *)(find_arg.found);
ddsrt_mutex_lock(&rpc->lock);
relation = CRYPTO_OBJECT_KEEP(ddsrt_avl_lookup(&specific_key_treedef, &rpc->specific_key_index, &key_id));
ddsrt_mutex_unlock(&rpc->lock);
return relation;
}

View file

@ -16,6 +16,8 @@
#include "dds/ddsrt/atomics.h"
#include "dds/ddsrt/sync.h"
#include "dds/ddsrt/types.h"
#include "dds/ddsrt/avl.h"
#include "dds/ddsrt/sync.h"
#include "dds/security/dds_security_api.h"
#include "dds/security/core/dds_security_utils.h"
#include "crypto_defs.h"
@ -38,6 +40,7 @@
#define CRYPTO_TRANSFORM_HAS_KEYS(k) ((k) != CRYPTO_TRANSFORMATION_KIND_NONE && (k) != CRYPTO_TRANSFORMATION_KIND_INVALID)
typedef DDS_Security_ParticipantCryptoHandle DDS_Security_LocalParticipantCryptoHandle;
typedef DDS_Security_ParticipantCryptoHandle DDS_Security_RemoteParticipantCryptoHandle;
@ -53,7 +56,7 @@ typedef enum
CRYPTO_OBJECT_KIND_KEY_MATERIAL,
CRYPTO_OBJECT_KIND_SESSION_KEY_MATERIAL,
CRYPTO_OBJECT_KIND_PARTICIPANT_KEY_MATERIAL,
CRYPTO_OBJECT_KIND_ENDPOINT_RELATION
CRYPTO_OBJECT_KIND_RELATION
} CryptoObjectKind_t;
typedef struct CryptoObject CryptoObject;
@ -103,44 +106,54 @@ typedef struct remote_session_info
crypto_session_key_t key;
} remote_session_info;
typedef struct endpoint_relation
typedef struct key_relation
{
CryptoObject _parent;
ddsrt_avl_node_t avlnode;
DDS_Security_SecureSubmessageCategory_t kind;
uint32_t key_id;
CryptoObject *local_crypto;
CryptoObject *remote_crypto;
} endpoint_relation;
master_key_material *key_material;
} key_relation;
typedef struct local_participant_crypto
{
CryptoObject _parent;
ddsrt_mutex_t lock;
master_key_material *key_material;
DDS_Security_IdentityHandle identity_handle;
ddsrt_avl_ctree_t key_material_table;
session_key_material *session;
DDS_Security_ProtectionKind rtps_protection_kind;
struct local_datareader_crypto *builtin_reader;
} local_participant_crypto;
typedef struct participant_key_material
{
CryptoObject _parent;
DDS_Security_ParticipantCryptoHandle pp_local_handle;
ddsrt_avl_node_t loc_avlnode;
ddsrt_avl_node_t rmt_avlnode;
DDS_Security_ParticipantCryptoHandle loc_pp_handle;
DDS_Security_ParticipantCryptoHandle rmt_pp_handle;
master_key_material *remote_key_material;
master_key_material *local_P2P_key_material;
master_key_material *P2P_kx_key_material;
session_key_material *P2P_writer_session;
session_key_material *P2P_reader_session;
struct CryptoObjectTable *endpoint_relations;
} participant_key_material;
typedef struct remote_participant_crypto
{
CryptoObject _parent;
ddsrt_mutex_t lock;
DDS_Security_GUID_t remoteGuid;
DDS_Security_IdentityHandle identity_handle;
struct CryptoObjectTable *key_material;
ddsrt_avl_ctree_t key_material_table;
session_key_material *session;
DDS_Security_ProtectionKind rtps_protection_kind;
ddsrt_avl_tree_t relation_index;
ddsrt_avl_tree_t specific_key_index;
} remote_participant_crypto;
typedef struct local_datawriter_crypto
@ -223,28 +236,45 @@ void crypto_object_init(
CryptoObjectKind_t kind,
CryptoObjectDestructor destructor);
endpoint_relation *
crypto_endpoint_relation_new(
key_relation *
crypto_key_relation_new(
DDS_Security_SecureSubmessageCategory_t kind,
uint32_t key_id,
CryptoObject *local_crypto,
CryptoObject *remote_crypto);
CryptoObject *remote_crypto,
master_key_material *keymat);
endpoint_relation *
crypto_endpoint_relation_find_by_key(
struct CryptoObjectTable *table,
void
crypto_insert_endpoint_relation(
remote_participant_crypto *rpc,
key_relation *relation);
void
crypto_remove_endpoint_relation(
remote_participant_crypto *rpc,
CryptoObject *lch,
uint32_t key_id);
endpoint_relation *
crypto_endpoint_relation_find_by_crypto(
struct CryptoObjectTable *table,
CryptoObject *local_crypto,
CryptoObject *remote_crypto);
key_relation *
crypto_find_endpoint_relation(
remote_participant_crypto *rpc,
CryptoObject *lch,
uint32_t key_id);
bool endpoint_relation_get_locals(
const endpoint_relation *relation,
const local_participant_crypto *participant,
DDS_Security_HandleSeq *list);
void
crypto_insert_specific_key_relation(
remote_participant_crypto *rpc,
key_relation *relation);
void
crypto_remove_specific_key_relation(
remote_participant_crypto *rpc,
uint32_t key_id);
key_relation *
crypto_find_specific_key_relation(
remote_participant_crypto *rpc,
uint32_t key_id);
local_datawriter_crypto *
crypto_local_datawriter_crypto__new(
@ -272,7 +302,7 @@ crypto_remote_datawriter_crypto__new(
DDS_Security_BasicProtectionKind data_protection,
local_datareader_crypto *local_reader);
CryptoObject *
void *
crypto_object_keep(
CryptoObject *obj);
@ -296,7 +326,8 @@ crypto_remote_participant_crypto__new(
participant_key_material *
crypto_participant_key_material_new(
const local_participant_crypto *pplocal);
const local_participant_crypto *loc_pp_crypto,
const remote_participant_crypto *rmt_pp_crypto);
struct CryptoObjectTable;
@ -351,4 +382,44 @@ void crypto_object_table_walk(
CryptoObjectTableCallback callback,
void *arg);
void
crypto_local_participant_add_keymat(
local_participant_crypto *loc_pp_crypte,
participant_key_material *keymat);
participant_key_material *
crypto_local_participant_remove_keymat(
local_participant_crypto *loc_pp_crypte,
DDS_Security_ParticipantCryptoHandle rmt_pp_handle);
participant_key_material *
crypto_local_participant_lookup_keymat(
local_participant_crypto *loc_pp_crypte,
DDS_Security_ParticipantCryptoHandle rmt_pp_handle);
void
crypto_remote_participant_add_keymat(
remote_participant_crypto *rmt_pp_crypte,
participant_key_material *keymat);
participant_key_material *
crypto_remote_participant_remove_keymat(
remote_participant_crypto *rmt_pp_crypte,
DDS_Security_ParticipantCryptoHandle loc_pp_handle);
participant_key_material *
crypto_remote_participant_lookup_keymat(
remote_participant_crypto *rmt_pp_crypte,
DDS_Security_ParticipantCryptoHandle loc_pp_handle);
size_t
crypto_local_participnant_get_matching(
local_participant_crypto *loc_pp_crypto,
DDS_Security_ParticipantCryptoHandle **handles);
size_t
crypto_remote_participnant_get_matching(
remote_participant_crypto *rmt_pp_crypto,
DDS_Security_ParticipantCryptoHandle **handles);
#endif /* CRYPTO_OBJECTS_H */

View file

@ -68,12 +68,6 @@ struct crypto_contents_ref
unsigned char *_data;
};
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
crypto_hmac_t receiver_mac;
};
struct receiver_specific_mac_seq
{
uint32_t _length;
@ -1467,64 +1461,73 @@ enc_dr_submsg_inv_args:
return result;
}
static DDS_Security_boolean
static bool
check_reader_specific_mac(
dds_security_crypto_key_factory *factory,
struct crypto_header *header,
struct crypto_footer *footer,
master_key_material *key_material,
CryptoObjectKind_t kind,
DDS_Security_Handle rmt_handle,
const char *context,
DDS_Security_SecurityException *ex)
{
bool result = false;
master_key_material *keymat = NULL;
uint32_t index;
uint32_t session_id;
crypto_session_key_t key;
crypto_hmac_t *href = NULL;
crypto_hmac_t hmac;
uint32_t i;
if (key_material->receiver_specific_key_id == 0)
if (footer->receiver_specific_macs._length == 0)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_RECEIVER_SIGN_CODE, 0,
"%s: don't have receiver key material to check specific mac", context);
"%s: message does not contain a receiver specific mac", context);
return false;
}
session_id = CRYPTO_TRANSFORM_ID(header->session_id);
for (i = 0; !href && (i < footer->receiver_specific_macs._length); i++)
if (!crypto_factory_get_specific_keymat(factory, kind, rmt_handle, &footer->receiver_specific_macs._buffer[0], footer->receiver_specific_macs._length, &index, &keymat))
{
uint32_t id = CRYPTO_TRANSFORM_ID(footer->receiver_specific_macs._buffer[i].receiver_mac_key_id);
if (id == key_material->receiver_specific_key_id)
href = &footer->receiver_specific_macs._buffer[i].receiver_mac;
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_RECEIVER_SIGN_CODE, 0,
"%s: message does not contain a known receiver specific key", context);
goto check_failed;
}
href = &footer->receiver_specific_macs._buffer[index].receiver_mac;
if (!href)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_RECEIVER_SIGN_CODE, 0,
"%s: message does not contain receiver specific mac", context);
return false;
goto check_failed;
}
if (!crypto_calculate_receiver_specific_key(&key, session_id, key_material->master_salt, key_material->master_receiver_specific_key, key_material->transformation_kind, ex))
session_id = CRYPTO_TRANSFORM_ID(header->session_id);
if (!crypto_calculate_receiver_specific_key(&key, session_id, keymat->master_salt, keymat->master_receiver_specific_key, keymat->transformation_kind, ex))
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_RECEIVER_SIGN_CODE, 0,
"%s: failed to calculate receiver specific session key", context);
return false;
goto check_failed;
}
if (!crypto_cipher_encrypt_data(&key, crypto_get_key_size(key_material->transformation_kind), header->session_id, NULL, 0, footer->common_mac.data, CRYPTO_HMAC_SIZE, NULL, NULL, &hmac, ex))
if (!crypto_cipher_encrypt_data(&key, crypto_get_key_size(keymat->transformation_kind), header->session_id, NULL, 0, footer->common_mac.data, CRYPTO_HMAC_SIZE, NULL, NULL, &hmac, ex))
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_RECEIVER_SIGN_CODE, 0,
"%s: failed to calculate receiver specific hmac", context);
return false;
goto check_failed;
}
if (memcmp(hmac.data, href->data, CRYPTO_HMAC_SIZE) != 0)
{
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_RECEIVER_SIGN_CODE, 0,
"%s: message does not contain a valid receiver specific mac", context);
return false;
goto check_failed;
}
return true;
result = true;
check_failed:
CRYPTO_OBJECT_RELEASE(keymat);
return result;
}
static DDS_Security_boolean encode_rtps_message_sign (
@ -1878,7 +1881,7 @@ decode_rtps_message(dds_security_crypto_transform *instance,
if (has_origin_authentication(remote_protection_kind))
{ /* default governance value */
if (!check_reader_specific_mac(&header, footer, pp_key_material->remote_key_material, context, ex))
if (!check_reader_specific_mac(factory, &header, footer, CRYPTO_OBJECT_KIND_REMOTE_CRYPTO, sending_participant_crypto, context, ex))
goto fail_reader_mac;
}
@ -2095,7 +2098,7 @@ decode_datawriter_submessage(
if (has_origin_authentication(protection_kind))
{
if (!check_reader_specific_mac(&header, footer, writer_master_key, context, ex))
if (!check_reader_specific_mac(factory, &header, footer, CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO, writer_crypto, context, ex))
goto fail_reader_mac;
}
@ -2137,6 +2140,7 @@ decode_datawriter_submessage(
"decode_datawriter_submessage: submessage is signed, which is unexpected");
goto fail_decrypt;
}
assert(transform_id != 0);
/* When the CryptoHeader indicates that authentication is performed then calculate the HMAC */
if (!crypto_cipher_decrypt_data(&remote_session, header.session_id, NULL, 0, contents._data, contents._length, NULL, 0, &footer->common_mac, ex))
goto fail_decrypt;
@ -2218,7 +2222,7 @@ decode_datareader_submessage(
if (has_origin_authentication(protection_kind))
{
if (!check_reader_specific_mac(&header, footer, reader_master_key, context, ex))
if (!check_reader_specific_mac(factory, &header, footer, CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO, reader_crypto, context, ex))
goto fail_reader_mac;
}

View file

@ -63,11 +63,13 @@ struct crypto_footer
unsigned char length[4];
};
#if 0
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
unsigned char receiver_mac[CRYPTO_HMAC_SIZE];
};
#endif
struct seq_number
{
@ -1559,7 +1561,7 @@ CU_Test(ddssec_builtin_decode_datareader_submessage, invalid_data, .init = suite
CU_ASSERT(len == 1);
rmac = (struct receiver_specific_mac *)(footer + 1);
rmac->receiver_mac[0] = (unsigned char)(rmac->receiver_mac[0] + 1);
rmac->receiver_mac.data[0] = (unsigned char)(rmac->receiver_mac.data[0] + 1);
result = crypto->crypto_transform->decode_datareader_submessage(
crypto->crypto_transform,

View file

@ -70,11 +70,13 @@ struct crypto_footer
unsigned char length[4];
};
#if 0
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
unsigned char receiver_mac[CRYPTO_HMAC_SIZE];
};
#endif
static void reset_exception(DDS_Security_SecurityException *ex)
{
@ -1579,7 +1581,7 @@ CU_Test(ddssec_builtin_decode_datawriter_submessage, invalid_data, .init = suite
CU_ASSERT(len == 1);
rmac = (struct receiver_specific_mac *)(footer + 1);
rmac->receiver_mac[0] = (unsigned char)(rmac->receiver_mac[0] + 1);
rmac->receiver_mac.data[0] = (unsigned char)(rmac->receiver_mac.data[0] + 1);
result = crypto->crypto_transform->decode_datawriter_submessage(
crypto->crypto_transform,

View file

@ -75,11 +75,13 @@ struct crypto_footer
unsigned char length[4];
};
#if 0
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
unsigned char receiver_mac[CRYPTO_HMAC_SIZE];
};
#endif
static void reset_exception(DDS_Security_SecurityException *ex)
{

View file

@ -66,11 +66,13 @@ struct crypto_footer
uint32_t length;
};
#if 0
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
unsigned char receiver_mac[CRYPTO_HMAC_SIZE];
};
#endif
struct encrypted_data
{
@ -744,7 +746,7 @@ static bool check_writer_signing(DDS_Security_DatareaderCryptoHandleSeq *list, s
for (i = 0; i < list->_length; i++)
{
key_id = ddsrt_bswap4u(*(uint32_t *)rmac[i].receiver_mac_key_id);
if (!check_writer_sign(list->_buffer[i], session_id, key_id, key_size, init_vector, footer->common_mac, rmac[i].receiver_mac))
if (!check_writer_sign(list->_buffer[i], session_id, key_id, key_size, init_vector, footer->common_mac, rmac[i].receiver_mac.data))
{
return false;
}

View file

@ -72,11 +72,13 @@ struct crypto_footer
uint32_t length;
};
#if 0
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
unsigned char receiver_mac[CRYPTO_HMAC_SIZE];
};
#endif
struct encrypted_data
{
@ -742,7 +744,7 @@ static bool check_reader_signing(DDS_Security_DatareaderCryptoHandleSeq *list, s
for (i = 0; i < list->_length; i++)
{
key_id = ddsrt_bswap4u(*(uint32_t *)rmac[i].receiver_mac_key_id);
if (!check_reader_sign(list->_buffer[i], session_id, key_id, key_size, init_vector, footer->common_mac, rmac[i].receiver_mac))
if (!check_reader_sign(list->_buffer[i], session_id, key_id, key_size, init_vector, footer->common_mac, rmac[i].receiver_mac.data))
{
return false;
}

View file

@ -73,11 +73,13 @@ struct crypto_footer
uint32_t length;
};
#if 0
struct receiver_specific_mac
{
DDS_Security_CryptoTransformKeyId receiver_mac_key_id;
unsigned char receiver_mac[CRYPTO_HMAC_SIZE];
};
#endif
static void reset_exception(DDS_Security_SecurityException *ex)
{
@ -567,32 +569,20 @@ static session_key_material * get_local_participant_session(DDS_Security_Partici
return participant_crypto_impl->session;
}
static participant_key_material * keymaterial_table_find(struct CryptoObjectTable *table, uint64_t handle)
{
CryptoObject *object;
assert(table);
ddsrt_mutex_lock(&table->lock);
object = table->findfnc(table, &handle);
ddsrt_mutex_unlock(&table->lock);
return (participant_key_material *)object;
}
static master_key_material * get_remote_participant_key_material(DDS_Security_ParticipantCryptoHandle participant_crypto)
{
participant_key_material *key_material;
master_key_material * master_keymat = NULL;
remote_participant_crypto *participant_crypto_impl = (remote_participant_crypto *)participant_crypto;
key_material = (participant_key_material *)keymaterial_table_find(participant_crypto_impl->key_material, (uint64_t) local_particpant_crypto);
if (!key_material)
key_material = crypto_remote_participant_lookup_keymat(participant_crypto_impl, local_particpant_crypto);
if (key_material)
{
return NULL;
}
else
{
return key_material->local_P2P_key_material;
master_keymat = key_material->local_P2P_key_material;
CRYPTO_OBJECT_RELEASE(key_material);
}
return master_keymat;
}
static void set_protection_kind(DDS_Security_ParticipantCryptoHandle participant_crypto, DDS_Security_ProtectionKind protection_kind)
@ -692,7 +682,7 @@ static bool check_signing(
for (i = 0; i < list->_length; i++)
{
key_id = ddsrt_bswap4u(*(uint32_t *)rmac[i].receiver_mac_key_id);
if (!check_sign(list->_buffer[i], session_id, key_id, key_size, init_vector, footer->common_mac, rmac[i].receiver_mac))
if (!check_sign(list->_buffer[i], session_id, key_id, key_size, init_vector, footer->common_mac, rmac[i].receiver_mac.data))
{
return false;
}

View file

@ -663,6 +663,7 @@ CU_Test(ddssec_builtin_preprocess_secure_submsg, invalid_args, .init = suite_pre
CU_ASSERT(exception.message != NULL);
reset_exception(&exception);
#if 0
/* unknown local_participant_handle */
result = crypto->crypto_transform->preprocess_secure_submsg(
crypto->crypto_transform,
@ -681,6 +682,7 @@ CU_Test(ddssec_builtin_preprocess_secure_submsg, invalid_args, .init = suite_pre
CU_ASSERT(exception.code != 0);
CU_ASSERT(exception.message != NULL);
reset_exception(&exception);
#endif
/* remote_participant_handle = DDS_SECURITY_HANDLE_NIL */
result = crypto->crypto_transform->preprocess_secure_submsg(

View file

@ -54,6 +54,14 @@ static void prepare_participant_security_attributes(DDS_Security_ParticipantSecu
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
}
static void reset_exception(DDS_Security_SecurityException *ex)
{
ex->code = 0;
ex->minor_code = 0;
ddsrt_free(ex->message);
ex->message = NULL;
}
static void suite_register_local_datareader_init(void)
{
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
@ -111,6 +119,14 @@ static void suite_register_local_datareader_init(void)
static void suite_register_local_datareader_fini(void)
{
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = (DDS_Security_SharedSecretHandleImpl *)shared_secret_handle;
DDS_Security_SecurityException exception = {NULL, 0, 0};
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_participant_crypto_handle, &exception);
reset_exception(&exception);
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, local_participant_crypto_handle, &exception);
reset_exception(&exception);
unload_plugins(plugins);
ddsrt_free(shared_secret_handle_impl->shared_secret);
ddsrt_free(shared_secret_handle_impl);
@ -120,13 +136,7 @@ static void suite_register_local_datareader_fini(void)
remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
}
static void reset_exception(DDS_Security_SecurityException *ex)
{
ex->code = 0;
ex->minor_code = 0;
ddsrt_free(ex->message);
ex->message = NULL;
}
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
{

View file

@ -54,6 +54,14 @@ static void prepare_participant_security_attributes(DDS_Security_ParticipantSecu
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
}
static void reset_exception(DDS_Security_SecurityException *ex)
{
ex->code = 0;
ex->minor_code = 0;
ddsrt_free(ex->message);
ex->message = NULL;
}
static void suite_register_local_datawriter_init(void)
{
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
@ -114,6 +122,14 @@ static void suite_register_local_datawriter_init(void)
static void suite_register_local_datawriter_fini(void)
{
DDS_Security_SecurityException exception = {NULL, 0, 0};
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_participant_crypto_handle, &exception);
reset_exception(&exception);
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, local_participant_crypto_handle, &exception);
reset_exception(&exception);
unload_plugins(plugins);
shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
crypto = NULL;
@ -121,14 +137,6 @@ static void suite_register_local_datawriter_fini(void)
remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
}
static void reset_exception(DDS_Security_SecurityException *ex)
{
ex->code = 0;
ex->minor_code = 0;
ddsrt_free(ex->message);
ex->message = NULL;
}
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
{
memset(attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));

View file

@ -435,13 +435,13 @@ static void test_data_protection_kind(DDS_Security_ProtectionKind rtps_pk, DDS_S
static void test_multiple_readers(size_t n_dom, size_t n_pp, size_t n_rd, DDS_Security_ProtectionKind metadata_pk, DDS_Security_BasicProtectionKind payload_pk)
{
struct domain_sec_config domain_config = { PK_N, PK_N, PK_N, metadata_pk, payload_pk, NULL };
test_write_read (&domain_config, n_dom, n_pp, n_rd, 1, 1, 1, NULL);
test_write_read (&domain_config, n_dom, n_pp, n_rd, 1, 1, 1, set_encryption_parameters_basic);
}
static void test_multiple_writers(size_t n_rd_dom, size_t n_rd, size_t n_wr_dom, size_t n_wr, DDS_Security_ProtectionKind metadata_pk)
{
struct domain_sec_config domain_config = { PK_N, PK_N, PK_N, metadata_pk, BPK_N, NULL };
test_write_read (&domain_config, n_rd_dom, 1, n_rd, n_wr_dom, 1, n_wr, NULL);
test_write_read (&domain_config, n_rd_dom, 1, n_rd, n_wr_dom, 1, n_wr, set_encryption_parameters_basic);
}
static void test_payload_secret(DDS_Security_ProtectionKind rtps_pk, DDS_Security_ProtectionKind metadata_pk, DDS_Security_BasicProtectionKind payload_pk)
@ -544,7 +544,7 @@ CU_TheoryDataPoints(ddssec_secure_communication, multiple_readers) = {
CU_DataPoints(size_t, 1, 3, 1, 3), /* number of participants per domain */
CU_DataPoints(size_t, 3, 1, 3, 3), /* number of readers per participant */
};
CU_Theory((size_t n_dom, size_t n_pp, size_t n_rd), ddssec_secure_communication, multiple_readers, .timeout = 60, .disabled = true)
CU_Theory((size_t n_dom, size_t n_pp, size_t n_rd), ddssec_secure_communication, multiple_readers, .timeout = 60, .disabled = false)
{
DDS_Security_ProtectionKind metadata_pk[] = { PK_N, PK_SOA, PK_EOA };
DDS_Security_BasicProtectionKind payload_pk[] = { BPK_N, BPK_S, BPK_E };
@ -563,7 +563,7 @@ CU_TheoryDataPoints(ddssec_secure_communication, multiple_readers_writers) = {
CU_DataPoints(size_t, 1, 1, 2), /* number of writer domains */
CU_DataPoints(size_t, 1, 3, 3), /* number of writers per domain */
};
CU_Theory((size_t n_rd_dom, size_t n_rd, size_t n_wr_dom, size_t n_wr), ddssec_secure_communication, multiple_readers_writers, .timeout = 60, .disabled = true)
CU_Theory((size_t n_rd_dom, size_t n_rd, size_t n_wr_dom, size_t n_wr), ddssec_secure_communication, multiple_readers_writers, .timeout = 60, .disabled = false)
{
DDS_Security_ProtectionKind metadata_pk[] = { PK_SOA, PK_EOA };
for (size_t metadata = 0; metadata < sizeof (metadata_pk) / sizeof (metadata_pk[0]); metadata++)