diff --git a/src/security/core/tests/CMakeLists.txt b/src/security/core/tests/CMakeLists.txt index 5618269..639b84b 100644 --- a/src/security/core/tests/CMakeLists.txt +++ b/src/security/core/tests/CMakeLists.txt @@ -75,7 +75,9 @@ if(ENABLE_SSL) list(APPEND security_core_test_sources "common/security_config_test_utils.c" "common/handshake_test_utils.c" + "common/cert_utils.c" "authentication.c" + "access_control.c" "config.c" "handshake.c" "plugin_loading.c" diff --git a/src/security/core/tests/access_control.c b/src/security/core/tests/access_control.c index 0b25a90..061dfef 100644 --- a/src/security/core/tests/access_control.c +++ b/src/security/core/tests/access_control.c @@ -44,15 +44,15 @@ static const char *config = " " " " " " - " " TEST_IDENTITY_CERTIFICATE "" - " " TEST_IDENTITY_PRIVATE_KEY "" - " " TEST_IDENTITY_CA_CERTIFICATE "" + " data:," TEST_IDENTITY1_CERTIFICATE "" + " data:," TEST_IDENTITY1_PRIVATE_KEY "" + " data:," TEST_IDENTITY_CA1_CERTIFICATE "" " " " " " " - " ${TEST_GOVERNANCE}" - " ${TEST_PERMISSIONS_CA}" - " ${TEST_PERMISSIONS}" + " ${INCL_GOV:+}${TEST_GOVERNANCE}${INCL_GOV:+}" + " ${INCL_PERM_CA:+}${TEST_PERMISSIONS_CA}${INCL_PERM_CA:+}" + " ${INCL_PERM:+}${TEST_PERMISSIONS}${INCL_PERM:+}" " " " " " " @@ -69,9 +69,12 @@ static dds_entity_t g_participant1 = 0; static dds_entity_t g_domain2 = 0; static dds_entity_t g_participant2 = 0; -static void access_control_init(const char * gov, const char * perm, const char * ca, bool exp_pp_fail) +static void access_control_init(bool incl_gov, const char * gov, bool incl_perm, const char * perm, bool incl_ca, const char * ca, bool exp_pp_fail) { struct kvp config_vars[] = { + { "INCL_GOV", incl_gov ? "1" : "", 2 }, + { "INCL_PERM", incl_perm ? "1" : "", 2 }, + { "INCL_PERM_CA", incl_ca ? "1" : "", 2 }, { "TEST_GOVERNANCE", gov, 1 }, { "TEST_PERMISSIONS", perm, 1 }, { "TEST_PERMISSIONS_CA", ca, 1 }, @@ -86,16 +89,8 @@ static void access_control_init(const char * gov, const char * perm, const char g_participant1 = dds_create_participant (DDS_DOMAINID1, NULL, NULL); g_participant2 = dds_create_participant (DDS_DOMAINID2, NULL, NULL); - if (exp_pp_fail) - { - CU_ASSERT_FATAL (g_participant1 <= 0); - CU_ASSERT_FATAL (g_participant2 <= 0); - } - else - { - CU_ASSERT_FATAL (g_participant1 > 0); - CU_ASSERT_FATAL (g_participant2 > 0); - } + CU_ASSERT_EQUAL_FATAL (exp_pp_fail, g_participant1 <= 0); + CU_ASSERT_EQUAL_FATAL (exp_pp_fail, g_participant2 <= 0); } static void access_control_fini(bool delete_pp) @@ -121,16 +116,34 @@ static void access_control_fini(bool delete_pp) #define CA_F PF_F COMMON_ETC_PATH("default_permissions_ca.pem") #define CA_FNE PF_F COMMON_ETC_PATH("default_permissions_ca_non_existing.pem") #define CA_DI PF_D COMMON_ETC_PATH("default_permissions_ca.pem") -#define CA_D TEST_PERMISSIONS_CA_CERTIFICATE +#define CA_D PF_D TEST_PERMISSIONS_CA_CERTIFICATE -CU_TheoryDataPoints(ddssec_access_control, config_parameters) = { - CU_DataPoints(const char *, GOV_F, GOV_FNE, GOV_FNE, GOV_F, GOV_F, "", GOV_F, GOV_F, GOV_DI, GOV_F), - CU_DataPoints(const char *, PERM_F, PERM_FNE, PERM_F, PERM_FNE, PERM_F, PERM_F, "", PERM_F, PERM_F, PERM_F), - CU_DataPoints(const char *, CA_F, CA_FNE, CA_F, CA_F, CA_FNE, CA_F, CA_F, "", CA_F, CA_D), - CU_DataPoints(bool, false, true, true, true, true, true, true, true, true, false) +CU_TheoryDataPoints(ddssec_access_control, config_parameters_file) = { + CU_DataPoints(const char *, + /* */"existing files", + /* | */"non-existing files", + /* | | */"non-existing governance file", + /* | | | */"non-existing permissions file", + /* | | | | */"non-existing permissions ca file", + /* | | | | | */"empty governance", + /* | | | | | | */"empty permissions", + /* | | | | | | | */"empty permissions ca", + /* | | | | | | | | */"all empty", + /* | | | | | | | | | */"invalid governance uri type", + /* | | | | | | | | | | */"permissions ca type data", + /* | | | | | | | | | | | */"no governance element", + /* | | | | | | | | | | | | */"no permissions element", + /* | | | | | | | | | | | | | */"no permissions ca element"), + CU_DataPoints(const char *, GOV_F, GOV_FNE, GOV_FNE, GOV_F, GOV_F, "", GOV_F, GOV_F, "", GOV_DI, GOV_F, "", GOV_F, GOV_F), // Governance config + CU_DataPoints(const char *, PERM_F, PERM_FNE, PERM_F, PERM_FNE, PERM_F, PERM_F, "", PERM_F, "", PERM_F, PERM_F, PERM_F, "", PERM_F), // Permissions config + CU_DataPoints(const char *, CA_F, CA_FNE, CA_F, CA_F, CA_FNE, CA_F, CA_F, "", "", CA_F, CA_D, CA_F, CA_F, ""), // Permissions CA + CU_DataPoints(bool, true, true, true, true, true, true, true, true, true, true, true, false, false, false), // include empty config elements + CU_DataPoints(bool, false, true, true, true, true, true, true, true, false, true, false, true, true, true) // expect failure }; -CU_Theory((const char * gov, const char * perm, const char * ca, bool exp_fail), ddssec_access_control, config_parameters) +CU_Theory((const char * test_descr, const char * gov, const char * perm, const char * ca, bool incl_empty_els, bool exp_fail), + ddssec_access_control, config_parameters_file) { - access_control_init (gov, perm, ca, exp_fail); + printf("running test config_parameters_file: %s\n", test_descr); + access_control_init (incl_empty_els || strlen (gov), gov, incl_empty_els || strlen (perm), perm, incl_empty_els || strlen (ca), ca, exp_fail); access_control_fini (!exp_fail); } diff --git a/src/security/core/tests/authentication.c b/src/security/core/tests/authentication.c index afab49b..a23f203 100644 --- a/src/security/core/tests/authentication.c +++ b/src/security/core/tests/authentication.c @@ -34,6 +34,22 @@ #include "common/handshake_test_utils.h" #include "common/security_config_test_utils.h" #include "common/test_identity.h" +#include "common/cert_utils.h" +#include "common/security_config_test_utils.h" + +#include "SecurityCoreTests.h" + + +#define ID1 TEST_IDENTITY1_CERTIFICATE +#define ID1K TEST_IDENTITY1_PRIVATE_KEY +#define ID2 TEST_IDENTITY2_CERTIFICATE +#define ID2K TEST_IDENTITY2_PRIVATE_KEY +#define ID3 TEST_IDENTITY3_CERTIFICATE +#define ID3K TEST_IDENTITY3_PRIVATE_KEY +#define CA1 TEST_IDENTITY_CA1_CERTIFICATE +#define CA1K TEST_IDENTITY_CA1_PRIVATE_KEY +#define CA2 TEST_IDENTITY_CA2_CERTIFICATE +#define CA2K TEST_IDENTITY_CA2_PRIVATE_KEY static const char *config = "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}" @@ -45,16 +61,16 @@ static const char *config = " " " " " " - " ${TEST_IDENTITY_CERTIFICATE}" - " ${TEST_IDENTITY_PRIVATE_KEY}" - " ${TEST_IDENTITY_CA_CERTIFICATE}" + " data:,${TEST_IDENTITY_CERTIFICATE}" + " data:,${TEST_IDENTITY_PRIVATE_KEY}" + " data:,${TEST_IDENTITY_CA_CERTIFICATE}" " ${TRUSTED_CA_DIR:+}${TRUSTED_CA_DIR}${TRUSTED_CA_DIR:+}" " " " " " " - " file:" COMMON_ETC_PATH("default_governance.p7s") "" + " " " file:" COMMON_ETC_PATH("default_permissions_ca.pem") "" - " file:" COMMON_ETC_PATH("default_permissions.p7s") "" + " " " " " " " " @@ -64,29 +80,59 @@ static const char *config = #define DDS_DOMAINID1 0 #define DDS_DOMAINID2 1 -#define MAX_ADDITIONAL_CONF 255 -static dds_entity_t g_domain1 = 0; -static dds_entity_t g_participant1 = 0; +#define DEF_PERM_CONF "file:" COMMON_ETC_PATH("default_permissions.p7s") -static dds_entity_t g_domain2 = 0; -static dds_entity_t g_participant2 = 0; +static dds_entity_t g_domain1; +static dds_entity_t g_participant1; +static dds_entity_t g_pub; +static dds_entity_t g_pub_tp; +static dds_entity_t g_wr; -static void authentication_init(bool different_ca, const char * trusted_ca_dir, bool exp_pp_fail) +static dds_entity_t g_domain2; +static dds_entity_t g_participant2; +static dds_entity_t g_sub; +static dds_entity_t g_sub_tp; +static dds_entity_t g_rd; + +static uint32_t g_topic_nr = 0; + +static void authentication_init( + const char * id1_cert, const char * id1_key, const char * id1_ca, + const char * id2_cert, const char * id2_key, const char * id2_ca, + const char * trusted_ca_dir, const char * perm_config, + bool exp_pp1_fail, bool exp_pp2_fail) { + if (perm_config == NULL) + perm_config = DEF_PERM_CONF; + + struct kvp governance_vars[] = { + { "DISCOVERY_PROTECTION_KIND", "NONE", 1 }, + { "LIVELINESS_PROTECTION_KIND", "NONE", 1 }, + { "RTPS_PROTECTION_KIND", "NONE", 1 }, + { "METADATA_PROTECTION_KIND", "NONE", 1 }, + { "DATA_PROTECTION_KIND", "NONE", 1 }, + { NULL, NULL, 0 } + }; + char * gov_config_signed = get_governance_config (governance_vars, true); + struct kvp config_vars1[] = { - { "TEST_IDENTITY_CERTIFICATE", TEST_IDENTITY_CERTIFICATE, 1 }, - { "TEST_IDENTITY_PRIVATE_KEY", TEST_IDENTITY_PRIVATE_KEY, 1 }, - { "TEST_IDENTITY_CA_CERTIFICATE", TEST_IDENTITY_CA_CERTIFICATE, 1 }, + { "TEST_IDENTITY_CERTIFICATE", id1_cert, 1 }, + { "TEST_IDENTITY_PRIVATE_KEY", id1_key, 1 }, + { "TEST_IDENTITY_CA_CERTIFICATE", id1_ca, 1 }, { "TRUSTED_CA_DIR", trusted_ca_dir, 3 }, + { "PERM_CONFIG", perm_config, 1 }, + { "GOVERNANCE_CONFIG", gov_config_signed, 1 }, { NULL, NULL, 0 } }; struct kvp config_vars2[] = { - { "TEST_IDENTITY_CERTIFICATE", TEST_IDENTITY2_CERTIFICATE, 1 }, - { "TEST_IDENTITY_PRIVATE_KEY", TEST_IDENTITY2_PRIVATE_KEY, 1 }, - { "TEST_IDENTITY_CA_CERTIFICATE", TEST_IDENTITY_CA2_CERTIFICATE, 1 }, + { "TEST_IDENTITY_CERTIFICATE", id2_cert, 1 }, + { "TEST_IDENTITY_PRIVATE_KEY", id2_key, 1 }, + { "TEST_IDENTITY_CA_CERTIFICATE", id2_ca, 1 }, { "TRUSTED_CA_DIR", trusted_ca_dir, 3 }, + { "PERM_CONFIG", perm_config, 1 }, + { "GOVERNANCE_CONFIG", gov_config_signed, 1 }, { NULL, NULL, 0 } }; @@ -95,57 +141,301 @@ static void authentication_init(bool different_ca, const char * trusted_ca_dir, CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars1), 0); CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars2), 0); g_domain1 = dds_create_domain (DDS_DOMAINID1, conf1); - g_domain2 = dds_create_domain (DDS_DOMAINID2, different_ca ? conf2 : conf1); - dds_free (conf1); - dds_free (conf2); - + g_domain2 = dds_create_domain (DDS_DOMAINID2, conf2); g_participant1 = dds_create_participant (DDS_DOMAINID1, NULL, NULL); g_participant2 = dds_create_participant (DDS_DOMAINID2, NULL, NULL); - if (exp_pp_fail) - { - CU_ASSERT_FATAL (g_participant1 <= 0); - CU_ASSERT_FATAL (g_participant2 <= 0); - } - else - { - CU_ASSERT_FATAL (g_participant1 > 0); - CU_ASSERT_FATAL (g_participant2 > 0); - } + CU_ASSERT_EQUAL_FATAL (exp_pp1_fail, g_participant1 <= 0); + CU_ASSERT_EQUAL_FATAL (exp_pp2_fail, g_participant2 <= 0); + + ddsrt_free (gov_config_signed); + ddsrt_free (conf1); + ddsrt_free (conf2); } -static void authentication_fini(bool delete_pp) +static char *create_topic_name(const char *prefix, uint32_t nr, char *name, size_t size) { - if (delete_pp) + 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 void sync_writer_to_reader() +{ + dds_attach_t triggered; + dds_return_t ret; + dds_entity_t waitset_wr = dds_create_waitset (g_participant1); + CU_ASSERT_FATAL (waitset_wr > 0); + dds_publication_matched_status_t pub_matched; + + /* Sync writer to reader. */ + ret = dds_waitset_attach (waitset_wr, g_wr, g_wr); + CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); + while (true) { - CU_ASSERT_EQUAL_FATAL (dds_delete (g_participant1), DDS_RETCODE_OK); - CU_ASSERT_EQUAL_FATAL (dds_delete (g_participant2), DDS_RETCODE_OK); + ret = dds_waitset_wait (waitset_wr, &triggered, 1, DDS_SECS(5)); + CU_ASSERT_FATAL (ret >= 1); + CU_ASSERT_EQUAL_FATAL (g_wr, (dds_entity_t)(intptr_t) triggered); + ret = dds_get_publication_matched_status(g_wr, &pub_matched); + CU_ASSERT_EQUAL_FATAL (ret, DDS_RETCODE_OK); + if (pub_matched.total_count >= 1) + break; + }; + dds_delete (waitset_wr); +} + +static void reader_wait_for_data() +{ + dds_attach_t triggered; + dds_return_t ret; + dds_entity_t waitset_rd = dds_create_waitset (g_participant2); + CU_ASSERT_FATAL (waitset_rd > 0); + + ret = dds_waitset_attach (waitset_rd, g_rd, g_rd); + 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 (g_rd, (dds_entity_t)(intptr_t)triggered); + dds_delete (waitset_rd); +} + +static void rd_wr_init() +{ + char name[100]; + dds_qos_t * qos = dds_create_qos (); + CU_ASSERT_FATAL (qos != NULL); + dds_qset_history (qos, DDS_HISTORY_KEEP_ALL, -1); + dds_qset_durability (qos, DDS_DURABILITY_TRANSIENT_LOCAL); + dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY); + + create_topic_name("ddssec_authentication_", g_topic_nr++, name, sizeof (name)); + g_pub = dds_create_publisher (g_participant1, NULL, NULL); + CU_ASSERT_FATAL (g_pub > 0); + g_sub = dds_create_subscriber (g_participant2, NULL, NULL); + CU_ASSERT_FATAL (g_sub > 0); + g_pub_tp = dds_create_topic (g_participant1, &SecurityCoreTests_Type1_desc, name, NULL, NULL); + CU_ASSERT_FATAL (g_pub_tp > 0); + g_sub_tp = dds_create_topic (g_participant2, &SecurityCoreTests_Type1_desc, name, NULL, NULL); + CU_ASSERT_FATAL (g_sub_tp > 0); + g_wr = dds_create_writer (g_pub, g_pub_tp, qos, NULL); + CU_ASSERT_FATAL (g_wr > 0); + dds_set_status_mask (g_wr, DDS_PUBLICATION_MATCHED_STATUS); + g_rd = dds_create_reader (g_sub, g_sub_tp, qos, NULL); + CU_ASSERT_FATAL (g_rd > 0); + dds_set_status_mask (g_rd, DDS_DATA_AVAILABLE_STATUS); + sync_writer_to_reader(); + dds_delete_qos (qos); +} + +static void write_read(dds_duration_t dur, bool exp_write_fail, bool exp_read_fail) +{ + SecurityCoreTests_Type1 sample = { 1, 1 }; + SecurityCoreTests_Type1 rd_sample; + void * samples[] = { &rd_sample }; + dds_sample_info_t info[1]; + dds_return_t ret; + dds_time_t tend = dds_time () + dur; + bool write_fail = false, read_fail = false; + + rd_wr_init (); + do + { + ret = dds_write (g_wr, &sample); + if (ret != DDS_RETCODE_OK) + write_fail = true; + while (true) + { + if ((ret = dds_take (g_rd, samples, info, 1, 1)) == 0) + { + reader_wait_for_data (); + continue; + } + else if (ret < 0) + { + read_fail = true; + break; + } + CU_ASSERT_EQUAL_FATAL (ret, 1); + break; + } + dds_sleepfor (DDS_MSECS (1)); } + while (dds_time() < tend && !write_fail && !read_fail); + CU_ASSERT_EQUAL_FATAL (write_fail, exp_write_fail); + CU_ASSERT_EQUAL_FATAL (read_fail, exp_read_fail); +} + +static void authentication_fini(bool delete_pp1, bool delete_pp2) +{ + if (delete_pp1) + CU_ASSERT_EQUAL_FATAL (dds_delete (g_participant1), DDS_RETCODE_OK); + if (delete_pp2) + CU_ASSERT_EQUAL_FATAL (dds_delete (g_participant2), DDS_RETCODE_OK); CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain1), DDS_RETCODE_OK); CU_ASSERT_EQUAL_FATAL (dds_delete (g_domain2), DDS_RETCODE_OK); } -CU_Test(ddssec_authentication, different_ca) +#define FM_CA "error: unable to get local issuer certificate" +#define FM_INVK "Failed to finalize verify context" +CU_TheoryDataPoints(ddssec_authentication, id_ca_certs) = { + CU_DataPoints(const char *, + /* */"valid ID1-ID1", + /* | */"non-trusted remote CA ID1(CA1)-ID2(CA2)", + /* | | */"valid ID1-ID3", + /* | | | */"invalid ca ID1(CA1)-ID1(CA2)", + /* | | | | */"invalid remote key ID3(K1)"), + CU_DataPoints(const char *, ID1, ID2, ID3, ID1, ID3), /* Identity for domain 2 */ + CU_DataPoints(const char *, ID1K, ID2K, ID3K, ID1K, ID1K), /* Private key for domain 2 identity */ + CU_DataPoints(const char *, CA1, CA2, CA1, CA2, CA1), /* CA for domain 2 identity */ + CU_DataPoints(bool, false, false, false, false, false), /* expect create participant1 fails */ + CU_DataPoints(bool, false, false, false, true, false), /* expect create participant2 fails */ + CU_DataPoints(bool, false, false, false, true, false), /* expect validate local failed for domain 2 */ + CU_DataPoints(const char *, NULL, NULL, NULL, FM_CA, NULL), /* expected error message for validate local failed */ + CU_DataPoints(bool, false, true, false, false, true), /* expect handshake request failed */ + CU_DataPoints(const char *, NULL, NULL, NULL, NULL, FM_INVK), /* expected error message for handshake request failed */ + CU_DataPoints(bool, false, true, false, true, true), /* expect handshake reply failed */ + CU_DataPoints(const char *, NULL, FM_CA, NULL, FM_CA, NULL) /* expected error message for handshake reply failed */ +}; +#undef FM_CA +#undef FM_INVK + +static void validate_hs(struct Handshake *hs, bool exp_fail_hs_req, const char * fail_hs_req_msg, bool exp_fail_hs_reply, const char * fail_hs_reply_msg) { - authentication_init (true, NULL, false); - validate_handshake (DDS_DOMAINID1, true, NULL, true, "error: unable to get local issuer certificate"); - validate_handshake (DDS_DOMAINID2, true, NULL, true, "error: unable to get local issuer certificate"); - authentication_fini (true); + DDS_Security_ValidationResult_t exp_result = hs->node_type == HSN_REQUESTER ? DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE : DDS_SECURITY_VALIDATION_OK; + if (hs->node_type == HSN_REQUESTER) + { + CU_ASSERT_EQUAL_FATAL (hs->finalResult, exp_fail_hs_req ? DDS_SECURITY_VALIDATION_FAILED : exp_result); + if (exp_fail_hs_req) + { + if (fail_hs_req_msg == NULL) + { + CU_ASSERT_EQUAL_FATAL (hs->err_msg, NULL); + } + else + { + CU_ASSERT_FATAL (hs->err_msg != NULL); + CU_ASSERT_FATAL (strstr(hs->err_msg, fail_hs_req_msg) != NULL); + } + } + } + else if (hs->node_type == HSN_REPLIER) + { + CU_ASSERT_EQUAL_FATAL (hs->finalResult, exp_fail_hs_reply ? DDS_SECURITY_VALIDATION_FAILED : exp_result); + if (exp_fail_hs_reply) + { + if (fail_hs_reply_msg == NULL) + { + CU_ASSERT_EQUAL_FATAL (hs->err_msg, NULL); + } + else + { + CU_ASSERT_FATAL (hs->err_msg != NULL); + CU_ASSERT_FATAL (strstr(hs->err_msg, fail_hs_reply_msg) != NULL); + } + } + } } +CU_Theory((const char * test_descr, const char * id2, const char *key2, const char *ca2, + bool exp_fail_pp1, bool exp_fail_pp2, + bool exp_fail_local, const char * fail_local_msg, + bool exp_fail_hs_req, const char * fail_hs_req_msg, + bool exp_fail_hs_reply, const char * fail_hs_reply_msg), + ddssec_authentication, id_ca_certs) +{ + struct Handshake *hs_list; + int nhs; + printf("running test id_ca_certs: %s\n", test_descr); + authentication_init (ID1, ID1K, CA1, id2, key2, ca2, NULL, NULL, exp_fail_pp1, exp_fail_pp2); + + // Domain 1 + validate_handshake (DDS_DOMAINID1, false, NULL, &hs_list, &nhs); + for (int n = 0; n < nhs; n++) + validate_hs (&hs_list[n], exp_fail_hs_req, fail_hs_req_msg, exp_fail_hs_reply, fail_hs_reply_msg); + handshake_list_fini (hs_list, nhs); + + // Domain 2 + validate_handshake (DDS_DOMAINID2, exp_fail_local, fail_local_msg, &hs_list, &nhs); + for (int n = 0; n < nhs; n++) + validate_hs (&hs_list[n], exp_fail_hs_req, fail_hs_req_msg, exp_fail_hs_reply, fail_hs_reply_msg); + handshake_list_fini (hs_list, nhs); + + authentication_fini (!exp_fail_pp1, !exp_fail_pp2); +} CU_TheoryDataPoints(ddssec_authentication, trusted_ca_dir) = { CU_DataPoints(const char *, "", ".", "/nonexisting", NULL), CU_DataPoints(bool, false, false, true, false) }; - CU_Theory((const char * ca_dir, bool exp_fail), ddssec_authentication, trusted_ca_dir) { printf("Testing custom CA dir: %s\n", ca_dir); - authentication_init (false, ca_dir, exp_fail); + authentication_init (ID1, ID1K, CA1, ID1, ID1K, CA1, ca_dir, NULL, exp_fail, exp_fail); if (!exp_fail) { - validate_handshake (DDS_DOMAINID1, false, NULL, false, NULL); - validate_handshake (DDS_DOMAINID2, false, NULL, false, NULL); + validate_handshake_nofail (DDS_DOMAINID1); + validate_handshake_nofail (DDS_DOMAINID2); } - authentication_fini (!exp_fail); + authentication_fini (!exp_fail, !exp_fail); } + +#define M(n) ((n)*60) +#define H(n) (M(n)*60) +#define D(n) (H(n)*24) +CU_TheoryDataPoints(ddssec_authentication, expired_cert) = { + CU_DataPoints(const char *, + /* */"all valid 1d", + /* | */"ca expired", + /* | | */"id1 expired", + /* | | | */"id2 expired", + /* | | | | */"ca and id1 1min valid", + /* | | | | | */"id1 and id2 1s valid, delay 1100ms", + /* | | | | | | */"id1 valid after 1s, delay 1100ms", + /* | | | | | | | *//*"ca and id1 expire during session"*/), + CU_DataPoints(int32_t, 0, -M(1), 0, 0, 0, 0, 0, /*0*/ ), /* CA1 not before */ + CU_DataPoints(int32_t, D(1), 0, D(1), D(1), M(1), D(1), D(1), /*2*/ ), /* CA1 not after */ + CU_DataPoints(int32_t, 0, 0, -D(1), 0, 0, 0, 1, /*0*/ ), /* ID1 not before */ + CU_DataPoints(int32_t, D(1), D(1), 0, D(1), M(1), 1, D(1), /*2*/ ), /* ID1 not after */ + CU_DataPoints(bool, false, true, true, false, false, true, false, /*false*/ ), /* expect validate local ID1 fail */ + CU_DataPoints(int32_t, 0, 0, 0, -D(1), 0, 0, 0, /*0*/ ), /* ID2 not before */ + CU_DataPoints(int32_t, D(1), D(1), D(1), 0, D(1), 1, D(1), /*D(1)*/ ), /* ID2 not after */ + CU_DataPoints(bool, false, true, false, true, false, true, false, /*false*/ ), /* expect validate local ID2 fail */ + CU_DataPoints(uint32_t, 0, 0, 0, 0, 0, 1100, 1100, /*0*/ ), /* delay (ms) after generating certificate */ + CU_DataPoints(uint32_t, 1, 0, 0, 0, 1, 0, 1, /*3500*/ ), /* write/read data during x ms */ + CU_DataPoints(bool, false, false, false, false, false, false, false, /*true*/ ), /* expect read data failure */ +}; +CU_Theory( + (const char * test_descr, int32_t ca_not_before, int32_t ca_not_after, + int32_t id1_not_before, int32_t id1_not_after, bool id1_local_fail, + int32_t id2_not_before, int32_t id2_not_after, bool id2_local_fail, + uint32_t delay, uint32_t write_read_dur, bool exp_read_fail), + ddssec_authentication, expired_cert) +{ + char *ca, *id1, *id2, *id1_subj, *id2_subj; + printf("running test expired_cert: %s\n", test_descr); + ca = generate_ca ("ca1", CA1K, ca_not_before, ca_not_after); + id1 = generate_identity (ca, CA1K, "id1", ID1K, id1_not_before, id1_not_after, &id1_subj); + id2 = generate_identity (ca, CA1K, "id2", ID1K, id2_not_before, id2_not_after, &id2_subj); + dds_sleepfor (DDS_MSECS (delay)); + + char * grants[] = { get_permissions_grant ("id1", id1_subj), get_permissions_grant ("id2", id2_subj) }; + char * perm_config = get_permissions_config (grants, 2, true); + authentication_init (id1, ID1K, ca, id2, ID1K, ca, NULL, perm_config, id1_local_fail, id2_local_fail); + validate_handshake (DDS_DOMAINID1, id1_local_fail, NULL, NULL, NULL); + validate_handshake (DDS_DOMAINID2, id2_local_fail, NULL, NULL, NULL); + if (write_read_dur > 0) + write_read (DDS_MSECS (write_read_dur), false, exp_read_fail); + authentication_fini (!id1_local_fail, !id2_local_fail); + ddsrt_free (grants[0]); + ddsrt_free (grants[1]); + ddsrt_free (perm_config); + ddsrt_free (ca); + ddsrt_free (id1_subj); + ddsrt_free (id2_subj); + ddsrt_free (id1); + ddsrt_free (id2); +} +#undef D +#undef H +#undef M + diff --git a/src/security/core/tests/common/cert_utils.c b/src/security/core/tests/common/cert_utils.c new file mode 100644 index 0000000..f2e7386 --- /dev/null +++ b/src/security/core/tests/common/cert_utils.c @@ -0,0 +1,142 @@ +/* + * Copyright(c) 2006 to 2020 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/string.h" +#include "CUnit/Test.h" +#include "cert_utils.h" + +#define MAX_EMAIL 255 +#define EMAIL_HOST "cycloneddssecurity.adlinktech.com" + +static X509 * get_x509(int not_valid_before, int not_valid_after, const char * cn, const char * email) +{ + X509 * cert = X509_new (); + CU_ASSERT_FATAL (cert != NULL); + ASN1_INTEGER_set (X509_get_serialNumber (cert), 1); + X509_gmtime_adj (X509_get_notBefore (cert), not_valid_before); + X509_gmtime_adj (X509_get_notAfter (cert), not_valid_after); + + X509_NAME * name = X509_get_subject_name (cert); + X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *) "NL", -1, -1, 0); + X509_NAME_add_entry_by_txt (name, "O", MBSTRING_ASC, (unsigned char *) "Example Organization", -1, -1, 0); + X509_NAME_add_entry_by_txt (name, "CN", MBSTRING_ASC, (unsigned char *) cn, -1, -1, 0); + X509_NAME_add_entry_by_txt (name, "emailAddress", MBSTRING_ASC, (unsigned char *) email, -1, -1, 0); + return cert; +} + +static char * get_x509_data(X509 * cert) +{ + // Create BIO for writing output + BIO *output_bio = BIO_new (BIO_s_mem ()); + if (!PEM_write_bio_X509 (output_bio, cert)) { + printf ("Error writing certificate\n"); + CU_ASSERT_FATAL (false); + } + + // Get string + char *output_tmp = NULL; + size_t output_sz = (size_t) BIO_get_mem_data (output_bio, &output_tmp); + char * output = ddsrt_malloc (output_sz + 1); + memcpy (output, output_tmp, output_sz); + output[output_sz] = 0; + BIO_free (output_bio); + + return output; +} + +static EVP_PKEY * get_priv_key(const char * priv_key_str) +{ + BIO *pkey_bio = BIO_new_mem_buf (priv_key_str, -1); + EVP_PKEY *priv_key = PEM_read_bio_PrivateKey (pkey_bio, NULL, NULL, 0); + CU_ASSERT_FATAL (priv_key != NULL); + BIO_free (pkey_bio); + return priv_key; +} + +static X509 * get_cert(const char * cert_str) +{ + BIO *cert_bio = BIO_new_mem_buf (cert_str, -1); + X509 *cert = PEM_read_bio_X509 (cert_bio, NULL, NULL, 0); + CU_ASSERT_FATAL (cert != NULL); + BIO_free (cert_bio); + return cert; +} + +char * generate_ca(const char *ca_name, const char * ca_priv_key_str, int not_valid_before, int not_valid_after) +{ + EVP_PKEY *ca_priv_key = get_priv_key (ca_priv_key_str); + + char * email = malloc (MAX_EMAIL); + snprintf(email, MAX_EMAIL, "%s@%s" , ca_name, EMAIL_HOST); + X509 * ca_cert = get_x509 (not_valid_before, not_valid_after, ca_name, email); + ddsrt_free (email); + + X509_set_pubkey (ca_cert, ca_priv_key); + X509_set_issuer_name (ca_cert, X509_get_subject_name (ca_cert)); /* self-signed */ + X509_sign (ca_cert, ca_priv_key, EVP_sha1 ()); + char * output = get_x509_data (ca_cert); + + EVP_PKEY_free (ca_priv_key); + X509_free (ca_cert); + + return output; +} + +char * generate_identity(const char * ca_cert_str, const char * ca_priv_key_str, const char * name, const char * priv_key_str, int not_valid_before, int not_valid_after, char ** subject) +{ + X509 *ca_cert = get_cert (ca_cert_str); + EVP_PKEY *ca_key_pkey = get_priv_key (ca_priv_key_str); + EVP_PKEY *id_pkey = get_priv_key (priv_key_str); + EVP_PKEY *ca_cert_pkey = X509_get_pubkey (ca_cert); + X509_REQ *csr = X509_REQ_new (); + X509_REQ_set_pubkey (csr, id_pkey); + X509_REQ_sign (csr, id_pkey, EVP_sha256 ()); + + char * email = malloc (MAX_EMAIL); + snprintf(email, MAX_EMAIL, "%s@%s" , name, EMAIL_HOST); + X509 * cert = get_x509 (not_valid_before, not_valid_after, name, email); + ddsrt_free (email); + + EVP_PKEY *csr_pkey = X509_REQ_get_pubkey (csr); + X509_set_pubkey (cert, csr_pkey); + X509_set_issuer_name (cert, X509_get_subject_name (ca_cert)); + X509_sign (cert, ca_key_pkey, EVP_sha256 ()); + char * output = get_x509_data (cert); + + if (subject) + { + X509_NAME *subj_name = X509_get_subject_name (cert); + char * subj_openssl = X509_NAME_oneline (subj_name, NULL, 0); + *subject = ddsrt_strdup (subj_openssl); + OPENSSL_free (subj_openssl); + } + + X509_REQ_free (csr); + EVP_PKEY_free (id_pkey); + EVP_PKEY_free (ca_cert_pkey); + EVP_PKEY_free (ca_key_pkey); + EVP_PKEY_free (csr_pkey); + X509_free (cert); + X509_free (ca_cert); + + return output; +} diff --git a/src/security/core/tests/common/cert_utils.h b/src/security/core/tests/common/cert_utils.h new file mode 100644 index 0000000..f6f9e92 --- /dev/null +++ b/src/security/core/tests/common/cert_utils.h @@ -0,0 +1,20 @@ +/* + * Copyright(c) 2006 to 2020 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#ifndef SECURITY_CORE_TEST_CERT_UTILS_H_ +#define SECURITY_CORE_TEST_CERT_UTILS_H_ + +#include + +char * generate_ca(const char *ca_name, const char * ca_priv_key_str, int not_valid_before, int not_valid_after); +char * generate_identity(const char * ca_cert_str, const char * ca_priv_key_str, const char * name, const char * priv_key_str, int not_valid_before, int not_valid_after, char ** subject); + +#endif /* SECURITY_CORE_TEST_CERT_UTILS_H_ */ diff --git a/src/security/core/tests/common/cryptography_wrapper.c b/src/security/core/tests/common/cryptography_wrapper.c index fcb3ed9..7af5c1b 100644 --- a/src/security/core/tests/common/cryptography_wrapper.c +++ b/src/security/core/tests/common/cryptography_wrapper.c @@ -56,9 +56,16 @@ struct dds_security_cryptography_impl { struct dds_security_crypto_key_factory_impl factory_wrap; struct dds_security_crypto_key_exchange_impl exchange_wrap; enum crypto_plugin_mode mode; + bool protection_kinds_set; + bool disc_protection_kinds_set; DDS_Security_ProtectionKind rtps_protection_kind; DDS_Security_ProtectionKind metadata_protection_kind; DDS_Security_BasicProtectionKind payload_protection_kind; + DDS_Security_ProtectionKind disc_protection_kind; + DDS_Security_ProtectionKind liveliness_protection_kind; + const char * pp_secret; + const char * groupdata_secret; + const char * ep_secret; const char * encrypted_secret; }; @@ -74,6 +81,7 @@ void set_protection_kinds( impl->rtps_protection_kind = rtps_protection_kind; impl->metadata_protection_kind = metadata_protection_kind; impl->payload_protection_kind = payload_protection_kind; + impl->protection_kinds_set = true; } void set_encrypted_secret(struct dds_security_cryptography_impl * impl, const char * secret) @@ -82,6 +90,25 @@ void set_encrypted_secret(struct dds_security_cryptography_impl * impl, const ch impl->encrypted_secret = secret; } +void set_disc_protection_kinds( + struct dds_security_cryptography_impl * impl, + DDS_Security_ProtectionKind disc_protection_kind, + DDS_Security_ProtectionKind liveliness_protection_kind) +{ + assert(impl); + impl->disc_protection_kind = disc_protection_kind; + impl->liveliness_protection_kind = liveliness_protection_kind; + impl->disc_protection_kinds_set = true; +} + +void set_entity_data_secret(struct dds_security_cryptography_impl * impl, const char * pp_secret, const char * groupdata_secret, const char * ep_secret) +{ + assert(impl); + impl->pp_secret = pp_secret; + impl->groupdata_secret = groupdata_secret; + impl->ep_secret = ep_secret; +} + 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) @@ -434,9 +461,11 @@ static DDS_Security_boolean encode_serialized_payload( if (!impl->instance->encode_serialized_payload (impl->instance, encoded_buffer, extra_inline_qos, plain_buffer, check_handle (sending_datawriter_crypto), ex)) return false; - if (impl->parent->encrypted_secret && (impl->parent->payload_protection_kind == DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT - || expect_encrypted_buffer (impl->parent->metadata_protection_kind) - || expect_encrypted_buffer (impl->parent->rtps_protection_kind))) + if (impl->parent->protection_kinds_set + && impl->parent->encrypted_secret + && (impl->parent->payload_protection_kind == DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT + || expect_encrypted_buffer (impl->parent->metadata_protection_kind) + || expect_encrypted_buffer (impl->parent->rtps_protection_kind))) { if (find_buffer_match (encoded_buffer->_buffer, encoded_buffer->_length, (const unsigned char *) impl->parent->encrypted_secret, strlen (impl->parent->encrypted_secret)) != NULL) { @@ -445,7 +474,7 @@ static DDS_Security_boolean encode_serialized_payload( return false; } } - return check_buffers (encoded_buffer, plain_buffer, impl->parent->payload_protection_kind == DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT, ex); + return !impl->parent->protection_kinds_set || check_buffers (encoded_buffer, plain_buffer, impl->parent->payload_protection_kind == DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT, ex); } default: return true; @@ -458,16 +487,15 @@ static DDS_Security_boolean check_buffer_submsg( const DDS_Security_OctetSeq *plain_rtps_submessage, DDS_Security_SecurityException *ex) { - bool exp_enc = expect_encrypted_buffer (impl->parent->metadata_protection_kind) || expect_encrypted_buffer (impl->parent->rtps_protection_kind); - if (exp_enc - && impl->parent->encrypted_secret - && find_buffer_match (encoded_rtps_submessage->_buffer, encoded_rtps_submessage->_length, (const unsigned char *) impl->parent->encrypted_secret, strlen (impl->parent->encrypted_secret)) != NULL) + bool exp_enc = impl->parent->protection_kinds_set && (expect_encrypted_buffer (impl->parent->metadata_protection_kind) || expect_encrypted_buffer (impl->parent->rtps_protection_kind)); + if (exp_enc && impl->parent->encrypted_secret && find_buffer_match (encoded_rtps_submessage->_buffer, encoded_rtps_submessage->_length, (const unsigned char *) impl->parent->encrypted_secret, strlen (impl->parent->encrypted_secret)) != NULL) { ex->code = 1; ex->message = ddsrt_strdup ("Expect encryption, but found secret in submessage after encoding"); return false; } - return expect_encrypted_buffer (impl->parent->metadata_protection_kind) ? check_buffers (encoded_rtps_submessage, plain_rtps_submessage, true, ex) : true; + + return impl->parent->protection_kinds_set && expect_encrypted_buffer (impl->parent->metadata_protection_kind) ? check_buffers (encoded_rtps_submessage, plain_rtps_submessage, true, ex) : true; } static DDS_Security_boolean encode_datawriter_submessage( @@ -486,7 +514,33 @@ static DDS_Security_boolean encode_datawriter_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)) return false; - return check_buffer_submsg(impl, encoded_rtps_submessage, plain_rtps_submessage, ex); + if (!check_buffer_submsg(impl, encoded_rtps_submessage, plain_rtps_submessage, ex)) + return false; + + if (impl->parent->disc_protection_kinds_set && expect_encrypted_buffer (impl->parent->disc_protection_kind)) + { + if (impl->parent->pp_secret && find_buffer_match (plain_rtps_submessage->_buffer, plain_rtps_submessage->_length, (const unsigned char *) impl->parent->pp_secret, strlen (impl->parent->pp_secret)) != NULL) + { + ex->code = 1; + ex->message = ddsrt_strdup ("Expect discovery encryption, but found participant userdata secret in submessage after encoding"); + return false; + } + if (impl->parent->groupdata_secret && find_buffer_match (plain_rtps_submessage->_buffer, plain_rtps_submessage->_length, (const unsigned char *) impl->parent->groupdata_secret, strlen (impl->parent->groupdata_secret)) != NULL) + { + ex->code = 1; + ex->message = ddsrt_strdup ("Expect discovery encryption, but found publisher/subscriber groupdata secret in submessage after encoding"); + return false; + } + if (impl->parent->ep_secret && find_buffer_match (plain_rtps_submessage->_buffer, plain_rtps_submessage->_length, (const unsigned char *) impl->parent->ep_secret, strlen (impl->parent->ep_secret)) != NULL) + { + ex->code = 1; + ex->message = ddsrt_strdup ("Expect discovery encryption, but found reader/writer userdata secret in submessage after encoding"); + return false; + } + } + return true; + + default: return true; } @@ -529,7 +583,8 @@ static DDS_Security_boolean encode_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)) return false; - if (impl->parent->encrypted_secret + if (impl->parent->protection_kinds_set + && impl->parent->encrypted_secret && expect_encrypted_buffer (impl->parent->rtps_protection_kind) && find_buffer_match (encoded_rtps_message->_buffer, encoded_rtps_message->_length, (const unsigned char *) impl->parent->encrypted_secret, strlen (impl->parent->encrypted_secret)) != NULL) { @@ -537,7 +592,7 @@ static DDS_Security_boolean encode_rtps_message( ex->message = ddsrt_strdup ("Expect encryption, but found secret in RTPS message after encoding"); return false; } - return expect_encrypted_buffer (impl->parent->rtps_protection_kind) ? + return impl->parent->protection_kinds_set && expect_encrypted_buffer (impl->parent->rtps_protection_kind) ? check_buffers (encoded_rtps_message, plain_rtps_message, true, ex) : true; default: return true; diff --git a/src/security/core/tests/common/cryptography_wrapper.h b/src/security/core/tests/common/cryptography_wrapper.h index 42ed1ef..44e0501 100644 --- a/src/security/core/tests/common/cryptography_wrapper.h +++ b/src/security/core/tests/common/cryptography_wrapper.h @@ -26,6 +26,13 @@ SECURITY_EXPORT void set_protection_kinds( SECURITY_EXPORT void set_encrypted_secret(struct dds_security_cryptography_impl * impl, const char * secret); +SECURITY_EXPORT void set_disc_protection_kinds( + struct dds_security_cryptography_impl * impl, + DDS_Security_ProtectionKind disc_protection_kind, + DDS_Security_ProtectionKind liveliness_protection_kind); + +SECURITY_EXPORT void set_entity_data_secret(struct dds_security_cryptography_impl * impl, const char * pp_secret, const char * groupdata_secret, const char * ep_secret); + /* Init in all-ok mode: all functions return success without calling the actual plugin */ SECURITY_EXPORT int32_t init_test_cryptography_all_ok(const char *argument, void **context); SECURITY_EXPORT int32_t finalize_test_cryptography_all_ok(void *context); diff --git a/src/security/core/tests/common/handshake_test_utils.c b/src/security/core/tests/common/handshake_test_utils.c index 6d2e494..6385de2 100644 --- a/src/security/core/tests/common/handshake_test_utils.c +++ b/src/security/core/tests/common/handshake_test_utils.c @@ -31,6 +31,33 @@ int numRemote = 0; struct Handshake handshakeList[MAX_HANDSHAKES]; int numHandshake = 0; +static char * get_validation_result_str(DDS_Security_ValidationResult_t result) +{ + switch (result) + { + case DDS_SECURITY_VALIDATION_OK: return "OK"; + case DDS_SECURITY_VALIDATION_PENDING_RETRY: return "PENDING_RETRY"; + case DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST: return "PENDING_HANDSHAKE_REQUEST"; + case DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE: return "PENDING_HANDSHAKE_MESSAGE"; + case DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE: return "OK_FINAL_MESSAGE"; + case DDS_SECURITY_VALIDATION_FAILED: return "FAILED"; + } + abort (); + return ""; +} + +static char * get_node_type_str(enum hs_node_type node_type) +{ + switch (node_type) + { + case HSN_UNDEFINED: return "UNDEFINED"; + case HSN_REQUESTER: return "REQUESTER"; + case HSN_REPLIER: return "REPLIER"; + } + abort (); + return ""; +} + static void add_local_identity(DDS_Security_IdentityHandle handle, DDS_Security_GUID_t *guid) { printf("add local identity %"PRId64"\n", handle); @@ -77,16 +104,18 @@ static void clear_stores(void) numHandshake = 0; } -static void add_handshake(DDS_Security_HandshakeHandle handle, int isRequest, DDS_Security_IdentityHandle lHandle, DDS_Security_IdentityHandle rHandle, DDS_Security_ValidationResult_t result) +static struct Handshake *add_handshake(enum hs_node_type node_type, DDS_Security_IdentityHandle lHandle, DDS_Security_IdentityHandle rHandle) { - printf("add handshake %"PRId64"\n", handle); - handshakeList[numHandshake].handle = handle; - handshakeList[numHandshake].isRequest = isRequest; - handshakeList[numHandshake].handshakeResult = result; + printf("add handshake %"PRId64"-%"PRId64"\n", lHandle, rHandle); + handshakeList[numHandshake].handle = -1; + handshakeList[numHandshake].node_type = node_type; + handshakeList[numHandshake].handshakeResult = DDS_SECURITY_VALIDATION_FAILED; handshakeList[numHandshake].lidx = find_local_identity(lHandle); handshakeList[numHandshake].ridx = find_remote_identity(rHandle); handshakeList[numHandshake].finalResult = DDS_SECURITY_VALIDATION_FAILED; + handshakeList[numHandshake].err_msg = NULL; numHandshake++; + return &handshakeList[numHandshake - 1]; } static int find_handshake(DDS_Security_HandshakeHandle handle) @@ -99,134 +128,144 @@ static int find_handshake(DDS_Security_HandshakeHandle handle) return -1; } -static char * get_validation_result_str(DDS_Security_ValidationResult_t result) -{ - switch (result) - { - case DDS_SECURITY_VALIDATION_OK: - return "ok"; - case DDS_SECURITY_VALIDATION_PENDING_RETRY: - return "pending retry"; - case DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST: - return "handshake request"; - case DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE: - return "handshake message"; - case DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE: - return "ok final"; - default: - case DDS_SECURITY_VALIDATION_FAILED: - return "failed"; - } -} - -static bool handle_process_message(dds_domainid_t domain_id, DDS_Security_IdentityHandle handshake) +static void handle_process_message(dds_domainid_t domain_id, DDS_Security_IdentityHandle handshake) { struct message *msg; - bool result = false; if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_PROCESS_HANDSHAKE, 0, 0, handshake, TIMEOUT))) { int idx; if ((idx = find_handshake(msg->hsHandle)) >= 0) { - printf("set handshake %"PRId64" final result to '%s'\n", msg->hsHandle, get_validation_result_str(msg->result)); + printf("set handshake %"PRId64" final result to '%s' (errmsg: %s)\n", msg->hsHandle, get_validation_result_str(msg->result), msg->err_msg); handshakeList[idx].finalResult = msg->result; - result = true; + handshakeList[idx].err_msg = ddsrt_strdup (msg->err_msg); } test_authentication_plugin_release_msg(msg); } - return result; } -static bool handle_begin_handshake_request(dds_domainid_t domain_id, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid, char ** err_msg) +static void handle_begin_handshake_request(dds_domainid_t domain_id, struct Handshake *hs, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid) { struct message *msg; - bool result = false; printf("handle begin handshake request %"PRId64"<->%"PRId64"\n", lid, rid); if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REQUEST, lid, rid, 0, TIMEOUT))) { - add_handshake(msg->hsHandle, 1, msg->lidHandle, msg->ridHandle, msg->result); + hs->handle = msg->hsHandle; + hs->handshakeResult = msg->result; if (msg->result != DDS_SECURITY_VALIDATION_FAILED) - result = handle_process_message(domain_id, msg->hsHandle); - else if (err_msg) - *err_msg = ddsrt_strdup (msg->err_msg); + handle_process_message(domain_id, msg->hsHandle); + else + hs->err_msg = ddsrt_strdup (msg->err_msg); test_authentication_plugin_release_msg(msg); } - return result; } -static bool handle_begin_handshake_reply(dds_domainid_t domain_id, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid, char ** err_msg) +static void handle_begin_handshake_reply(dds_domainid_t domain_id, struct Handshake *hs, DDS_Security_IdentityHandle lid, DDS_Security_IdentityHandle rid) { struct message *msg; - bool result = false; printf("handle begin handshake reply %"PRId64"<->%"PRId64"\n", lid, rid); if ((msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_BEGIN_HANDSHAKE_REPLY, lid, rid, 0, TIMEOUT))) { - add_handshake(msg->hsHandle, 0, msg->lidHandle, msg->ridHandle, msg->result); + hs->handle = msg->hsHandle; + hs->handshakeResult = msg->result; if (msg->result != DDS_SECURITY_VALIDATION_FAILED) - result = handle_process_message(domain_id, msg->hsHandle); - else if (err_msg) - *err_msg = ddsrt_strdup (msg->err_msg); + handle_process_message(domain_id, msg->hsHandle); + else + hs->err_msg = ddsrt_strdup (msg->err_msg); test_authentication_plugin_release_msg(msg); } - return result; } -static bool handle_validate_remote_identity(dds_domainid_t domain_id, DDS_Security_IdentityHandle lid, int count, bool * is_hs_requester, char ** err_msg_req, char ** err_msg_reply) +static void handle_validate_remote_identity(dds_domainid_t domain_id, DDS_Security_IdentityHandle lid, int count) { - bool result = true; struct message *msg; - assert(is_hs_requester); - while (count-- > 0 && result && (msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_VALIDATE_REMOTE_IDENTITY, lid, 0, 0, TIMEOUT))) + while (count-- > 0 && (msg = test_authentication_plugin_take_msg(domain_id, MESSAGE_KIND_VALIDATE_REMOTE_IDENTITY, lid, 0, 0, TIMEOUT))) { + struct Handshake *hs; add_remote_identity(msg->ridHandle, &msg->rguid); + hs = add_handshake(HSN_UNDEFINED, lid, msg->ridHandle); if (msg->result == DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST) { - result = handle_begin_handshake_request(domain_id, lid, msg->ridHandle, err_msg_req); - *is_hs_requester = true; + hs->node_type = HSN_REQUESTER; + handle_begin_handshake_request(domain_id, hs, lid, msg->ridHandle); } else if (msg->result == DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE) { - result = handle_begin_handshake_reply(domain_id, lid, msg->ridHandle, err_msg_reply); - *is_hs_requester = false; + hs->node_type = HSN_REPLIER; + handle_begin_handshake_reply(domain_id, hs, lid, msg->ridHandle); } else - result = false; - + { + printf("validate remote failed\n"); + } test_authentication_plugin_release_msg(msg); } - return result; } -void validate_handshake(dds_domainid_t domain_id, bool exp_req_fail, const char * exp_req_msg, bool exp_reply_fail, const char * exp_reply_msg) +static void handle_validate_local_identity(dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg) +{ + struct message *msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_LOCAL_IDENTITY, 0, 0, 0, TIMEOUT); + CU_ASSERT_FATAL (msg != NULL); + CU_ASSERT_FATAL ((msg->result == DDS_SECURITY_VALIDATION_OK) != exp_localid_fail); + if (exp_localid_fail && exp_localid_msg) + { + printf("validate_local_identity failed as expected (msg: %s)\n", msg->err_msg); + CU_ASSERT_FATAL (msg->err_msg && strstr(msg->err_msg, exp_localid_msg) != NULL); + } + else + add_local_identity (msg->lidHandle, &msg->lguid); + test_authentication_plugin_release_msg (msg); +} + +void validate_handshake(dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg, struct Handshake *hs_list[], int *nhs) { - printf("validate handshake for domain %d\n", domain_id); clear_stores(); - struct message *msg = test_authentication_plugin_take_msg (domain_id, MESSAGE_KIND_VALIDATE_LOCAL_IDENTITY, 0, 0, 0, TIMEOUT); - CU_ASSERT_FATAL (msg != NULL); - add_local_identity (msg->lidHandle, &msg->lguid); - test_authentication_plugin_release_msg (msg); - bool is_requester = false; - char * err_msg_req = NULL, *err_msg_reply = NULL; - bool ret = handle_validate_remote_identity (domain_id, localIdentityList[0].handle, 1, &is_requester, &err_msg_req, &err_msg_reply); - CU_ASSERT_FATAL ((is_requester && ret != exp_req_fail) || (!is_requester && ret != exp_reply_fail)); - if (ret) + if (nhs) + *nhs = 0; + if (hs_list) + *hs_list = NULL; + + handle_validate_local_identity(domain_id, exp_localid_fail, exp_localid_msg); + if (!exp_localid_fail) { - DDS_Security_ValidationResult_t exp_result = is_requester ? DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE : DDS_SECURITY_VALIDATION_OK; - CU_ASSERT_EQUAL_FATAL (handshakeList[0].finalResult, exp_result); + handle_validate_remote_identity (domain_id, localIdentityList[0].handle, 1); + for (int n = 0; n < numHandshake; n++) + { + struct Handshake *hs = &handshakeList[n]; + printf("Result: hs %"PRId64", node type %s, final result %s\n", hs->handle, get_node_type_str(hs->node_type), get_validation_result_str(hs->finalResult)); + if (hs->err_msg && strlen (hs->err_msg)) + printf("- err_msg: %s\n", hs->err_msg); + } + if (nhs) + *nhs = numHandshake; + if (hs_list) + *hs_list = handshakeList; + else + handshake_list_fini(handshakeList, numHandshake); } - else if (is_requester && exp_req_msg) - { - CU_ASSERT_FATAL (err_msg_req && strstr(err_msg_req, exp_req_msg) != NULL); - } - else if (!is_requester && exp_reply_msg) - { - CU_ASSERT_FATAL (err_msg_reply && strstr(err_msg_reply, exp_reply_msg) != NULL); - } - if (err_msg_req) - ddsrt_free (err_msg_req); - if (err_msg_reply) - ddsrt_free (err_msg_reply); printf ("finished validate handshake for domain %d\n\n", domain_id); } +void validate_handshake_nofail (dds_domainid_t domain_id) +{ + struct Handshake *hs_list; + int nhs; + validate_handshake (domain_id, false, NULL, &hs_list, &nhs); + for (int n = 0; n < nhs; n++) + { + struct Handshake hs = hs_list[n]; + DDS_Security_ValidationResult_t exp_result = hs.node_type == HSN_REQUESTER ? DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE : DDS_SECURITY_VALIDATION_OK; + CU_ASSERT_EQUAL_FATAL (hs.finalResult, exp_result); + } + handshake_list_fini (hs_list, nhs); +} + +void handshake_list_fini(struct Handshake *hs_list, int nhs) +{ + for (int n = 0; n < nhs; n++) + { + struct Handshake hs = hs_list[n]; + ddsrt_free (hs.err_msg); + } +} \ No newline at end of file diff --git a/src/security/core/tests/common/handshake_test_utils.h b/src/security/core/tests/common/handshake_test_utils.h index 9ca8afb..0ae3a59 100644 --- a/src/security/core/tests/common/handshake_test_utils.h +++ b/src/security/core/tests/common/handshake_test_utils.h @@ -27,6 +27,13 @@ union guid { unsigned u[4]; }; +enum hs_node_type +{ + HSN_UNDEFINED, + HSN_REQUESTER, + HSN_REPLIER +}; + struct Identity { DDS_Security_IdentityHandle handle; @@ -36,13 +43,16 @@ struct Identity struct Handshake { DDS_Security_HandshakeHandle handle; - int isRequest; + enum hs_node_type node_type; int lidx; int ridx; DDS_Security_ValidationResult_t handshakeResult; DDS_Security_ValidationResult_t finalResult; + char * err_msg; }; -void validate_handshake(dds_domainid_t domain_id, bool exp_req_fail, const char * exp_req_msg, bool exp_reply_fail, const char * exp_reply_msg); +void validate_handshake(dds_domainid_t domain_id, bool exp_localid_fail, const char * exp_localid_msg, struct Handshake *hs_list[], int *nhs); +void validate_handshake_nofail (dds_domainid_t domain_id); +void handshake_list_fini(struct Handshake *hs_list, int nhs); #endif /* SECURITY_CORE_HANDSHAKE_TEST_UTILS_H_ */ diff --git a/src/security/core/tests/common/security_config_test_utils.c b/src/security/core/tests/common/security_config_test_utils.c index c6e939b..ef9f0f8 100644 --- a/src/security/core/tests/common/security_config_test_utils.c +++ b/src/security/core/tests/common/security_config_test_utils.c @@ -25,6 +25,7 @@ #include "dds/ddsrt/expand_vars.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/string.h" +#include "dds/ddsrt/io.h" #include "common/config_env.h" #include "security_config_test_utils.h" @@ -59,6 +60,33 @@ static const char *governance_xml = " " ""; +static const char *permissions_xml_grant = + " " + " ${SUBJECT_NAME}" + " 2015-09-15T01:00:002115-09-15T01:00:00" + " " + " 0230" + " " + " *" + " *" + " " + " " + " *" + " *" + " " + " " + " DENY" + " "; + +static const char *permissions_xml = + "" + "" + " " + " ${GRANTS}" + " " + ""; + + const char * expand_lookup_vars(const char *name, void * data) { struct kvp *vars = (struct kvp *)data; @@ -157,18 +185,59 @@ static char * smime_sign(char * ca_cert_path, char * ca_priv_key_path, const cha return output; } -static char *get_signed_governance_data(const char *gov_xml) +static char *get_signed_data(const char *data) { return smime_sign ( COMMON_ETC_PATH("default_permissions_ca.pem"), COMMON_ETC_PATH("default_permissions_ca_key.pem"), - gov_xml); + data); } -char * get_governance_config(struct kvp *config_vars) +static char * prefix_data (char * config_signed, bool add_prefix) { - char * config = ddsrt_expand_vars(governance_xml, &expand_lookup_vars, config_vars); - char * config_signed = get_signed_governance_data(config); - ddsrt_free (config); + if (add_prefix) + { + char * tmp = config_signed; + ddsrt_asprintf (&config_signed, "data:,%s", tmp); + ddsrt_free (tmp); + } return config_signed; } + +char * get_governance_config(struct kvp *config_vars, bool add_prefix) +{ + char * config = ddsrt_expand_vars (governance_xml, &expand_lookup_vars, config_vars); + char * config_signed = get_signed_data (config); + ddsrt_free (config); + return prefix_data (config_signed, add_prefix); +} + +char * get_permissions_grant(const char * name, const char * subject) +{ + struct kvp vars[] = { + { "GRANT_NAME", name, 1 }, + { "SUBJECT_NAME", subject, 1 }, + { NULL, NULL, 0 } + }; + return ddsrt_expand_vars (permissions_xml_grant, &expand_lookup_vars, vars); +} + +char * get_permissions_config(char * grants[], size_t ngrants, bool add_prefix) +{ + char *grants_str = NULL; + for (size_t n = 0; n < ngrants; n++) + { + char * tmp = grants_str; + ddsrt_asprintf (&grants_str, "%s%s", grants_str ? grants_str : "", grants[n]); + ddsrt_free (tmp); + } + struct kvp vars[] = { + { "GRANTS", grants_str, 1 }, + { NULL, NULL, 0} + }; + char *config = ddsrt_expand_vars (permissions_xml, &expand_lookup_vars, vars); + char *config_signed = get_signed_data (config); + ddsrt_free (grants_str); + ddsrt_free (config); + return prefix_data (config_signed, add_prefix); +} diff --git a/src/security/core/tests/common/security_config_test_utils.h b/src/security/core/tests/common/security_config_test_utils.h index ab14b7f..056b4d5 100644 --- a/src/security/core/tests/common/security_config_test_utils.h +++ b/src/security/core/tests/common/security_config_test_utils.h @@ -25,6 +25,8 @@ const char * expand_lookup_vars (const char *name, void * data); const char * expand_lookup_vars_env (const char *name, void * data); int32_t expand_lookup_unmatched (const struct kvp * lookup_table); -char * get_governance_config (struct kvp *config_vars); +char * get_governance_config (struct kvp *config_vars, bool add_prefix); +char * get_permissions_grant(const char * name, const char * subject); +char * get_permissions_config(char * grants[], size_t ngrants, bool add_prefix); #endif /* SECURITY_CORE_TEST_SECURITY_CONFIG_TEST_UTILS_H_ */ diff --git a/src/security/core/tests/common/test_identity.h b/src/security/core/tests/common/test_identity.h index 2fbcd3b..30bb916 100644 --- a/src/security/core/tests/common/test_identity.h +++ b/src/security/core/tests/common/test_identity.h @@ -17,7 +17,178 @@ #define TEST_IDENTITY_PRIVATE_KEY_DUMMY "testtext_PrivateKey_testtext" #define TEST_IDENTITY_CA_CERTIFICATE_DUMMY "testtext_IdentityCA_testtext" -#define TEST_IDENTITY_CERTIFICATE "data:,-----BEGIN CERTIFICATE-----\n\ +// Identity CAs +#define TEST_IDENTITY_CA1_CERTIFICATE "-----BEGIN CERTIFICATE-----\n\ +MIIEYzCCA0ugAwIBAgIUOp5yaGGuh0vaQTZHVPkX5jHoc/4wDQYJKoZIhvcNAQEL\n\ +BQAwgcAxCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJPVjEWMBQGA1UEBwwNTG9jYWxp\n\ +dHkgTmFtZTETMBEGA1UECwwKRXhhbXBsZSBPVTEjMCEGA1UECgwaRXhhbXBsZSBJ\n\ +RCBDQSBPcmdhbml6YXRpb24xFjAUBgNVBAMMDUV4YW1wbGUgSUQgQ0ExOjA4Bgkq\n\ +hkiG9w0BCQEWK2F1dGhvcml0eUBjeWNsb25lZGRzc2VjdXJpdHkuYWRsaW5rdGVj\n\ +aC5jb20wHhcNMjAwMjI3MTkyMjA1WhcNMzAwMjI0MTkyMjA1WjCBwDELMAkGA1UE\n\ +BhMCTkwxCzAJBgNVBAgMAk9WMRYwFAYDVQQHDA1Mb2NhbGl0eSBOYW1lMRMwEQYD\n\ +VQQLDApFeGFtcGxlIE9VMSMwIQYDVQQKDBpFeGFtcGxlIElEIENBIE9yZ2FuaXph\n\ +dGlvbjEWMBQGA1UEAwwNRXhhbXBsZSBJRCBDQTE6MDgGCSqGSIb3DQEJARYrYXV0\n\ +aG9yaXR5QGN5Y2xvbmVkZHNzZWN1cml0eS5hZGxpbmt0ZWNoLmNvbTCCASIwDQYJ\n\ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALKhk7JXUpqJphyOC6oOI00LH49WTtO2\n\ +GCgDyJhcRYYAm7APMtmEDH+zptvd34N4eSu03Dc65cB/XN4Lbi2TjolVvKz0hHjz\n\ +tzmQT5jTgb1UkJX4NjKGw+RrYe9Ls0kfoAL2kvb12kmd1Oj4TIKMZP9TCrz7Vw8m\n\ +cZKQxZ56bLys6cU2XdiTp3v+Ef/vMll4+DINj4ZAMWL3CkT+q1G6ZxHRpFlsIyhc\n\ +Q1wX6gxUoY6cQdBA7TehKCCEWz4L1KM1A18ZmCHmjTniU0ssLoiAzsQs4b6Fnw8Z\n\ +MLFj8ocwzN5g66gJJWGofakXqX/V24KbGl54WX2X7FYU0tGzR234DXcCAwEAAaNT\n\ +MFEwHQYDVR0OBBYEFGeCcK8B74QWCuuCjlSUzOBBUTF5MB8GA1UdIwQYMBaAFGeC\n\ +cK8B74QWCuuCjlSUzOBBUTF5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\n\ +BQADggEBAJQeMc4XzMFnpQKCb58rzRs3Wt9FmZZS4O596sHxMEewTkEHm5gLYMzF\n\ +9JYEdUiLoTurQuIr0KgPi+Q3kliQdLfrVPbdWTmlUDZARR5ir5d1gGHST6qnb3Xi\n\ +mG+7nwle9R/hLrtPio+gYRgwJEiS55f6p0/E1wDcc+6numvjCRQ/CGIiJfwD/R+d\n\ +pv93YLEfuliZttfBc/apIu6OL4chxF+3QgSw1ltV5nXXqDTGHMRZENkp3Yiolumc\n\ +6smL4uA7Q812pVcENi3MLjdJgBS/8DcSBQHspVuXugaKKPDMkJnD0IyLWc8vLXh4\n\ +O7JdDrmusJAZA9RsTkinl3DuPfF34Sk=\n\ +-----END CERTIFICATE-----" + +#define TEST_IDENTITY_CA1_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n\ +MIIEowIBAAKCAQEAsqGTsldSmommHI4Lqg4jTQsfj1ZO07YYKAPImFxFhgCbsA8y\n\ +2YQMf7Om293fg3h5K7TcNzrlwH9c3gtuLZOOiVW8rPSEePO3OZBPmNOBvVSQlfg2\n\ +MobD5Gth70uzSR+gAvaS9vXaSZ3U6PhMgoxk/1MKvPtXDyZxkpDFnnpsvKzpxTZd\n\ +2JOne/4R/+8yWXj4Mg2PhkAxYvcKRP6rUbpnEdGkWWwjKFxDXBfqDFShjpxB0EDt\n\ +N6EoIIRbPgvUozUDXxmYIeaNOeJTSywuiIDOxCzhvoWfDxkwsWPyhzDM3mDrqAkl\n\ +Yah9qRepf9XbgpsaXnhZfZfsVhTS0bNHbfgNdwIDAQABAoIBAAylo+9cf1yxojEj\n\ +XXAM0DMENpfPZIVYvx0WJ32iCsoSAPPWH6OG1du0vHuUmd6VCP8vLug6I0odulV+\n\ +Oa7AY7cVeuZD6Z0mpDJPJVOMpgLhmdsEV9H7+KKTd7uZgHgM5SdQjdcuUOYlZo2Y\n\ +BtK3Xe810ezPXrqT3jaiSVuPD2PMO/LH3S+MSynHUZdou+NEr0S5FyX7HT2SUvPg\n\ +nEG5KUSE32/1Rnho9BacWKQ/HAoBiS+jMRHOPwu1Q/qS/QLw8HRDEuEoXlVYoNMc\n\ +il0r3M25COZVJVJecBqXHAWZqCBsqmNXs2hU1bh8VVKl/CMkG3W+IAR7XzMmw6bi\n\ +ZYAvgQECgYEA3pIeB8WptYv7hU0I1FZMfyhwLZDRSTZMlObTIXXsdSVKEllBwKAW\n\ +N0G84cyl7q+tOio63tbk1rQRi21O0wTrt16j+0SqDIYy59QhqXhiKAko+nf7cSpy\n\ +8h+k+HF5HpxsxcwYPiwO1SywPJ4TuDLIRHXXqschRzNtATrqCBtNeBsCgYEAzXX5\n\ +cQfMORsg0Z/K0d/U8JLdK0dnqsjwKt+9L7BAGOSv9Xxf4OT+vK3AlzkTUUOztXy7\n\ +3YzpSrHy1Dzu57Dv83BgCFPJxa7jKX4/n+SFYjqxcQVSziQAJjyaa0JsxYkxWC0K\n\ +IXg8MXYcgwHL6k/PYblQCJw8Lgtf8J2DtXhZTdUCgYAvt/4uRmfLX7bObqS8+b+u\n\ +55mde1YTr0ueBRsxKlpHB3apFm/tf6UjtblsY/cThKDMPq+ehU5M5hB45zemMIDl\n\ +MKpRvfgDdWZGpAmPjxrkYIpjoQPM0IASf0xcY9/G+1yqz8ZG1iVb+RfT90RdEq4z\n\ +V1yk5cqxvEnboKj6kff7DwKBgQCXnqbcVZ/MyIs4ho4awO4YNpkGNiR3cN9jFEc9\n\ +aPh0Jlb/drAee37M6AAG2LS7tJVqqcjNXw5N8/G509mNmxIH+Pa1TnfI7R1v4l27\n\ +dd1EtwF44S/RNdnyXaiq3JL+VxbV9i7SsjLhYUL7HplHqWvltuYr5He4luZO3z5x\n\ +7YUhnQKBgHmjhmSEPPxZLjPcYJ/z2opXalPJ5OObJ6nM6X4T5LvfhSnANdeeM6yj\n\ +gigRY8UlnNYzC5iSt17/VuMeta7I8GaVNUu7WU72Q7sYYlrXevdgl/0OFYayXHlB\n\ +sSo6yb9za+C2+5olHEZvs7dIzwDcveoEatds/X4VNrULEwaGbZR0\n\ +-----END RSA PRIVATE KEY-----" + +#define TEST_IDENTITY_CA2_CERTIFICATE "-----BEGIN CERTIFICATE-----\n\ +MIIEbTCCA1WgAwIBAgIUL0mSpPRgzveYTJ8UHSmOIwkIjjYwDQYJKoZIhvcNAQEL\n\ +BQAwgcUxCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJPVjEWMBQGA1UEBwwNTG9jYWxp\n\ +dHkgTmFtZTETMBEGA1UECwwKRXhhbXBsZSBPVTElMCMGA1UECgwcRXhhbXBsZSBJ\n\ +RCBDQSAyIE9yZ2FuaXphdGlvbjEYMBYGA1UEAwwPRXhhbXBsZSBJRCBDQSAyMTsw\n\ +OQYJKoZIhvcNAQkBFixhdXRob3JpdHkyQGN5Y2xvbmVkZHNzZWN1cml0eS5hZGxp\n\ +bmt0ZWNoLmNvbTAeFw0yMDAyMjcxNjI3MjRaFw0zMDAyMjQxNjI3MjRaMIHFMQsw\n\ +CQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5hbWUx\n\ +EzARBgNVBAsMCkV4YW1wbGUgT1UxJTAjBgNVBAoMHEV4YW1wbGUgSUQgQ0EgMiBP\n\ +cmdhbml6YXRpb24xGDAWBgNVBAMMD0V4YW1wbGUgSUQgQ0EgMjE7MDkGCSqGSIb3\n\ +DQEJARYsYXV0aG9yaXR5MkBjeWNsb25lZGRzc2VjdXJpdHkuYWRsaW5rdGVjaC5j\n\ +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDk+ewDf871kPgBqXkm\n\ +UEXdf/vqWWoKx3KfJ4N3Gq4vt/cDOMs0xakpqr5uxm787AvbOui4P8QmT8naLhAA\n\ +TvHtNGg2LV0ZQtLcVVFsXXsBYDUEbLJYmCBtJU8zSfLLzgtN+z9nVqLthAcVyGhZ\n\ +iEkCfXKS4XzwjFUxgrXUM1VSiHHz8DbreQFDTF8mVavZ75HjieuHz1OcSaoIHCIF\n\ +mhPDlxRR/qZpc3Y52NZMNRHVPj4Tmc3N4H2eneeoG7nVn0MgNuqbssezeQtUOOoH\n\ +DgPGp3xzd8XQxaF5hVIM9E7aL77kw5v4gwccjL5xWC72zzxC3c1ltmbaEcwhHGsu\n\ +MR4lAgMBAAGjUzBRMB0GA1UdDgQWBBTTpmGTY5teWrZBA8Sd7kL5Lg/JmjAfBgNV\n\ +HSMEGDAWgBTTpmGTY5teWrZBA8Sd7kL5Lg/JmjAPBgNVHRMBAf8EBTADAQH/MA0G\n\ +CSqGSIb3DQEBCwUAA4IBAQCbelDJr9sVsYgQSp4yzSOSop5DSOWCweBF56NatcbY\n\ +3HUYc4iaH4NcB04WFkUl2XmqVCAM0zbmV0q4HoQikTK5PBHmwxuuD2HhPDWtMeFR\n\ +W96BjzGVpV27yaNIPvLwjTVV+A72r4vRvufiFhrMCovRwlWgHY6+gXKfrtyljTZ0\n\ +m1mENHOJOQWDXFAXP5yiehSMKy/izKvQ1G1hLErYMMc+sdgF/9X2KaudnTakTW0d\n\ +44kXUFKSU7mqV44D12unxCNODclznd31tiJ+70U39AXlR2BzwBzyFzPCh5JYtMog\n\ +TwbdLY3LN40gpkDUxIIH115D7ujUKNd8s2gmSHOCm1ar\n\ +-----END CERTIFICATE-----" + +#define TEST_IDENTITY_CA2_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n\ +MIIEogIBAAKCAQEA5PnsA3/O9ZD4Aal5JlBF3X/76llqCsdynyeDdxquL7f3AzjL\n\ +NMWpKaq+bsZu/OwL2zrouD/EJk/J2i4QAE7x7TRoNi1dGULS3FVRbF17AWA1BGyy\n\ +WJggbSVPM0nyy84LTfs/Z1ai7YQHFchoWYhJAn1ykuF88IxVMYK11DNVUohx8/A2\n\ +63kBQ0xfJlWr2e+R44nrh89TnEmqCBwiBZoTw5cUUf6maXN2OdjWTDUR1T4+E5nN\n\ +zeB9np3nqBu51Z9DIDbqm7LHs3kLVDjqBw4Dxqd8c3fF0MWheYVSDPRO2i++5MOb\n\ ++IMHHIy+cVgu9s88Qt3NZbZm2hHMIRxrLjEeJQIDAQABAoIBABBUirKNMPNujWGA\n\ +9rT20KTFde/2xItUQiZ7qPKbooSguCswp71xw2jHVqGL4WqEYywVfXd2hMS+uASp\n\ +eFatSq/CJxSGE7ezflpcc1wpJpaoh99y6R1MbDOcj5N22KwUW9YJ7zGtih0qZ170\n\ +VgzcnWhiDgPPtRtqxsCrM9CYgKNMGU6M9CFPX3PKDudKVU5fmi9bhtCqQaLhImbs\n\ +aQO3y4yI0af4KSQSur+eqeB/z7V39BEo1LfqaVQd1e9ItEYnTg8TaSaCshS4H8UG\n\ +Yx/pGhnxgn8+5LFL2K635Mb99OLb0hUwIOAbuoAuTlKijit0uGEJe/+DjbkcgZ5d\n\ +VB9I8UECgYEA/56Em8M6N6mTUN3WN+U8NSLltjSIL8kemK30dJ56aUsTiy4h0jNa\n\ +Jda7BeRPQcf9pnQpgFkV7XoKIbfTIqOhqD8XAvJL4//+VMmH2q/R2Xf6e0/CIEUe\n\ +3K74QyRVazx+tt+NOafCwjU9bA7ebjwQVsb+dPAS6kOWxTCZFzCgFk0CgYEA5VE+\n\ +U/C8D9zmJjL1uc4XkBNAg/dQNybQ9DX2Ku5dKME6yg4u7Lxnl3X9asvtQAsUeOPa\n\ +dKGkQ8NZfnSvXYd04n/FTRohFCaYz3RWIbo/q4KCsnJk6uAUM9YFeQGqZdEjO3Mu\n\ +Yk1uhHFl+C4Q/InzYEs+QwtMOS7XVMa5vm6OQzkCgYAR+xKU6ly0AaetLo2dDPD5\n\ +Q+UotfVGdz1BvCrP8T3nHjLXvXz/jkEvHDW3qmGw3OKIzO8Gaj3SoJ0J1iZx71S1\n\ +wwpZWLXh6eX4DN0Tkv6N75SdC/U50+Lh3yTzhCDGFFFNh9glUBmxE5Gogjs/QdZc\n\ +ZE8N5r1N4Uc/w7VhHjiEmQKBgHMA2pQ4P+horRdtKSTEwbZkoU9NYXI3SkWfJlSD\n\ +dD7zISuiD1B0cDNaXfwIR3R92geCpdUmF35QYvpzRFtQioLo9ybiusIjVTF9M5D4\n\ +mePGsQsTKZ9NP3R7mgUEm9MyHkw7SIDOOmW7hRsA503vVRnuwkvXR6PJ5P3EJ/Tj\n\ +9v6pAoGAfVTCJkf0aZ7KjV5GQ33l8uH9dEBzRJ4xOjGpeVBTm+L5N4ejcrQ4p9t0\n\ +JQr8hQHEp7tnHZ9H8DuIIQVDUJdrRa1qO+TNQiOdPLRNofXHuFDNIoj4+bP5ISnL\n\ +dImrEylWjCLbiiOpIbBmAQLb55xYsFzkdRCW3AlmldSVUW96yfU=\n\ +-----END RSA PRIVATE KEY-----" + +// Permissions CAs +#define TEST_PERMISSIONS_CA_CERTIFICATE "-----BEGIN CERTIFICATE-----\n\ +MIIEbzCCA1egAwIBAgIUfoby6818hlJQ+41KUHiM6BZll/0wDQYJKoZIhvcNAQEL\n\ +BQAwgcYxCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJPVjEWMBQGA1UEBwwNTG9jYWxp\n\ +dHkgTmFtZTETMBEGA1UECwwKRXhhbXBsZSBPVTEgMB4GA1UECgwXRXhhbXBsZSBD\n\ +QSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUgUGVybWlzc2lvbnMgQ0Ex\n\ +OjA4BgkqhkiG9w0BCQEWK2F1dGhvcml0eUBjeWNsb25lZGRzc2VjdXJpdHkuYWRs\n\ +aW5rdGVjaC5jb20wHhcNMjAwMjI3MTM0ODA5WhcNMzAwMjI0MTM0ODA5WjCBxjEL\n\ +MAkGA1UEBhMCTkwxCzAJBgNVBAgMAk9WMRYwFAYDVQQHDA1Mb2NhbGl0eSBOYW1l\n\ +MRMwEQYDVQQLDApFeGFtcGxlIE9VMSAwHgYDVQQKDBdFeGFtcGxlIENBIE9yZ2Fu\n\ +aXphdGlvbjEfMB0GA1UEAwwWRXhhbXBsZSBQZXJtaXNzaW9ucyBDQTE6MDgGCSqG\n\ +SIb3DQEJARYrYXV0aG9yaXR5QGN5Y2xvbmVkZHNzZWN1cml0eS5hZGxpbmt0ZWNo\n\ +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNWwyrW3J+TCyaZ\n\ +H77q+29GGqFsYP5rv9cpcL/TMDNccsPYY+1RA1K+zMRYo1LG8VdJNtJlhxE+tmEb\n\ +KxsVUTtoj8zbLVU4P4g0gIh6U7LMv5lUEZ3XYKWvYrbZTFMof2rXQYGXPO7pFnvb\n\ +NAbnMiLmagRKxKJ91kq4utuMG3U6rkCA7i2S8cEISNO3gIpFa0IZJ8yS8wDlKa/L\n\ +GxL90BYasLsSA6tw/69OIiUUYqpMRD+xxyyTkMO37VjmdiFLHa/dxO8HH0t3Q0U0\n\ +AgZP9uwYTgZpN+2UEFnjv3BDIydc3Wa0UaSdxLtHXMPvg3sRuH9CTqr4Le7/3uTY\n\ +ehYKgd0CAwEAAaNTMFEwHQYDVR0OBBYEFFi4pK986ZSB0BLiMm8ivu6AUxYPMB8G\n\ +A1UdIwQYMBaAFFi4pK986ZSB0BLiMm8ivu6AUxYPMA8GA1UdEwEB/wQFMAMBAf8w\n\ +DQYJKoZIhvcNAQELBQADggEBAHYLaJVWrLHg+62jC8yIz9dbECIroX9Gb7Ll937H\n\ +Mum6Hj4wlImrifMVV3iORWBrBLvtTtn0Zno3mwfjLRQtkjOih71eJT+6//B7CT7n\n\ +oULJYVq8IRGErbKtmXULnxTajFApzO0v4hSu7rWj/Jfhil0TX7QgKNpgKzjYodWz\n\ +3oGGtchxvw3+v9wdIWD5Cj0bk/VMCQCaBV0anvyga7d4k8/zPF7nW2Z9jNfKsVD1\n\ +piFa+Yd4zN6XOPPKiFXfLD7ht9i2gG25iS+d95tKg1DfjnRD7u0BJSOAPerxGtN/\n\ +wf43qY1XzUoE2FBJ9QJGOA/02ffaUMOwSzICF/ShctH+Knk=\n\ +-----END CERTIFICATE-----" + +#define TEST_PERMISSIONS_CA_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n\ +MIIEpAIBAAKCAQEA01bDKtbcn5MLJpkfvur7b0YaoWxg/mu/1ylwv9MwM1xyw9hj\n\ +7VEDUr7MxFijUsbxV0k20mWHET62YRsrGxVRO2iPzNstVTg/iDSAiHpTssy/mVQR\n\ +nddgpa9ittlMUyh/atdBgZc87ukWe9s0BucyIuZqBErEon3WSri624wbdTquQIDu\n\ +LZLxwQhI07eAikVrQhknzJLzAOUpr8sbEv3QFhqwuxIDq3D/r04iJRRiqkxEP7HH\n\ +LJOQw7ftWOZ2IUsdr93E7wcfS3dDRTQCBk/27BhOBmk37ZQQWeO/cEMjJ1zdZrRR\n\ +pJ3Eu0dcw++DexG4f0JOqvgt7v/e5Nh6FgqB3QIDAQABAoIBABFHMKGZ+2OYc/rt\n\ +3eiP8YqBYr/7ylpCmOaQXsVwEKrCTiew00qdqvXi337V+FRWK3kFZVQCNO61/9ck\n\ +j3uhXIjM3aTT7nrfJGKQWEnQJnOhxbBVbTNIXoBtPFbSoSjTUMd9Xb+oi7TEna/2\n\ +leRSloi/6b78FeNrAlANlklIxR3qTjRSxjGYVfukCWsKq3uFfWM4Wp9N1B1gsyRo\n\ +/SH2jOu0XTLNdajggtBKcFoqxVIiaetERKVRRid7pW0zwuYS5Zwv5Wtl3XMbUuAn\n\ +VGesMeCKAGpwkLjmvXKBE5setnd7cWBKdVKddYDkzbDvU7X6QEHFnac6m6OQ2P62\n\ +QfkO94ECgYEA70tV55AreDnPQEpf698ZjA8pYvF90GfGx/Y4oYWU/s0IlD6Pfbsr\n\ +qkRu+1I+SUNZWARhirXmJzuOmJYUQRteCEq+6RPJzn5Jl9MtipOBAjI0h589dbAB\n\ +8m/BRk+bEZKCXLgVa0TyZ/gd/wDBxB+qd+bPep8nAl4krMWK9W1+DLECgYEA4hfP\n\ +EwUPMwHrGlq0oRUA08ssQ8XxVCKWeS3cLAJjO6EdJyIUm/8S/UZPBPeSkGyZeld+\n\ +fY7z9ZV0HA338p5BYYDCqgJC6b5Ud5UV0yLkq01v6b0H3nSjTPcbA61l9laN0vhm\n\ +QJ/xTiAHgsGBbOx2VtwDoE8T1AbAaamcapqNYu0CgYAXCiPdRc5JpxdDU2Xk6fgl\n\ +uhf8BNBeTn+fJR/SvW/ZEJiw3U0nh+vuWuRsokCJAUkK5nEVz+m3AU77dgfBNQda\n\ +uQeknVki3pnrWlPaMdWMBpV0MWrTd/zYANaVFHkTug1/K+I0D9FfHU6WDNabMYlS\n\ +PhDf947j9XiGggadFsu6IQKBgQC6dgpIVFbZqU5cuMvZQToicaA68Kd7zN6uZ7z5\n\ +6qouRkyFtpyqnq3pha+rmAYe6AGXnUrrgBcAxdYxQO/o/s1K/WcN0LmgjmCZErIi\n\ +I9fU0xNmAIjZ1PXMhsqXuMyrYWyrvkKOL5pR5SZsluwHieh68A5pim3+4eaT/dbL\n\ +MFVEbQKBgQDfkeApSfKATXJpYIV/tiGjmRkkYoZ6NVar92npjlb72jaA4V0gHmuD\n\ +9ttypXOJPB/5zMa5uL6drp3CLv/GcWekUiUUXuyKQpcxZWqxf/leh9gTgGDAH/k4\n\ +4+zX4HLEzTmoOc0cqzi4w6pTIj29BOV5QpnnyUGyvj8NGNSdFvZFSQ==\n\ +-----END RSA PRIVATE KEY-----" + + +// Identities + +// created with TEST_IDENTITY_CA1_CERTIFICATE +#define TEST_IDENTITY1_CERTIFICATE "-----BEGIN CERTIFICATE-----\n\ MIIEDTCCAvUCFHZ4yXyk/9yeMxgHs6Ib0bLKhXYuMA0GCSqGSIb3DQEBCwUAMIHA\n\ MQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5h\n\ bWUxEzARBgNVBAsMCkV4YW1wbGUgT1UxIzAhBgNVBAoMGkV4YW1wbGUgSUQgQ0Eg\n\ @@ -42,7 +213,7 @@ VwzWIaZ06idvCtPKTfP71jJypV3+I2g5PNqranbuMv5nNAKZq1QlSB07f2Z1VIu6\n\ 6jeSZSADfm73qnE2Kj1PiZkPn0Wu+K24GXCvdILATcUS\n\ -----END CERTIFICATE-----" -#define TEST_IDENTITY_PRIVATE_KEY "data:,-----BEGIN RSA PRIVATE KEY-----\n\ +#define TEST_IDENTITY1_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n\ MIIEpQIBAAKCAQEA5mEhLZIP2ko1bRJyJCwbnvhIpXFv6GOhnvuS5v8tsTju40O6\n\ 2NNQmKT/my1QVKiUu7OoWZtLNBebgxgJ851eQ4TBRXy/f2jGkLPYM22dohLTblVC\n\ pGutn+Itw3QRM3nkne7Sk8O6FP6NH6Y+7gkjxy5kI3GvhuICuBIzAV4dHK+hPlCn\n\ @@ -71,35 +242,8 @@ yNw1+km1Zy6EWdFEMciEFlbRwWVmDfE/um9LZsSWbmuWAOTww9GBDhc=\n\ -----END RSA PRIVATE KEY-----" -#define TEST_IDENTITY_CA_CERTIFICATE "data:,-----BEGIN CERTIFICATE-----\n\ -MIIEYzCCA0ugAwIBAgIUOp5yaGGuh0vaQTZHVPkX5jHoc/4wDQYJKoZIhvcNAQEL\n\ -BQAwgcAxCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJPVjEWMBQGA1UEBwwNTG9jYWxp\n\ -dHkgTmFtZTETMBEGA1UECwwKRXhhbXBsZSBPVTEjMCEGA1UECgwaRXhhbXBsZSBJ\n\ -RCBDQSBPcmdhbml6YXRpb24xFjAUBgNVBAMMDUV4YW1wbGUgSUQgQ0ExOjA4Bgkq\n\ -hkiG9w0BCQEWK2F1dGhvcml0eUBjeWNsb25lZGRzc2VjdXJpdHkuYWRsaW5rdGVj\n\ -aC5jb20wHhcNMjAwMjI3MTkyMjA1WhcNMzAwMjI0MTkyMjA1WjCBwDELMAkGA1UE\n\ -BhMCTkwxCzAJBgNVBAgMAk9WMRYwFAYDVQQHDA1Mb2NhbGl0eSBOYW1lMRMwEQYD\n\ -VQQLDApFeGFtcGxlIE9VMSMwIQYDVQQKDBpFeGFtcGxlIElEIENBIE9yZ2FuaXph\n\ -dGlvbjEWMBQGA1UEAwwNRXhhbXBsZSBJRCBDQTE6MDgGCSqGSIb3DQEJARYrYXV0\n\ -aG9yaXR5QGN5Y2xvbmVkZHNzZWN1cml0eS5hZGxpbmt0ZWNoLmNvbTCCASIwDQYJ\n\ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALKhk7JXUpqJphyOC6oOI00LH49WTtO2\n\ -GCgDyJhcRYYAm7APMtmEDH+zptvd34N4eSu03Dc65cB/XN4Lbi2TjolVvKz0hHjz\n\ -tzmQT5jTgb1UkJX4NjKGw+RrYe9Ls0kfoAL2kvb12kmd1Oj4TIKMZP9TCrz7Vw8m\n\ -cZKQxZ56bLys6cU2XdiTp3v+Ef/vMll4+DINj4ZAMWL3CkT+q1G6ZxHRpFlsIyhc\n\ -Q1wX6gxUoY6cQdBA7TehKCCEWz4L1KM1A18ZmCHmjTniU0ssLoiAzsQs4b6Fnw8Z\n\ -MLFj8ocwzN5g66gJJWGofakXqX/V24KbGl54WX2X7FYU0tGzR234DXcCAwEAAaNT\n\ -MFEwHQYDVR0OBBYEFGeCcK8B74QWCuuCjlSUzOBBUTF5MB8GA1UdIwQYMBaAFGeC\n\ -cK8B74QWCuuCjlSUzOBBUTF5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\n\ -BQADggEBAJQeMc4XzMFnpQKCb58rzRs3Wt9FmZZS4O596sHxMEewTkEHm5gLYMzF\n\ -9JYEdUiLoTurQuIr0KgPi+Q3kliQdLfrVPbdWTmlUDZARR5ir5d1gGHST6qnb3Xi\n\ -mG+7nwle9R/hLrtPio+gYRgwJEiS55f6p0/E1wDcc+6numvjCRQ/CGIiJfwD/R+d\n\ -pv93YLEfuliZttfBc/apIu6OL4chxF+3QgSw1ltV5nXXqDTGHMRZENkp3Yiolumc\n\ -6smL4uA7Q812pVcENi3MLjdJgBS/8DcSBQHspVuXugaKKPDMkJnD0IyLWc8vLXh4\n\ -O7JdDrmusJAZA9RsTkinl3DuPfF34Sk=\n\ ------END CERTIFICATE-----" - - -#define TEST_IDENTITY2_CERTIFICATE "data:,-----BEGIN CERTIFICATE-----\n\ +// created with TEST_IDENTITY_CA2_CERTIFICATE +#define TEST_IDENTITY2_CERTIFICATE "-----BEGIN CERTIFICATE-----\n\ MIIEDjCCAvYCFDEZQzcfGKK8IKNyH+AdNSjdyVgnMA0GCSqGSIb3DQEBCwUAMIHF\n\ MQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5h\n\ bWUxEzARBgNVBAsMCkV4YW1wbGUgT1UxJTAjBgNVBAoMHEV4YW1wbGUgSUQgQ0Eg\n\ @@ -124,7 +268,7 @@ AuPUgPJObxJhxJSC4p5qy37pYZHiNH1wG/+BDHgZo3wNwFsWqxabKziGB8XU3INc\n\ USI3GDWM2jjElMSnDCj4ChM5wFbwWrqwdOEzeGWBWbo3hQ==\n\ -----END CERTIFICATE-----" -#define TEST_IDENTITY2_PRIVATE_KEY "data:,-----BEGIN RSA PRIVATE KEY-----\n\ +#define TEST_IDENTITY2_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n\ MIIEpQIBAAKCAQEAwBAz143TONNN1kAsJOKOiDSirH+SqdZW1VaNX9zfg7I+9S4f\n\ 8M1EfoKvR8jvpSKigsP2d+8d7nZfyhkfxao1bubuDt0yWK4MkPfJWl0tGZNOCXjQ\n\ RLwxOqZ1vbLy63vQwl/mdTPQRCz2Ve+dPSu7QHYJ/K5uI+1otJ/IOhUGREtt/N6p\n\ @@ -153,32 +297,58 @@ mi1HgIUzXZTRBNamYCltJWYnN0hOlSL6vcHgeJ9y1gSDh0QqB2BG8HY=\n\ -----END RSA PRIVATE KEY-----" -#define TEST_IDENTITY_CA2_CERTIFICATE "data:,-----BEGIN CERTIFICATE-----\n\ -MIIEbTCCA1WgAwIBAgIUL0mSpPRgzveYTJ8UHSmOIwkIjjYwDQYJKoZIhvcNAQEL\n\ -BQAwgcUxCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJPVjEWMBQGA1UEBwwNTG9jYWxp\n\ -dHkgTmFtZTETMBEGA1UECwwKRXhhbXBsZSBPVTElMCMGA1UECgwcRXhhbXBsZSBJ\n\ -RCBDQSAyIE9yZ2FuaXphdGlvbjEYMBYGA1UEAwwPRXhhbXBsZSBJRCBDQSAyMTsw\n\ -OQYJKoZIhvcNAQkBFixhdXRob3JpdHkyQGN5Y2xvbmVkZHNzZWN1cml0eS5hZGxp\n\ -bmt0ZWNoLmNvbTAeFw0yMDAyMjcxNjI3MjRaFw0zMDAyMjQxNjI3MjRaMIHFMQsw\n\ -CQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5hbWUx\n\ -EzARBgNVBAsMCkV4YW1wbGUgT1UxJTAjBgNVBAoMHEV4YW1wbGUgSUQgQ0EgMiBP\n\ -cmdhbml6YXRpb24xGDAWBgNVBAMMD0V4YW1wbGUgSUQgQ0EgMjE7MDkGCSqGSIb3\n\ -DQEJARYsYXV0aG9yaXR5MkBjeWNsb25lZGRzc2VjdXJpdHkuYWRsaW5rdGVjaC5j\n\ -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDk+ewDf871kPgBqXkm\n\ -UEXdf/vqWWoKx3KfJ4N3Gq4vt/cDOMs0xakpqr5uxm787AvbOui4P8QmT8naLhAA\n\ -TvHtNGg2LV0ZQtLcVVFsXXsBYDUEbLJYmCBtJU8zSfLLzgtN+z9nVqLthAcVyGhZ\n\ -iEkCfXKS4XzwjFUxgrXUM1VSiHHz8DbreQFDTF8mVavZ75HjieuHz1OcSaoIHCIF\n\ -mhPDlxRR/qZpc3Y52NZMNRHVPj4Tmc3N4H2eneeoG7nVn0MgNuqbssezeQtUOOoH\n\ -DgPGp3xzd8XQxaF5hVIM9E7aL77kw5v4gwccjL5xWC72zzxC3c1ltmbaEcwhHGsu\n\ -MR4lAgMBAAGjUzBRMB0GA1UdDgQWBBTTpmGTY5teWrZBA8Sd7kL5Lg/JmjAfBgNV\n\ -HSMEGDAWgBTTpmGTY5teWrZBA8Sd7kL5Lg/JmjAPBgNVHRMBAf8EBTADAQH/MA0G\n\ -CSqGSIb3DQEBCwUAA4IBAQCbelDJr9sVsYgQSp4yzSOSop5DSOWCweBF56NatcbY\n\ -3HUYc4iaH4NcB04WFkUl2XmqVCAM0zbmV0q4HoQikTK5PBHmwxuuD2HhPDWtMeFR\n\ -W96BjzGVpV27yaNIPvLwjTVV+A72r4vRvufiFhrMCovRwlWgHY6+gXKfrtyljTZ0\n\ -m1mENHOJOQWDXFAXP5yiehSMKy/izKvQ1G1hLErYMMc+sdgF/9X2KaudnTakTW0d\n\ -44kXUFKSU7mqV44D12unxCNODclznd31tiJ+70U39AXlR2BzwBzyFzPCh5JYtMog\n\ -TwbdLY3LN40gpkDUxIIH115D7ujUKNd8s2gmSHOCm1ar\n\ +// created with TEST_IDENTITY_CA1_CERTIFICATE +#define TEST_IDENTITY3_CERTIFICATE "-----BEGIN CERTIFICATE-----\n\ +MIIEDTCCAvUCFHZ4yXyk/9yeMxgHs6Ib0bLKhXYvMA0GCSqGSIb3DQEBCwUAMIHA\n\ +MQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5h\n\ +bWUxEzARBgNVBAsMCkV4YW1wbGUgT1UxIzAhBgNVBAoMGkV4YW1wbGUgSUQgQ0Eg\n\ +T3JnYW5pemF0aW9uMRYwFAYDVQQDDA1FeGFtcGxlIElEIENBMTowOAYJKoZIhvcN\n\ +AQkBFithdXRob3JpdHlAY3ljbG9uZWRkc3NlY3VyaXR5LmFkbGlua3RlY2guY29t\n\ +MB4XDTIwMDMwNTEzMTczN1oXDTMwMDMwMzEzMTczN1owgcQxCzAJBgNVBAYTAk5M\n\ +MQswCQYDVQQIDAJPVjEWMBQGA1UEBwwNTG9jYWxpdHkgTmFtZTEhMB8GA1UECwwY\n\ +T3JnYW5pemF0aW9uYWwgVW5pdCBOYW1lMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2Fu\n\ +aXphdGlvbjEWMBQGA1UEAwwNQ2Fyb2wgRXhhbXBsZTE2MDQGCSqGSIb3DQEJARYn\n\ +Y2Fyb2xAY3ljbG9uZWRkc3NlY3VyaXR5LmFkbGlua3RlY2guY29tMIIBIjANBgkq\n\ +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0QduVwXptfjiwkvbn5aXuIpwZ9aWOqmj\n\ +e36qNknnS0mng1zPhzi4RLAl6CUxa6E5bkfjGZxFfYefDNk3ynzerEotFa1f5++b\n\ +aY73hs2ecfz+9ofjqR2fsroxOFwFF9JLbeWTDPS2mf5yE0Ci2+ctq6Ep4jDeHNui\n\ +WpSOY8OoIEWq4PD/R/VGJSiHSG+OjOUN7gwuxta0yglFeyHBdzr8mDZiejj1KYBD\n\ +AzuQrtaibHNtGBo3VGFvPKs85mK/Swv1GoXxcy1uBU1Yup9JLq3Ds8R5YYecSlXk\n\ +77EmZl4dgoScbt4NKTPuo8t803Ph3PYQCggILhlaEwjpfd1YTFLxOQIDAQABMA0G\n\ +CSqGSIb3DQEBCwUAA4IBAQAtV57Zc5dV9+z51zTOtghNZrFGJ48xJhnXddMVJ1Yh\n\ +08uoODRSRJHXNxMrlSRMeZ+CNkvd/QmqzOYvok3EqusOXFNU9qfmc3DToU/DDqkf\n\ +PMEpc9lPLTjmm6MfQgjyT5pDDNPUV9Io1s2o492ozr87ULyVf6I2bNu2NnVv2IzE\n\ +j9Mz/L7TkcgJgbdDl+21CR3NRA1PpxFB/PcM+zy4C2XoFv/qcF5pkcBpkyNjva9m\n\ +xmjSJWMoIVzXk6apPsRGCJLFJ3uuj+9K6POo/xgAkrbgvZF0i0yAJSTvSQmg6x2S\n\ +FMxE89kC7Npg+fQF15aaNEn4tuQiz0WW9pq1wSTXjoqj\n\ -----END CERTIFICATE-----" +#define TEST_IDENTITY3_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n\ +MIIEpAIBAAKCAQEA0QduVwXptfjiwkvbn5aXuIpwZ9aWOqmje36qNknnS0mng1zP\n\ +hzi4RLAl6CUxa6E5bkfjGZxFfYefDNk3ynzerEotFa1f5++baY73hs2ecfz+9ofj\n\ +qR2fsroxOFwFF9JLbeWTDPS2mf5yE0Ci2+ctq6Ep4jDeHNuiWpSOY8OoIEWq4PD/\n\ +R/VGJSiHSG+OjOUN7gwuxta0yglFeyHBdzr8mDZiejj1KYBDAzuQrtaibHNtGBo3\n\ +VGFvPKs85mK/Swv1GoXxcy1uBU1Yup9JLq3Ds8R5YYecSlXk77EmZl4dgoScbt4N\n\ +KTPuo8t803Ph3PYQCggILhlaEwjpfd1YTFLxOQIDAQABAoIBAGSpyHh+L3vj/QgG\n\ +0iB7vFsxyEopbDWaBlHtwPjeBFYchWBcrNB4/zyM++RdLPyhKvAyDGsD9+8pBe6B\n\ +GT4Zfn7IRgf/c4VVvalLIWc41IoehYaiEIAb9RF0W0nB/u3m505oVbXSj7F/eN5O\n\ +rV9raHIT7gCw+fY5y2kFy8C9s9S9+VzzYOzIZPWSh6Plc/eI2niSVt+MDufDeVOR\n\ +Ug6Z54lpXkwqv0Pz8F7ELyRGBvUW5UAvgyprvXgSYz1VNeHr3fmLX/O4rGktk02x\n\ +bAFxvaNV/JEK1fLFWLZ8TJVGsni+uYu/zkvXdxw7gphdoM77UKeZ00udg7orYUhW\n\ +6MwsuRUCgYEA7KzanZVPfbL4TMCpS6EJUO8H9lebH0srzqKNJD3/NL2JPebRNjZA\n\ +niH6vXD773/8IYlFTAXe0npVApZETKVzP4LNvsSVtjNvqXKdRM0cT47Dc4Y16kn/\n\ +X9Pd/ff+HH93T8Pcpguovw8QU7nxlf5dCvlnWrCj84Dw1ZToS2NLWAcCgYEA4hiy\n\ +nz6xvbkkUc5oHWxJIHxSLrOvMsyLMNp9UlUxgrxGqth0yQsFZwinPzs/y8aUVKyi\n\ +bHJlL35fpHeuna0V054E5vyeOOM7eLLFToDITS1m91hsl6amMW8iup/HTZhSemt7\n\ +tEn4mWlINXyP47MWfOr4oQ1KDzDCA3JFfzjInL8CgYBRulL3zcKYbn/tyS3s7twP\n\ +taszNwdbJBMplNpWZI5HQRguZxFhvhRMRwGV/3kQOErxrbxfRzutxQ6sCQXmzc9h\n\ +ZCL2OF5Wf6aUhf6m7olTM8JslzDxCcKE7d2fwM5gOugRhFoigK4x49rIftJc8Gxi\n\ +yMMW/x5ujN0ddAFPXyd6awKBgQCypX8lsnzwgsR+2w+LCA+z2md5PULWaaYlgM36\n\ +6xPG0AsqXQPSAqJPKhg0LxWWZp63VPy1oaHv5/OcWXCgZ63SWo5XEQ3Xtzw7f03F\n\ +XJ5n1NMB511Oaj/w2XZgbXUmC5BH6HuDFduXJAgJMxXifZPsOiEf6Ac3f3gdDwJ4\n\ +pp5kswKBgQDNUI3uzqw8J3e81tTAn2U8eyHuQxi8swv6K4Dx+sqCKpxkFcYvDLQl\n\ +qI+v234hvmZN3CmGPCY01aZl3NUUFKx9fvwweYG/vicCsA2XKwnmaSWTTrT62vlY\n\ +S1cWlJlUjw59ZhAqgD1pe4r0suRQ6e1OT/pByTKz1BxE/lwZftpauA==\n\ +-----END RSA PRIVATE KEY-----" #endif /* PLUGIN_SECURITY_CORE_TEST_IDENTITY_H_ */ diff --git a/src/security/core/tests/handshake.c b/src/security/core/tests/handshake.c index 5534434..62ca589 100644 --- a/src/security/core/tests/handshake.c +++ b/src/security/core/tests/handshake.c @@ -43,9 +43,9 @@ static const char *config = " " " " " " - " "TEST_IDENTITY_CERTIFICATE"" - " "TEST_IDENTITY_PRIVATE_KEY"" - " "TEST_IDENTITY_CA_CERTIFICATE"" + " data:,"TEST_IDENTITY1_CERTIFICATE"" + " data:,"TEST_IDENTITY1_PRIVATE_KEY"" + " data:,"TEST_IDENTITY_CA1_CERTIFICATE"" " " " " " " @@ -91,6 +91,6 @@ static void handshake_fini(void) CU_Test(ddssec_handshake, happy_day, .init = handshake_init, .fini = handshake_fini) { - validate_handshake (DDS_DOMAINID_PART1, false, NULL, false, NULL); - validate_handshake (DDS_DOMAINID_PART2, false, NULL, false, NULL); + validate_handshake_nofail (DDS_DOMAINID_PART1); + validate_handshake_nofail (DDS_DOMAINID_PART2); } diff --git a/src/security/core/tests/secure_communication.c b/src/security/core/tests/secure_communication.c index 10769e0..7ed18b5 100644 --- a/src/security/core/tests/secure_communication.c +++ b/src/security/core/tests/secure_communication.c @@ -59,9 +59,9 @@ static const char *config = " " " " " " - " "TEST_IDENTITY_CERTIFICATE"" - " "TEST_IDENTITY_PRIVATE_KEY"" - " "TEST_IDENTITY_CA_CERTIFICATE"" + " data:,"TEST_IDENTITY1_CERTIFICATE"" + " data:,"TEST_IDENTITY1_PRIVATE_KEY"" + " data:,"TEST_IDENTITY_CA1_CERTIFICATE"" " " " ." " " @@ -89,6 +89,10 @@ const char * g_pk_encrypt = "ENCRYPT"; const char * g_pk_sign_oa = "SIGN_WITH_ORIGIN_AUTHENTICATION"; const char * g_pk_encrypt_oa = "ENCRYPT_WITH_ORIGIN_AUTHENTICATION"; +const char * g_pp_secret = "ppsecret"; +const char * g_groupdata_secret = "groupsecret"; +const char * g_ep_secret = "epsecret"; + uint32_t g_topic_nr = 0; static dds_entity_t g_pub_domains[MAX_DOMAINS]; @@ -106,6 +110,9 @@ struct domain_sec_config { DDS_Security_ProtectionKind metadata_pk; DDS_Security_BasicProtectionKind payload_pk; const char * payload_secret; + const char * pp_userdata_secret; + const char * groupdata_secret; + const char * ep_userdata_secret; }; typedef void (*set_crypto_params_fn)(struct dds_security_cryptography_impl *, const struct domain_sec_config *); @@ -170,6 +177,7 @@ static dds_qos_t *get_qos() dds_qset_history (qos, DDS_HISTORY_KEEP_ALL, -1); dds_qset_durability (qos, DDS_DURABILITY_TRANSIENT_LOCAL); dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY); + dds_qset_userdata (qos, g_ep_secret, strlen (g_ep_secret)); return qos; } @@ -183,12 +191,15 @@ static char *create_topic_name(const char *prefix, uint32_t nr, char *name, size 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_entity_t pp = dds_create_participant (domain_id, NULL, NULL); + dds_qos_t *qos = dds_create_qos (); + dds_qset_userdata (qos, g_pp_secret, strlen (g_pp_secret)); + dds_entity_t pp = dds_create_participant (domain_id, qos, NULL); CU_ASSERT_FATAL (pp > 0); + dds_delete_qos (qos); struct dds_security_cryptography_impl * crypto_context = get_crypto_context (pp); CU_ASSERT_FATAL (crypto_context != NULL); - if (set_crypto_params) - set_crypto_params (crypto_context, domain_config); + assert (set_crypto_params); + set_crypto_params (crypto_context, domain_config); return pp; } @@ -204,8 +215,11 @@ static void create_dom_pp_pubsub(dds_domainid_t domain_id_base, const char * dom { size_t pp_index = d * n_pp + p; pps[pp_index] = create_pp (domain_id_base + (uint32_t)d, domain_sec_config, set_crypto_params); - pubsubs[pp_index] = pubsub_create (pps[pp_index], NULL, NULL); + dds_qos_t *qos = dds_create_qos (); + dds_qset_groupdata (qos, g_groupdata_secret, strlen (g_groupdata_secret)); + pubsubs[pp_index] = pubsub_create (pps[pp_index], qos, NULL); CU_ASSERT_FATAL (pubsubs[pp_index] > 0); + dds_delete_qos (qos); } } } @@ -230,7 +244,7 @@ static void test_init(const struct domain_sec_config * domain_config, size_t n_s print_config_vars(governance_vars); printf("\n"); - char * gov_config_signed = get_governance_config (governance_vars); + char * gov_config_signed = get_governance_config (governance_vars, false); struct kvp config_vars[] = { { "GOVERNANCE_DATA", gov_config_signed, 1 }, @@ -417,13 +431,21 @@ static void set_encryption_parameters_basic(struct dds_security_cryptography_imp static void set_encryption_parameters_secret(struct dds_security_cryptography_impl * crypto_context, const struct domain_sec_config *domain_config) { set_encrypted_secret (crypto_context, domain_config->payload_secret); + set_encryption_parameters_basic (crypto_context, domain_config); +} + +static void set_encryption_parameters_disc(struct dds_security_cryptography_impl * crypto_context, const struct domain_sec_config *domain_config) +{ + set_entity_data_secret (crypto_context, domain_config->pp_userdata_secret, domain_config->groupdata_secret, domain_config->ep_userdata_secret); + set_encryption_parameters_basic (crypto_context, domain_config); + set_disc_protection_kinds (crypto_context, domain_config->discovery_pk, domain_config->liveliness_pk); } static void test_discovery_liveliness_protection(DDS_Security_ProtectionKind discovery_pk, DDS_Security_ProtectionKind liveliness_pk) { struct domain_sec_config domain_config = { discovery_pk, liveliness_pk, PK_N, PK_N, BPK_N, NULL }; /* FIXME: add more asserts in wrapper or test instead of just testing communication */ - test_write_read (&domain_config, 1, 1, 1, 1, 1, 1, NULL); + test_write_read (&domain_config, 1, 1, 1, 1, 1, 1, &set_encryption_parameters_disc); } static void test_data_protection_kind(DDS_Security_ProtectionKind rtps_pk, DDS_Security_ProtectionKind metadata_pk, DDS_Security_BasicProtectionKind payload_pk)