diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h b/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h index 7eaaee1..dc63d5a 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_security_omg.h @@ -64,6 +64,7 @@ struct security_entity_match { ddsrt_avl_node_t avlnode; struct guid_pair guids; bool matched; + bool tokens_sent; int64_t crypto_handle; DDS_Security_ParticipantCryptoTokenSeq *tokens; }; @@ -85,6 +86,7 @@ struct proxypp_pp_match { DDS_Security_ParticipantCryptoHandle pp_crypto_handle; DDS_Security_PermissionsHandle permissions_handle; DDS_Security_SharedSecretHandle shared_secret; + bool authenticated; }; struct participant_sec_attributes { @@ -558,6 +560,20 @@ bool q_omg_security_remote_participant_is_initialized(struct proxy_participant * */ bool q_omg_security_register_remote_participant(struct participant *pp, struct proxy_participant *proxypp, int64_t shared_secret); +/** + * @brief Sets the matching participant and proxy participant as authorized. + * + * When the authentication handshake has finished successfully and the + * volatile secure readers and writers are matched then with this function + * the matching local and remote participant are set to authenticated which + * allows the crypto tokens to be exchanged and the corresponding entities + * be matched. + * + * @param[in] pp The participant. + * @param[in] proxypp The proxy participant. + */ +void q_omg_security_set_remote_participant_authenticated(struct participant *pp, struct proxy_participant *proxypp); + /** * @brief Removes a registered proxy participant from administation of the authentication, * access control and crypto plugins. diff --git a/src/core/ddsi/src/ddsi_security_omg.c b/src/core/ddsi/src/ddsi_security_omg.c index 40768d9..70b2b93 100644 --- a/src/core/ddsi/src/ddsi_security_omg.c +++ b/src/core/ddsi/src/ddsi_security_omg.c @@ -378,6 +378,7 @@ static struct proxypp_pp_match * proxypp_pp_match_new(struct participant *pp, DD pm->pp_crypto_handle = pp->sec_attr->crypto_handle; pm->permissions_handle = permissions_hdl; pm->shared_secret = shared_secret; + pm->authenticated = false; return pm; } @@ -1753,6 +1754,37 @@ register_failed: return ret; } +void q_omg_security_set_remote_participant_authenticated(struct participant *pp, struct proxy_participant *proxypp) +{ + struct proxypp_pp_match *pm; + + ddsrt_mutex_lock(&proxypp->sec_attr->lock); + pm = ddsrt_avl_lookup(&proxypp_pp_treedef, &proxypp->sec_attr->participants, &pp->sec_attr->crypto_handle); + if (pm) + pm->authenticated = true; + ddsrt_mutex_unlock(&proxypp->sec_attr->lock); +} + +static bool is_volatile_secure_endpoint(ddsi_entityid_t entityid) +{ + return ((entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER) || (entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_READER)); +} + +static struct proxypp_pp_match * get_pp_proxypp_match_if_authenticated(struct participant *pp, struct proxy_participant *proxypp, ddsi_entityid_t entityid) +{ + struct proxypp_pp_match *pm; + + ddsrt_mutex_lock(&proxypp->sec_attr->lock); + pm = ddsrt_avl_lookup(&proxypp_pp_treedef, &proxypp->sec_attr->participants, &pp->sec_attr->crypto_handle); + if (pm) + { + if (!pm->authenticated && !is_volatile_secure_endpoint(entityid)) + pm = NULL; + } + ddsrt_mutex_unlock(&proxypp->sec_attr->lock); + return pm; +} + void q_omg_security_deregister_remote_participant(struct proxy_participant *proxypp) { struct ddsi_domaingv *gv = proxypp->e.gv; @@ -2028,11 +2060,9 @@ static bool q_omg_security_register_remote_writer_match(struct proxy_writer *pwr struct security_entity_match *match; bool send_tokens = false; - ddsrt_mutex_lock(&proxypp->sec_attr->lock); - pm = ddsrt_avl_lookup(&proxypp_pp_treedef, &proxypp->sec_attr->participants, &pp->sec_attr->crypto_handle); - ddsrt_mutex_unlock(&proxypp->sec_attr->lock); + *crypto_handle = 0; - if (!pm) + if ((pm = get_pp_proxypp_match_if_authenticated(pp, proxypp, pwr->e.guid.entityid)) == NULL) return false; /* TODO: the security_entity_match should be removed after the the received tokens are stored in the plugin. @@ -2380,10 +2410,7 @@ static bool q_omg_security_register_remote_reader_match(struct proxy_reader *prd *crypto_handle = 0; - ddsrt_mutex_lock(&proxypp->sec_attr->lock); - pm = ddsrt_avl_lookup(&proxypp_pp_treedef, &proxypp->sec_attr->participants, &pp->sec_attr->crypto_handle); - ddsrt_mutex_unlock(&proxypp->sec_attr->lock); - if (!pm) + if ((pm = get_pp_proxypp_match_if_authenticated(pp, proxypp, prd->e.guid.entityid)) == NULL) return false; /* TODO: the security_entity_match should be removed after the the received tokens are stored in the plugin. diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 242cb28..23a64a9 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -3620,7 +3620,7 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se assert ((wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL) || (wr->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_MESSAGE_WRITER)); } - wr->handle_as_transient_local = (wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL); + wr->handle_as_transient_local = (wr->xqos->durability.kind == DDS_DURABILITY_TRANSIENT_LOCAL || wr->e.guid.entityid.u == NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_SECURE_WRITER); wr->include_keyhash = wr->e.gv->config.generate_keyhash && ((wr->e.guid.entityid.u & NN_ENTITYID_KIND_MASK) == NN_ENTITYID_KIND_WRITER_WITH_KEY); @@ -4773,6 +4773,7 @@ void handshake_end_cb(struct ddsi_handshake *handshake, struct participant *pp, DDS_CLOG (DDS_LC_DISCOVERY, &gv->logconfig, "handshake (lguid="PGUIDFMT" rguid="PGUIDFMT") processed\n", PGUID (pp->e.guid), PGUID (proxypp->e.guid)); if (q_omg_security_register_remote_participant(pp, proxypp, shared_secret)) { match_volatile_secure_endpoints(pp, proxypp); + q_omg_security_set_remote_participant_authenticated(pp, proxypp); } break; diff --git a/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.c b/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.c index 02ba273..ab75a63 100644 --- a/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.c +++ b/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.c @@ -1998,3 +1998,27 @@ invalid_handle: CRYPTO_OBJECT_RELEASE(obj); return result; } + +master_key_material * +crypto_factory_get_master_key_material_for_test( + const dds_security_crypto_key_factory *factory, + DDS_Security_ParticipantCryptoHandle local_id, + DDS_Security_ParticipantCryptoHandle remote_id) +{ + dds_security_crypto_key_factory_impl *impl = (dds_security_crypto_key_factory_impl *)factory; + remote_participant_crypto *rmt_cr = (remote_participant_crypto *)crypto_object_table_find(impl->crypto_objects, remote_id); + participant_key_material *keymat; + master_key_material *master_keymat = NULL; + + if (rmt_cr) + { + keymat = crypto_remote_participant_lookup_keymat(rmt_cr, local_id); + if (keymat) + { + master_keymat = keymat->local_P2P_key_material; + CRYPTO_OBJECT_RELEASE(keymat); + } + } + + return master_keymat; +} diff --git a/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.h b/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.h index 3e49766..a908e2c 100644 --- a/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.h +++ b/src/security/builtin_plugins/cryptographic/src/crypto_key_factory.h @@ -14,6 +14,7 @@ #include "dds/security/dds_security_api.h" #include "crypto_objects.h" +#include "dds/security/export.h" /** * @brief Allocation function for implementer structure (with internal variables) transparently. @@ -158,4 +159,10 @@ crypto_factory_get_specific_keymat( uint32_t *index, master_key_material **key_mat); +SECURITY_EXPORT master_key_material * +crypto_factory_get_master_key_material_for_test( + const dds_security_crypto_key_factory *factory, + DDS_Security_ParticipantCryptoHandle local_id, + DDS_Security_ParticipantCryptoHandle remote_id); + #endif /* CRYPTO_KEY_FACTORY_H */ diff --git a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c index cc6cd22..ea77f41 100644 --- a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c +++ b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c @@ -28,6 +28,7 @@ #include "CUnit/Test.h" #include "common/src/loader.h" #include "common/src/crypto_helper.h" +#include "crypto_key_factory.h" #include "crypto_objects.h" #include "crypto_utils.h" @@ -571,18 +572,7 @@ static session_key_material * get_local_participant_session(DDS_Security_Partici 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 = crypto_remote_participant_lookup_keymat(participant_crypto_impl, local_particpant_crypto); - if (key_material) - { - master_keymat = key_material->local_P2P_key_material; - CRYPTO_OBJECT_RELEASE(key_material); - } - - return master_keymat; + return crypto_factory_get_master_key_material_for_test(crypto->crypto_key_factory, local_particpant_crypto, participant_crypto); } static void set_protection_kind(DDS_Security_ParticipantCryptoHandle participant_crypto, DDS_Security_ProtectionKind protection_kind)