From aef4f0a12661c7149d990acad47dc00a5573b2b9 Mon Sep 17 00:00:00 2001 From: Stefan Kimmer Date: Fri, 24 Jan 2020 10:53:18 +0100 Subject: [PATCH] Certificate trigger and directory operations Implement trigger of certificate and permission expiries using the timed callbacks. Implement directory operations such that trusted CA can be read. This implements OS abstraction functions such as opendir and stat. Signed-off-by: Stefan Kimmer --- src/ddsrt/CMakeLists.txt | 2 +- src/ddsrt/include/dds/ddsrt/filesystem.h | 123 + .../include/dds/ddsrt/filesystem/posix.h | 34 + .../include/dds/ddsrt/filesystem/windows.h | 34 + src/ddsrt/src/filesystem/posix/filesystem.c | 116 + src/ddsrt/src/filesystem/windows/filesystem.c | 122 + .../access_control/src/access_control.c | 51 +- .../authentication/src/auth_utils.c | 50 +- .../authentication/src/authentication.c | 43 +- .../builtin_plugins/tests/CMakeLists.txt | 6 + .../builtin_plugins/tests/config_env.h.in | 1 + .../etc/Test_Permissions_listener.p7s | 51 - .../src/listeners_access_control_utests.c | 49 +- .../etc/Example_Governance.p7s | 120 + .../etc/Example_Permissions_Alice.p7s | 98 + .../etc/Example_Permissions_Bob.p7s | 98 + .../etc/Identity_CA_Cert.pem | 25 + .../etc/Identity_CA_Private_Key.pem | 27 + .../etc/Permissions_CA_Cert.pem | 26 + .../src/listeners_authentication_utests.c | 2105 +++++++++++++++++ .../src/process_handshake_utests.c | 2 +- .../validate_begin_handshake_reply_utests.c | 9 +- .../src/validate_local_identity_utests.c | 9 +- .../dds/security/core/dds_security_timed_cb.h | 6 +- src/security/core/src/dds_security_utils.c | 1 + 25 files changed, 3039 insertions(+), 169 deletions(-) create mode 100644 src/ddsrt/include/dds/ddsrt/filesystem.h create mode 100644 src/ddsrt/include/dds/ddsrt/filesystem/posix.h create mode 100644 src/ddsrt/include/dds/ddsrt/filesystem/windows.h create mode 100644 src/ddsrt/src/filesystem/posix/filesystem.c create mode 100644 src/ddsrt/src/filesystem/windows/filesystem.c delete mode 100644 src/security/builtin_plugins/tests/listeners_access_control/etc/Test_Permissions_listener.p7s create mode 100644 src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Governance.p7s create mode 100644 src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Alice.p7s create mode 100644 src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Bob.p7s create mode 100644 src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Cert.pem create mode 100644 src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Private_Key.pem create mode 100644 src/security/builtin_plugins/tests/listeners_authentication/etc/Permissions_CA_Cert.pem create mode 100644 src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt index c9c44a7..00d51e5 100644 --- a/src/ddsrt/CMakeLists.txt +++ b/src/ddsrt/CMakeLists.txt @@ -149,7 +149,7 @@ list(APPEND sources # network stack. In order to mix-and-match various compilers, architectures, # operating systems, etc input from the build system is required. foreach(feature atomics cdtors environ heap ifaddrs random rusage - sockets string sync threads time md5 process netstat dynlib) + sockets string sync threads time md5 process netstat dynlib filesystem) if(EXISTS "${include_path}/dds/ddsrt/${feature}.h") list(APPEND headers "${include_path}/dds/ddsrt/${feature}.h") file(GLOB_RECURSE diff --git a/src/ddsrt/include/dds/ddsrt/filesystem.h b/src/ddsrt/include/dds/ddsrt/filesystem.h new file mode 100644 index 0000000..60ade53 --- /dev/null +++ b/src/ddsrt/include/dds/ddsrt/filesystem.h @@ -0,0 +1,123 @@ +/* + * Copyright(c) 2006 to 2018 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 FILESYSTEM_H +#define FILESYSTEM_H + +#include + +#include "dds/export.h" +#include "dds/ddsrt/retcode.h" +#include "dds/ddsrt/time.h" + +#if _WIN32 +#include "dds/ddsrt/filesystem/windows.h" +#else +#include "dds/ddsrt/filesystem/posix.h" +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + +struct ddsrt_stat { + ddsrt_mode_t stat_mode; + size_t stat_size; + dds_time_t stat_mtime; +}; + + +struct ddsrt_dirent { + char d_name[DDSRT_PATH_MAX + 1]; +}; + +/** \brief opendir wrapper + * + * Open the directory conform opendir + * + * Precondition: + * none + * + * Possible results: + * - return DDS_RETCODE_OK if directory 'name' is opened + * - DDS_RETCODE_ERROR if 'name' could not + * be found or is not a directory. + */ +DDS_EXPORT dds_return_t ddsrt_opendir(const char *name, ddsrt_dir_handle_t *dir); + +/** \brief closedir wrapper + * + * Close the directory conform closdir + * + * Precondition: + * none + * + * Possible results: + * - return DDS_RETCODE_OK if directory identified by the handle + * is succesfully closed + * - return DDS_RETCODE_ERROR if the handle is invalid. + */ +DDS_EXPORT dds_return_t ddsrt_closedir(ddsrt_dir_handle_t d); + +/** \brief readdir wrapper + * + * Read the directory conform readdir. + * + * Precondition: + * none + * + * Possible results: + * - return DDS_RETCODE_OK if next directory is found + * - return DDS_RETCODE_ERROR if no more directories are found. + */ +DDS_EXPORT dds_return_t ddsrt_readdir(ddsrt_dir_handle_t d, struct ddsrt_dirent *direntp); + +/** \brief stat wrapper + * + * Gets directory status conform stat. + * + * Precondition: + * none + * + * Possible results: + * - return DDS_RETCODE_OK if stat is successful + * - return DDS_RETCODE_ERROR if stat fails. + */ +DDS_EXPORT dds_return_t ddsrt_stat(const char *path, struct ddsrt_stat *buf); + +/** \brief Transforms the given filepath into a platform specific filepath. + * + * This translation function will replace any platform file seperator into + * the fileseperator of the current platform. Doulbe quotes are removed + * as well. + * + * Precondition: + * none + * + * Possible results: + * - returns normalized filepath conform current platform + * - return NULL if out of memory. + */ +DDS_EXPORT char* ddsrt_file_normalize(const char *filepath); + +/** \brief Get file seperator + * + * Possible Results: + * - "" + */ +DDS_EXPORT const char* ddsrt_file_sep(void); + +#if defined (__cplusplus) +} +#endif + +#endif // FILESYSTEM_H diff --git a/src/ddsrt/include/dds/ddsrt/filesystem/posix.h b/src/ddsrt/include/dds/ddsrt/filesystem/posix.h new file mode 100644 index 0000000..7d8e7c2 --- /dev/null +++ b/src/ddsrt/include/dds/ddsrt/filesystem/posix.h @@ -0,0 +1,34 @@ +/* + * Copyright(c) 2006 to 2018 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 DDSRT_FILESYSTEM_POSIX_H +#define DDSRT_FILESYSTEM_POSIX_H + +#include +#include +#include +#include + +typedef DIR *ddsrt_dir_handle_t; +typedef mode_t ddsrt_mode_t; + +#define DDSRT_PATH_MAX PATH_MAX +#define DDSRT_FILESEPCHAR '/' + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* DDSRT_FILESYSTEM_POSIX_H */ diff --git a/src/ddsrt/include/dds/ddsrt/filesystem/windows.h b/src/ddsrt/include/dds/ddsrt/filesystem/windows.h new file mode 100644 index 0000000..abde1d6 --- /dev/null +++ b/src/ddsrt/include/dds/ddsrt/filesystem/windows.h @@ -0,0 +1,34 @@ +/* + * Copyright(c) 2006 to 2018 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 DDSRT_FILESYSTEM_WINDOWS_H +#define DDSRT_FILESYSTEM_WINDOWS_H + +#include +#include + +#include "dds/ddsrt/types.h" + +typedef HANDLE ddsrt_dir_handle_t; +typedef unsigned short ddsrt_mode_t; + +#define DDSRT_PATH_MAX MAX_PATH +#define DDSRT_FILESEPCHAR '\\' + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* DDSRT_FILESYSTEM_WINDOWS_H */ diff --git a/src/ddsrt/src/filesystem/posix/filesystem.c b/src/ddsrt/src/filesystem/posix/filesystem.c new file mode 100644 index 0000000..11b57ce --- /dev/null +++ b/src/ddsrt/src/filesystem/posix/filesystem.c @@ -0,0 +1,116 @@ +/* + * Copyright(c) 2006 to 2018 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 "dds/ddsrt/filesystem.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/heap.h" + +dds_return_t ddsrt_opendir(const char *name, ddsrt_dir_handle_t *dir) +{ + dds_return_t result = DDS_RETCODE_ERROR; + DIR *d; + if (dir) { + d = opendir(name); + if (d) { + *dir = d; + result = DDS_RETCODE_OK; + } + } + return result; +} + +dds_return_t ddsrt_readdir(ddsrt_dir_handle_t d, struct ddsrt_dirent *direntp) +{ + dds_return_t result; + struct dirent *d_entry; + + result = DDS_RETCODE_ERROR; + if (d && direntp) { + d_entry = readdir(d); + if (d_entry) { + ddsrt_strlcpy(direntp->d_name, d_entry->d_name, sizeof(direntp->d_name)); + result = DDS_RETCODE_OK; + } + } + + return result; +} + +dds_return_t ddsrt_closedir(ddsrt_dir_handle_t d) +{ + dds_return_t result; + + result = DDS_RETCODE_ERROR; + if (d) { + if (closedir(d) == 0) { + result = DDS_RETCODE_OK; + } + } + + return result; +} + +dds_return_t ddsrt_stat(const char *path, struct ddsrt_stat *buf) +{ + dds_return_t result; + struct stat _buf; + int r; + + r = stat(path, &_buf); + if (r == 0) { + buf->stat_mode = _buf.st_mode; + buf->stat_size = (size_t) _buf.st_size; + buf->stat_mtime = DDS_SECS(_buf.st_mtime); + result = DDS_RETCODE_OK; + } else { + result = DDS_RETCODE_ERROR; + } + + return result; +} + +char * ddsrt_file_normalize(const char *filepath) +{ + char *norm; + const char *fpPtr; + char *normPtr; + + norm = NULL; + if ((filepath != NULL) && (*filepath != '\0')) { + norm = ddsrt_malloc(strlen(filepath) + 1); + /* replace any / or \ by DDSRT_FILESEPCHAR */ + fpPtr = (char *) filepath; + normPtr = norm; + while (*fpPtr != '\0') { + *normPtr = *fpPtr; + if ((*fpPtr == '/') || (*fpPtr == '\\')) { + *normPtr = DDSRT_FILESEPCHAR; + normPtr++; + } else { + if (*fpPtr != '\"') { + normPtr++; + } + } + fpPtr++; + } + *normPtr = '\0'; + } + + return norm; +} + +const char *ddsrt_file_sep(void) +{ + return "/"; +} diff --git a/src/ddsrt/src/filesystem/windows/filesystem.c b/src/ddsrt/src/filesystem/windows/filesystem.c new file mode 100644 index 0000000..068d76e --- /dev/null +++ b/src/ddsrt/src/filesystem/windows/filesystem.c @@ -0,0 +1,122 @@ +/* + * Copyright(c) 2006 to 2018 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 "dds/ddsrt/filesystem.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/io.h" + +dds_return_t ddsrt_opendir(const char *name, ddsrt_dir_handle_t *dir) +{ + dds_return_t result; + + TCHAR szDir[DDSRT_PATH_MAX + 1]; + WIN32_FIND_DATA FileData; + HANDLE hList; + + result = DDS_RETCODE_ERROR; + if (dir) { + snprintf(szDir, DDSRT_PATH_MAX, "%s\\*", name); + hList = FindFirstFile(szDir, &FileData); + + if (hList != INVALID_HANDLE_VALUE) { + *dir = hList; + result = DDS_RETCODE_OK; + } + } + + return result; +} + +dds_return_t ddsrt_readdir(ddsrt_dir_handle_t d, struct ddsrt_dirent *direntp) +{ + dds_return_t result; + WIN32_FIND_DATA FileData; + BOOL r; + + if (direntp) { + r = FindNextFile(d, &FileData); + if (r) { + ddsrt_strlcpy(direntp->d_name, FileData.cFileName, sizeof(direntp->d_name)); + result = DDS_RETCODE_OK; + } else { + result = DDS_RETCODE_ERROR; + } + } else { + result = DDS_RETCODE_ERROR; + } + + return result; +} + +dds_return_t ddsrt_closedir(ddsrt_dir_handle_t d) +{ + FindClose(d); + + return DDS_RETCODE_OK; +} + +dds_return_t ddsrt_stat(const char *path, struct ddsrt_stat *buf) +{ + dds_return_t result; + struct _stat _buf; + int r; + + r = _stat(path, &_buf); + if (r == 0) { + buf->stat_mode = _buf.st_mode; + buf->stat_size = _buf.st_size; + buf->stat_mtime = DDS_SECS(_buf.st_mtime);; + result = DDS_RETCODE_OK; + } else { + result = DDS_RETCODE_ERROR; + } + + return result; +} + +char * ddsrt_file_normalize(const char *filepath) +{ + char *norm; + const char *fpPtr; + char *normPtr; + + norm = NULL; + if ((filepath != NULL) && (*filepath != '\0')) { + norm = ddsrt_malloc(strlen(filepath) + 1); + /* replace any / or \ by DDSRT_FILESEPCHAR */ + fpPtr = (char *) filepath; + normPtr = norm; + while (*fpPtr != '\0') { + *normPtr = *fpPtr; + if ((*fpPtr == '/') || (*fpPtr == '\\')) { + *normPtr = DDSRT_FILESEPCHAR; + normPtr++; + } else { + if (*fpPtr != '\"') { + normPtr++; + } + } + fpPtr++; + } + *normPtr = '\0'; + } + + return norm; +} + +const char *ddsrt_file_sep(void) +{ + return "\\"; +} diff --git a/src/security/builtin_plugins/access_control/src/access_control.c b/src/security/builtin_plugins/access_control/src/access_control.c index f356445..d26b761 100644 --- a/src/security/builtin_plugins/access_control/src/access_control.c +++ b/src/security/builtin_plugins/access_control/src/access_control.c @@ -26,6 +26,7 @@ #include "access_control_utils.h" #include "access_control_objects.h" #include "access_control_parser.h" +#include "dds/security/core/dds_security_timed_cb.h" #if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10100000L #define REMOVE_THREAD_STATE() ERR_remove_thread_state(NULL); @@ -78,9 +79,10 @@ typedef struct dds_security_access_control_impl struct AccessControlTable *local_permissions; #endif struct AccessControlTable *remote_permissions; -#if TIMED_CALLBACK_IMPLEMENTED - struct ut_timed_dispatcher_t *timed_callbacks; -#endif + + struct dds_security_timed_cb_data *timed_callbacks; + struct dds_security_timed_dispatcher_t *dispatcher; + } dds_security_access_control_impl; static bool get_sec_attributes(dds_security_access_control_impl *ac, const DDS_Security_PermissionsHandle permissions_handle, const char *topic_name, @@ -105,9 +107,7 @@ static struct topic_rule *find_topic_from_domain_rule(struct domain_rule *domain static DDS_Security_boolean domainid_within_sets(struct domain_id_set *domain, int domain_id); static DDS_Security_boolean compare_class_id_plugin_classname(DDS_Security_string class_id_1, DDS_Security_string class_id_2); static DDS_Security_boolean compare_class_id_major_ver(DDS_Security_string class_id_1, DDS_Security_string class_id_2); -#if TIMED_CALLBACK_IMPLEMENTED - static void add_validity_end_trigger(dds_security_access_control_impl *ac, const DDS_Security_PermissionsHandle permissions_handle, dds_time_t end); -#endif +static void add_validity_end_trigger(dds_security_access_control_impl *ac, const DDS_Security_PermissionsHandle permissions_handle, dds_time_t end); static DDS_Security_boolean is_allowed_by_permissions(struct permissions_parser *permissions, int domain_id, const char *topic_name, const DDS_Security_PartitionQosPolicy *partitions, const char *identity_subject_name, permission_criteria_type criteria_type, DDS_Security_SecurityException *ex); static void sanity_check_local_access_rights(local_participant_access_rights *rights); @@ -168,10 +168,8 @@ validate_local_permissions( { assert (rights->permissions_expiry != DDS_TIME_INVALID); -#if TIMED_CALLBACK_IMPLEMENTED if (rights->permissions_expiry != 0) add_validity_end_trigger(ac, permissions_handle, rights->permissions_expiry); -#endif } return permissions_handle; @@ -232,10 +230,8 @@ validate_remote_permissions( permissions_handle = ACCESS_CONTROL_OBJECT_HANDLE(remote_rights); -#if TIMED_CALLBACK_IMPLEMENTED if (permissions_handle != DDS_SECURITY_HANDLE_NIL) add_validity_end_trigger(ac, permissions_handle, remote_rights->permissions_expiry); -#endif if (remote_rights) access_control_table_insert(ac->remote_permissions, (AccessControlObject *)remote_rights); @@ -926,16 +922,12 @@ set_listener(dds_security_access_control *instance, DDS_Security_SecurityException *ex) { DDSRT_UNUSED_ARG(ex); -#if TIMED_CALLBACK_IMPLEMENTED + dds_security_access_control_impl *ac = (dds_security_access_control_impl *)instance; if (listener) - ut_timed_dispatcher_enable(ac->timed_callbacks, (void *)listener); + dds_security_timed_dispatcher_enable(ac->timed_callbacks, ac->dispatcher, (void *)listener); else - ut_timed_dispatcher_disable(ac->timed_callbacks); -#else - DDSRT_UNUSED_ARG(instance); - DDSRT_UNUSED_ARG(listener); -#endif + dds_security_timed_dispatcher_disable(ac->timed_callbacks, ac->dispatcher); return true; } @@ -1490,9 +1482,9 @@ int init_access_control(const char *argument, void **context) dds_security_access_control_impl *access_control = ddsrt_malloc(sizeof(*access_control)); memset(access_control, 0, sizeof(*access_control)); -#if TIMED_CALLBACK_IMPLEMENTED - access_control->timed_callbacks = ut_timed_dispatcher_new(); -#endif + + access_control->timed_callbacks = dds_security_timed_cb_new(); + access_control->dispatcher = dds_security_timed_dispatcher_new(access_control->timed_callbacks); access_control->base.validate_local_permissions = &validate_local_permissions; access_control->base.validate_remote_permissions = &validate_remote_permissions; access_control->base.check_create_participant = &check_create_participant; @@ -1875,7 +1867,6 @@ find_remote_permissions_by_permissions_handle( return (remote_participant_access_rights *)args.object; } -#if TIMED_CALLBACK_IMPLEMENTED typedef struct { @@ -1884,15 +1875,17 @@ typedef struct } validity_cb_info; static void -validity_callback(struct ut_timed_dispatcher_t *d, - ut_timed_cb_kind kind, +validity_callback(struct dds_security_timed_dispatcher_t *d, + dds_security_timed_cb_kind kind, void *listener, void *arg) { validity_cb_info *info = arg; + + DDSRT_UNUSED_ARG(d); assert(d); assert(arg); - if (kind == UT_TIMED_CB_KIND_TIMEOUT) + if (kind == DDS_SECURITY_TIMED_CB_KIND_TIMEOUT) { assert(listener); if (1 /* TODO: Check if hdl is still valid or if it has been already returned. */) @@ -1913,9 +1906,8 @@ add_validity_end_trigger(dds_security_access_control_impl *ac, validity_cb_info *arg = ddsrt_malloc(sizeof(validity_cb_info)); arg->ac = ac; arg->hdl = permissions_handle; - ut_timed_dispatcher_add(ac->timed_callbacks, validity_callback, end, (void *)arg); + dds_security_timed_dispatcher_add(ac->timed_callbacks, ac->dispatcher, validity_callback, end, (void *)arg); } -#endif static DDS_Security_boolean is_allowed_by_permissions(struct permissions_parser *permissions, @@ -2465,9 +2457,10 @@ int finalize_access_control(void *context) dds_security_access_control_impl *access_control = context; if (access_control) { -#if TIMED_CALLBACK_IMPLEMENTED - ut_timed_dispatcher_free(access_control->timed_callbacks); -#endif + + dds_security_timed_dispatcher_free(access_control->timed_callbacks, access_control->dispatcher); + dds_security_timed_cb_free(access_control->timed_callbacks); + access_control_table_free(access_control->remote_permissions); #ifdef ACCESS_CONTROL_USE_ONE_PERMISSION if (access_control->local_access_rights) diff --git a/src/security/builtin_plugins/authentication/src/auth_utils.c b/src/security/builtin_plugins/authentication/src/auth_utils.c index 430dffd..54b2224 100644 --- a/src/security/builtin_plugins/authentication/src/auth_utils.c +++ b/src/security/builtin_plugins/authentication/src/auth_utils.c @@ -30,6 +30,8 @@ #include #include "dds/ddsrt/time.h" #include "dds/ddsrt/heap.h" +#include "dds/ddsrt/filesystem.h" +#include "dds/ddsrt/retcode.h" #include "dds/security/dds_security_api_defs.h" #include "dds/security/core/dds_security_utils.h" #include @@ -47,11 +49,11 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/atomics.h" #include "dds/ddsrt/string.h" +#include "dds/ddsrt/io.h" #include "dds/security/core/dds_security_utils.h" #include #include "auth_utils.h" - #define MAX_TRUSTED_CA 100 char * @@ -1190,40 +1192,29 @@ get_trusted_ca_list ( const char* trusted_ca_dir, DDS_Security_ValidationResult_t loading_result = DDS_RETCODE_OK; - DDSRT_UNUSED_ARG( ca_list ); - DDSRT_UNUSED_ARG( trusted_ca_dir ); - DDSRT_UNUSED_ARG( ex ); -/* TODO: Trusted CA directory tracing function should be ported */ -/* TODO: MAX_TRUSTED_CA limitation will be removed */ -#ifdef TRUSTED_CA_LIST_IMPLEMENTED - os_result r; - os_dirHandle d_descr; - struct os_dirent d_entry; - struct os_stat_s status; + dds_return_t r; + ddsrt_dir_handle_t d_descr; + struct ddsrt_dirent d_entry; + struct ddsrt_stat status; char *full_file_path; char *trusted_ca_dir_normalized; X509 *ca_buffer_array[MAX_TRUSTED_CA]; /*max trusted CA size */ unsigned ca_buffer_array_size=0; unsigned i; - trusted_ca_dir_normalized = os_fileNormalize(trusted_ca_dir); + trusted_ca_dir_normalized = ddsrt_file_normalize(trusted_ca_dir); - r = os_opendir(trusted_ca_dir_normalized, &d_descr); + r = ddsrt_opendir(trusted_ca_dir_normalized, &d_descr); ddsrt_free ( trusted_ca_dir_normalized ); - - if (r == os_resultSuccess && ca_buffer_array_size < MAX_TRUSTED_CA) { /* accessable */ - r = os_readdir(d_descr, &d_entry); - while (r == os_resultSuccess) { - full_file_path = (char*) ddsrt_malloc(strlen(trusted_ca_dir) + strlen(os_fileSep()) + strlen(d_entry.d_name) + strlen(os_fileSep()) + 1 ); - ddsrt_strcpy(full_file_path, trusted_ca_dir); - ddsrt_strcat(full_file_path, os_fileSep()); - ddsrt_strcat(full_file_path, d_entry.d_name); - - if (os_stat (full_file_path, &status) == os_resultSuccess) { /* accessable */ + if (r == DDS_RETCODE_OK && ca_buffer_array_size < MAX_TRUSTED_CA) { /* accessable */ + r = ddsrt_readdir(d_descr, &d_entry); + while (r == DDS_RETCODE_OK) { + ddsrt_asprintf(&full_file_path, "%s%s%s", trusted_ca_dir, ddsrt_file_sep(), d_entry.d_name); + if (ddsrt_stat (full_file_path, &status) == DDS_RETCODE_OK) { /* accessable */ if ((strcmp(d_entry.d_name, ".") != 0) && (strcmp(d_entry.d_name, "..") != 0)) { - char * filename = os_fileNormalize(full_file_path); + char * filename = ddsrt_file_normalize(full_file_path); if(filename){ X509 *identityCA; @@ -1239,26 +1230,26 @@ get_trusted_ca_list ( const char* trusted_ca_dir, } } } - r = os_readdir(d_descr, &d_entry); + r = ddsrt_readdir(d_descr, &d_entry); ddsrt_free(full_file_path); } - os_closedir (d_descr); + ddsrt_closedir (d_descr); /* deallocate given ca_list if it is not NULL */ free_ca_list_contents(ca_list); /*copy CAs to out parameter as HASH*/ if( ca_buffer_array_size > 0 ){ - ca_list->_buffer = ddsrt_malloc( ca_buffer_array_size * sizeof(X509 * ) ); + ca_list->buffer = ddsrt_malloc( ca_buffer_array_size * sizeof(X509 * ) ); for (i = 0; i < ca_buffer_array_size; ++i) { - ca_list->_buffer[i] = ca_buffer_array[i]; + ca_list->buffer[i] = ca_buffer_array[i]; } } - ca_list->_length = ca_buffer_array_size; + ca_list->length = ca_buffer_array_size; return DDS_SECURITY_VALIDATION_OK; @@ -1267,7 +1258,6 @@ get_trusted_ca_list ( const char* trusted_ca_dir, DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_TRUSTED_CA_DIR_CODE, 0, DDS_SECURITY_ERR_INVALID_TRUSTED_CA_DIR_MESSAGE); return DDS_SECURITY_VALIDATION_FAILED; } -#endif return loading_result; } diff --git a/src/security/builtin_plugins/authentication/src/authentication.c b/src/security/builtin_plugins/authentication/src/authentication.c index dada4db..a3d5ea7 100644 --- a/src/security/builtin_plugins/authentication/src/authentication.c +++ b/src/security/builtin_plugins/authentication/src/authentication.c @@ -22,6 +22,7 @@ #include "authentication.h" #include "dds/ddsrt/heap.h" #include "dds/security/dds_security_api.h" +#include "dds/security/core/dds_security_timed_cb.h" #if OPENSLL_VERSION_NUMBER >= 0x10002000L @@ -202,7 +203,8 @@ typedef struct dds_security_authentication_impl { ddsrt_mutex_t lock; struct ddsrt_hh *objectHash; struct ddsrt_hh *remoteGuidHash; - struct ut_timed_dispatcher_t *timed_callbacks; + struct dds_security_timed_cb_data *timed_callbacks; + struct dds_security_timed_dispatcher_t *dispatcher; X509Seq trustedCAList; @@ -844,22 +846,19 @@ hash_value_to_binary_property( return bp; } - -/* Will be enabled after timed callback feature implementation */ -#if TIMED_CALLBACK_IMPLEMENTED - static void -validity_callback(struct ut_timed_dispatcher_t *d, - ut_timed_cb_kind kind, +validity_callback(struct dds_security_timed_dispatcher_t *d, + dds_security_timed_cb_kind kind, void *listener, void *arg) { validity_cb_info *info = arg; + DDSRT_UNUSED_ARG(d); assert(d); assert(arg); - if (kind == UT_TIMED_CB_KIND_TIMEOUT) { + if (kind == DDS_SECURITY_TIMED_CB_KIND_TIMEOUT) { assert(listener); dds_security_authentication_listener *auth_listener = (dds_security_authentication_listener*)listener; if (auth_listener->on_revoke_identity) { @@ -872,26 +871,19 @@ validity_callback(struct ut_timed_dispatcher_t *d, ddsrt_free(arg); } -#endif static void add_validity_end_trigger(dds_security_authentication_impl *auth, const DDS_Security_IdentityHandle identity_handle, dds_time_t end) { - DDSRT_UNUSED_ARG( auth ); - DDSRT_UNUSED_ARG( identity_handle ); - DDSRT_UNUSED_ARG( end ); - /* Will be enabled after timed call back feature implementation */ - /* validity_cb_info *arg = ddsrt_malloc(sizeof(validity_cb_info)); arg->auth = auth; arg->hdl = identity_handle; - ut_timed_dispatcher_add(auth->timed_callbacks, + dds_security_timed_dispatcher_add(auth->timed_callbacks, auth->dispatcher, validity_callback, end, (void*)arg); - */ } @@ -3170,18 +3162,14 @@ DDS_Security_boolean set_listener(dds_security_authentication *instance, { dds_security_authentication_impl *auth = (dds_security_authentication_impl*)instance; - DDSRT_UNUSED_ARG(auth); - DDSRT_UNUSED_ARG(listener); DDSRT_UNUSED_ARG(ex); - /* Will be enabled after timed call back feature implementation */ -#if TIMED_CALLBACK_IMPLEMENTED if (listener) { - ut_timed_dispatcher_enable(auth->timed_callbacks, (void*)listener); + dds_security_timed_dispatcher_enable(auth->timed_callbacks, auth->dispatcher, (void*)listener); } else { - ut_timed_dispatcher_disable(auth->timed_callbacks); + dds_security_timed_dispatcher_disable(auth->timed_callbacks, auth->dispatcher); } -#endif + return true; } @@ -3398,8 +3386,8 @@ init_authentication( const char *argument, void **context) memset(authentication, 0, sizeof(dds_security_authentication_impl)); /* assign dispatcher to be notified when a validity date ends */ - /* Disable it until timed callback is ready */ - /*authentication->timed_callbacks = ut_timed_dispatcher_new(); */ + authentication->timed_callbacks = dds_security_timed_cb_new(); + authentication->dispatcher = dds_security_timed_dispatcher_new(authentication->timed_callbacks); /* assign the interface functions */ authentication->base.validate_local_identity = &validate_local_identity; @@ -3474,8 +3462,9 @@ int32_t finalize_authentication(void *instance) if( authentication ){ ddsrt_mutex_lock(&authentication->lock); - /* Will be enabled after timed call back feature implementation */ - /* ut_timed_dispatcher_free(authentication->timed_callbacks); */ + dds_security_timed_dispatcher_free(authentication->timed_callbacks, authentication->dispatcher); + dds_security_timed_cb_free(authentication->timed_callbacks); + if (authentication->remoteGuidHash) { ddsrt_hh_free(authentication->remoteGuidHash); } diff --git a/src/security/builtin_plugins/tests/CMakeLists.txt b/src/security/builtin_plugins/tests/CMakeLists.txt index d822524..ac56a7f 100644 --- a/src/security/builtin_plugins/tests/CMakeLists.txt +++ b/src/security/builtin_plugins/tests/CMakeLists.txt @@ -21,6 +21,8 @@ set(security_auth_test_sources "validate_begin_handshake_request/src/validate_begin_handshake_request_utests.c" "validate_local_identity/src/validate_local_identity_utests.c" "validate_remote_identity/src/validate_remote_identity_utests.c" + "listeners_authentication/src/listeners_authentication_utests.c" + "listeners_access_control/src/listeners_access_control_utests.c" ) set(security_ac_test_sources @@ -74,6 +76,7 @@ if(OPENSSL_FOUND) target_link_libraries(cunit_security_plugins PRIVATE ddsc dds_security_ac) target_link_libraries(cunit_security_plugins PRIVATE ddsc dds_security_crypto) target_link_libraries(cunit_security_plugins PRIVATE OpenSSL::SSL) + else() message(FATAL_ERROR "To build with openssl support, set ENABLE_OPENSSL to ON") endif() @@ -92,5 +95,8 @@ target_include_directories( set(CUnit_builtin_plugins_tests_dir "${CMAKE_CURRENT_LIST_DIR}") +set(CUnit_build_dir "${CMAKE_CURRENT_BINARY_DIR}") configure_file("config_env.h.in" "config_env.h") + + diff --git a/src/security/builtin_plugins/tests/config_env.h.in b/src/security/builtin_plugins/tests/config_env.h.in index 3f2b23a..c22d1f5 100644 --- a/src/security/builtin_plugins/tests/config_env.h.in +++ b/src/security/builtin_plugins/tests/config_env.h.in @@ -13,5 +13,6 @@ #define CONFIG_ENV_H #define CONFIG_ENV_TESTS_DIR "@CUnit_builtin_plugins_tests_dir@" +#define CONFIG_ENV_BUILD_DIR "@CUnit_build_dir@" #endif /* CONFIG_ENV_H */ diff --git a/src/security/builtin_plugins/tests/listeners_access_control/etc/Test_Permissions_listener.p7s b/src/security/builtin_plugins/tests/listeners_access_control/etc/Test_Permissions_listener.p7s deleted file mode 100644 index 08434a9..0000000 --- a/src/security/builtin_plugins/tests/listeners_access_control/etc/Test_Permissions_listener.p7s +++ /dev/null @@ -1,51 +0,0 @@ -MIME-Version: 1.0 -Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----3900963D3572093F6AEC654A72CAEE5A" - -This is an S/MIME signed message - -------3900963D3572093F6AEC654A72CAEE5A -Content-Type: text/plain - - /C=NL/ST=Some-State/O=Internet Widgits Pty Ltd/CN=CHAM500 cert 2015-09-15T01:00:00 2019-11-18T11:48:49 0 230 * * DENY -------3900963D3572093F6AEC654A72CAEE5A -Content-Type: application/x-pkcs7-signature; name="smime.p7s" -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; filename="smime.p7s" - -MIIGSAYJKoZIhvcNAQcCoIIGOTCCBjUCAQExDzANBglghkgBZQMEAgEFADALBgkq -hkiG9w0BBwGgggORMIIDjTCCAnWgAwIBAgIJANsr3sm0NrypMA0GCSqGSIb3DQEB -CwUAMFwxCzAJBgNVBAYTAk5MMRMwEQYDVQQIDApTb21lLVN0YXRlMR8wHQYDVQQK -DBZBRExJTksgVGVjaG5vbG9jeSBJbmMuMRcwFQYDVQQDDA5hZGxpbmt0ZWNoLmNv -bTAgFw0xODA3MzAxMjQ1NTVaGA8yMTE4MDcwNjEyNDU1NVowXDELMAkGA1UEBhMC -TkwxEzARBgNVBAgMClNvbWUtU3RhdGUxHzAdBgNVBAoMFkFETElOSyBUZWNobm9s -b2N5IEluYy4xFzAVBgNVBAMMDmFkbGlua3RlY2guY29tMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAu7jfnJ0wYVuXgG+PgNawdN38+dRpa8jceqi+blID -ehV6XCxrnGXusTCDuFmo7HMOBVMVNDXlcBWgoGd+u5EultnOEiIeGTgtHc1O6V9w -icp3BGSpZZax/TcONjMVORaqHCADbQ2J8wsz1FHxuKDwX6BJElYOlK77lb/x3yLs -DFFC+a0qn2RFh37rcWBRAHy8VEASXKZElT9ZmfKd+KUq34KojhNJ4DepKStTq074 -BRDXVivx+wVD951LFNPiQXq+mgHcLj1k37KlZflTFhdP5oEMtATNsXNJPHlEymiy -SogRWAmKhysLQudukHfNKN+r0FEQMk/hzpYcFeZSOvbfNQIDAQABo1AwTjAdBgNV -HQ4EFgQURWMbWvBKZwJvRV1/tyc1R82k0+gwHwYDVR0jBBgwFoAURWMbWvBKZwJv -RV1/tyc1R82k0+gwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAkPF+ -ysVtvHnk2hpu9yNDLCJ96ZzIoKOyY7uRj4ovzlAHFdpNOJQdcJihTmN8i7Trht9X -Vh0rGoR/6nHzo3TIeiogRC80RlDtuA3PF2dDQBMVDStlZMTZPb693hfjdAjhyyw9 -yghhKHHqNDvSsAL0KfBqjG4yGfGpJylYXIT5fWuKlo/ln/yyPa5s54T5XDo+CMbt -lLX3QnwVOmaRyzylPiTcPCDIkdLBdXmlfyJcmW6fWa6kPx+35MOxPsXZbujCo+42 -+OyLqcH1rKT6XhcshjXBEf+kdgUfSClrM1pNRWsw2ChIYim0F+nry5JFy0Y+8Hbb -6SDB340BFmtgDHbFHTGCAnswggJ3AgEBMGkwXDELMAkGA1UEBhMCTkwxEzARBgNV -BAgMClNvbWUtU3RhdGUxHzAdBgNVBAoMFkFETElOSyBUZWNobm9sb2N5IEluYy4x -FzAVBgNVBAMMDmFkbGlua3RlY2guY29tAgkA2yveybQ2vKkwDQYJYIZIAWUDBAIB -BQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcN -MTkxMTE4MTE0ODQ4WjAvBgkqhkiG9w0BCQQxIgQgaLNNlFwfVR0PrziT9wCAy5bM -qCZJX9yO3xJgut3/o7EweQYJKoZIhvcNAQkPMWwwajALBglghkgBZQMEASowCwYJ -YIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgIC -AIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZI -hvcNAQEBBQAEggEAWCFrUIvdYKBeT0lmpkRdmYJuvdmQ/Ro7k9iyreVofpB1/70B -hVOEeRjrlmhv/TUjSgQyli56wmXFmexcNRzSzpPNycz0gjwP9kX5BMnhAkKd08fC -4rgoirScmNxvxEkj5+wyq7s7rBEJOgVQ9ofwiZXEBVDMVvW2ENZhVF3FyoNulDQe -6BjXkuLw/QrJLWjywPy5naSSda2T7V3+Ssdu5/2vEjXPIJMM+xPOCaqGHJsSb72s -KiP48jZ95Wruvj3QAlpGxDaazWPTgn7tfThYrY3Kgiz5zyZM7FhFyIqxRF/89Ngo -hbu2mWzcXFF7wBLy+CvK5Foajro9t/PzD8uNuA== - -------3900963D3572093F6AEC654A72CAEE5A-- - diff --git a/src/security/builtin_plugins/tests/listeners_access_control/src/listeners_access_control_utests.c b/src/security/builtin_plugins/tests/listeners_access_control/src/listeners_access_control_utests.c index 5f32d09..f215738 100644 --- a/src/security/builtin_plugins/tests/listeners_access_control/src/listeners_access_control_utests.c +++ b/src/security/builtin_plugins/tests/listeners_access_control/src/listeners_access_control_utests.c @@ -215,6 +215,7 @@ static DDS_Security_PermissionsHandle local_permissions_handle = DDS_SECURITY_HA static DDS_Security_PermissionsHandle remote_permissions_handle = DDS_SECURITY_HANDLE_NIL; static DDS_Security_GUID_t local_participant_guid; static char *g_path_to_etc_dir = NULL; +static char *g_path_build_dir = NULL; static DDS_Security_PermissionsHandle permission_handle_for_callback1 = DDS_SECURITY_HANDLE_NIL; static DDS_Security_PermissionsHandle permission_handle_for_callback2 = DDS_SECURITY_HANDLE_NIL; static dds_time_t local_expiry_date; @@ -251,14 +252,16 @@ static void reset_exception(DDS_Security_SecurityException *ex) static void get_future_xsdate(char *str, size_t len, int32_t delta) { time_t rawtime; - struct tm *future; + struct tm *future = ddsrt_malloc(sizeof(struct tm)); /* Get future time. */ rawtime = time(NULL) + delta; - future = gmtime(&rawtime); + OPENSSL_gmtime(&rawtime, future); /* Put the future time in a xsDate format. */ strftime(str, len, "%Y-%m-%dT%H:%M:%S", future); + + ddsrt_free(future); } static int smime_sign(const char *certificate_file, const char *key_file, const char *data, const char *out_file) @@ -345,7 +348,7 @@ static void fill_participant_qos(DDS_Security_Qos *qos, int32_t permission_expir ddsrt_asprintf(&permissions_ca_cert_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_CA_CERT_FILE); ddsrt_asprintf(&permissions_ca_key_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_CA_KEY_FILE); - ddsrt_asprintf(&permissions_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_FILE); + ddsrt_asprintf(&permissions_file, "%s%s", g_path_build_dir, PERMISSIONS_FILE); smime_sign(permissions_ca_cert_file, permissions_ca_key_file, permissions_xml_with_expiry, permissions_file); @@ -407,9 +410,9 @@ static int fill_peer_credential_token(DDS_Security_AuthenticatedPeerCredentialTo remote_expiry_date = DDS_Security_parse_xml_date(permission_expiry_date_str); permissions_xml_with_expiry = ddsrt_str_replace(PERMISSIONS_DOCUMENT, "PERMISSION_EXPIRY_DATE", permission_expiry_date_str, 1); - ddsrt_asprintf(permissions_ca_cert_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_CA_CERT_FILE); - ddsrt_asprintf(permissions_ca_key_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_CA_KEY_FILE); - ddsrt_asprintf(permissions_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_FILE); + ddsrt_asprintf(&permissions_ca_cert_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_CA_CERT_FILE); + ddsrt_asprintf(&permissions_ca_key_file, "%s%s", g_path_to_etc_dir, PERMISSIONS_CA_KEY_FILE); + ddsrt_asprintf(&permissions_file, "%s%s", g_path_build_dir, PERMISSIONS_FILE); smime_sign(permissions_ca_cert_file, permissions_ca_key_file, permissions_xml_with_expiry, permissions_file); @@ -531,17 +534,29 @@ static void set_path_to_etc_dir(void) { ddsrt_asprintf(&g_path_to_etc_dir, "%s%s", CONFIG_ENV_TESTS_DIR, RELATIVE_PATH_TO_ETC_DIR); } - -static void suite_listeners_access_control_init(void) +static void set_path_build_dir(void) { - plugins = load_plugins(&access_control, &auth, NULL /* Cryptograpy */); - CU_ASSERT_FATAL(plugins != NULL); - set_path_to_etc_dir(); - OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); + ddsrt_asprintf(&g_path_build_dir, "%s/", CONFIG_ENV_BUILD_DIR); } -static void suite_listeners_access_control_fini(void) +CU_Init(ddssec_builtin_listeners_access_control) +{ + int res = 0; + + plugins = load_plugins(&access_control, &auth, NULL /* Cryptograpy */); + if (!plugins) { + res = -1; + } else { + set_path_to_etc_dir(); + set_path_build_dir(); + OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); + } + + return res; +} + +CU_Clean(ddssec_builtin_listeners_access_control) { unload_plugins(plugins); ddsrt_free(g_path_to_etc_dir); @@ -549,6 +564,8 @@ static void suite_listeners_access_control_fini(void) CRYPTO_cleanup_all_ex_data(); REMOVE_THREAD_STATE(); ERR_free_strings(); + + return 0; } static DDS_Security_boolean on_revoke_permissions_cb(dds_security_access_control_listener *instance, const dds_security_access_control *plugin, const DDS_Security_PermissionsHandle handle) @@ -559,11 +576,11 @@ static DDS_Security_boolean on_revoke_permissions_cb(dds_security_access_control permission_handle_for_callback1 = handle; else if (permission_handle_for_callback2 == DDS_SECURITY_HANDLE_NIL) permission_handle_for_callback2 = handle; - printf("Listener called for handle: %lld Local:%ld Remote:%ld\n", (long long)handle, local_permissions_handle, remote_permissions_handle); + printf("Listener called for handle: %lld Local:%lld Remote:%lld\n", (long long)handle, (long long)local_permissions_handle, (long long)remote_permissions_handle); return true; } -CU_Test(ddssec_builtin_listeners_access_control, local_2secs, .init = suite_listeners_access_control_init, .fini = suite_listeners_access_control_fini) +CU_Test(ddssec_builtin_listeners_access_control, local_2secs) { DDS_Security_PermissionsHandle result; DDS_Security_PermissionsToken permissions_token; diff --git a/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Governance.p7s b/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Governance.p7s new file mode 100644 index 0000000..8c6aae5 --- /dev/null +++ b/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Governance.p7s @@ -0,0 +1,120 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----8F2D5CA80FE8B4509AF031712E008F0E" + +This is an S/MIME signed message + +------8F2D5CA80FE8B4509AF031712E008F0E +Content-Type: text/plain + + + + + + + + + 0 + 230 + + + + + true + + + true + + + ENCRYPT + + + ENCRYPT + + + ENCRYPT + + + + + * + + + true + + + true + + + true + + + true + + + ENCRYPT + + + ENCRYPT + + + + + + +------8F2D5CA80FE8B4509AF031712E008F0E +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIHiwYJKoZIhvcNAQcCoIIHfDCCB3gCAQExDzANBglghkgBZQMEAgEFADALBgkq +hkiG9w0BBwGgggRnMIIEYzCCA0ugAwIBAgIJAM3yAtULcaEIMA0GCSqGSIb3DQEB +CwUAMIHHMQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2Fs +aXR5IE5hbWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4G +A1UECgwXRXhhbXBsZSBDQSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUg +UGVybWlzc2lvbnMgQ0ExLTArBgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNz +aW9uc2NhbHRkLm9yZzAeFw0xOTAyMTIxMzUyMzJaFw0yOTAyMDkxMzUyMzJaMIHH +MQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5h +bWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4GA1UECgwX +RXhhbXBsZSBDQSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUgUGVybWlz +c2lvbnMgQ0ExLTArBgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNzaW9uc2Nh +bHRkLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKD6nYCszMha +h3xGfJy8f3lowPHIj6zcldVYs5Krg7zXxZn+20lAMHUfgQcWZAauKbCnokYfTvXV +v0j9HCpQ3mRynNTyjLjc7HxAe6kfaJ75PoIoOMMQMEGvPOqRUq0tomVVJvcgzZZk +pwE30E6xvZrlQcrkQY/aOQ0sbje+RN8RKQ9vf6O45Np/0m2K5ohZPlBqg4F539v2 +iXGZczCr9AqAszc/7rOPX1aqZmmRDou0T+Zhx3ZZSAwZYQtr7uvvlUeGmDhNh+8p +LC+1FQPtkKmcVXO8oZWm5N8piOvH3M+v3qhyPtLv30cpl0bDiFl+PN7nZ6InOOtd +ZJVMa2rYCk8CAwEAAaNQME4wHQYDVR0OBBYEFA/CtiP8Z5Fk4aWDIb2j3FPwh9pg +MB8GA1UdIwQYMBaAFA/CtiP8Z5Fk4aWDIb2j3FPwh9pgMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBACBupRddIR9zYBFLGFTzeiW+H1tRRKz+B3SWnCJH +89ijEdMYlKKLYT0R18lCV0vHnl29bU1CPlkLn+GQkvdfIjKguWEQKTP+GLzoa9TV +zOKAJ8NttCyW3YqriUOUGKqra1Fdt8nvrAyZUF+v/k8pTInmCvwu3l5HrVhkKHER +IbCIohKi/2mk1JZS9reWvZhqLoUIw5IDFlqtBDYOfMaqm8XF01YjEDBM6OuyQzYN +gDFVUZx0At4zzRjGTvqpLTkDYL1A3v4QYXZcwZiKeEVbFuNkauXgD+8pEZMB8yL4 +h1feIH+aucsAKBz1Ne5fTiTCannlKvLl8xWz5IdzP7gF0LIxggLoMIIC5AIBATCB +1TCBxzELMAkGA1UEBhMCTkwxCzAJBgNVBAgMAk9WMRYwFAYDVQQHDA1Mb2NhbGl0 +eSBOYW1lMSEwHwYDVQQLDBhPcmdhbml6YXRpb25hbCBVbml0IE5hbWUxIDAeBgNV +BAoMF0V4YW1wbGUgQ0EgT3JnYW5pemF0aW9uMR8wHQYDVQQDDBZFeGFtcGxlIFBl +cm1pc3Npb25zIENBMS0wKwYJKoZIhvcNAQkBFh5hdXRob3JpdHlAcGVybWlzc2lv +bnNjYWx0ZC5vcmcCCQDN8gLVC3GhCDANBglghkgBZQMEAgEFAKCB5DAYBgkqhkiG +9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xOTEyMDcxNjAxMjZa +MC8GCSqGSIb3DQEJBDEiBCCAw/IHksMBWVnBQEtBoPLvJ1B+9IvOrQ4OkihJ6q0v +ijB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglghkgBZQMEARYwCwYJ +YIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDANBggqhkiG9w0D +AgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG9w0BAQEFAASCAQAd +j3vO63v4bBbNhE0wZ8gWPHFfJsZO4JUu+ZzJ08hO1fku07Q13medyyp1+6jeZWoV +rCqQbG37xL1dx023wsRu+mYPSgEtIx2zBGW8ADk2qEIGAVPUPGUiVXl6+7esAmnP +AFDrt3Qp6nEZIr7iQ6i+4WW3kWM3o9C1ghSz4tVBjP9El5/yrux2mo5DTSeB8QMR +npMNgwgatwAxTwUrBpQj0FE5NUDm21OT1VwlUAGTHz6m5npw92p6qvQxFYufRzWj +XoADdJW0qgfbL00Gvoimi2K21cSUqiYcKU06eQeCkrLXyjif2JlFdKXvODwlydOy +dtwcKpPKVKgBI01+5Imf + +------8F2D5CA80FE8B4509AF031712E008F0E-- + diff --git a/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Alice.p7s b/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Alice.p7s new file mode 100644 index 0000000..1e19a63 --- /dev/null +++ b/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Alice.p7s @@ -0,0 +1,98 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----51AB97062CF028E6EBDDAA31699954BC" + +This is an S/MIME signed message + +------51AB97062CF028E6EBDDAA31699954BC +Content-Type: text/plain + + + + + + /C=NL/ST=OV/L=Locality Name/OU=Organizational Unit Name/O=Example Organization/CN=Alice Example/emailAddress=alice@exampleltd.com + + + 2015-09-15T01:00:00 + 2115-09-15T01:00:00 + + + + + 0 + 230 + + + + + * + + + * + + + + + * + + + * + + + + + DENY + + + + +------51AB97062CF028E6EBDDAA31699954BC +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIHiwYJKoZIhvcNAQcCoIIHfDCCB3gCAQExDzANBglghkgBZQMEAgEFADALBgkq +hkiG9w0BBwGgggRnMIIEYzCCA0ugAwIBAgIJAM3yAtULcaEIMA0GCSqGSIb3DQEB +CwUAMIHHMQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2Fs +aXR5IE5hbWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4G +A1UECgwXRXhhbXBsZSBDQSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUg +UGVybWlzc2lvbnMgQ0ExLTArBgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNz +aW9uc2NhbHRkLm9yZzAeFw0xOTAyMTIxMzUyMzJaFw0yOTAyMDkxMzUyMzJaMIHH +MQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5h +bWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4GA1UECgwX +RXhhbXBsZSBDQSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUgUGVybWlz +c2lvbnMgQ0ExLTArBgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNzaW9uc2Nh +bHRkLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKD6nYCszMha +h3xGfJy8f3lowPHIj6zcldVYs5Krg7zXxZn+20lAMHUfgQcWZAauKbCnokYfTvXV +v0j9HCpQ3mRynNTyjLjc7HxAe6kfaJ75PoIoOMMQMEGvPOqRUq0tomVVJvcgzZZk +pwE30E6xvZrlQcrkQY/aOQ0sbje+RN8RKQ9vf6O45Np/0m2K5ohZPlBqg4F539v2 +iXGZczCr9AqAszc/7rOPX1aqZmmRDou0T+Zhx3ZZSAwZYQtr7uvvlUeGmDhNh+8p +LC+1FQPtkKmcVXO8oZWm5N8piOvH3M+v3qhyPtLv30cpl0bDiFl+PN7nZ6InOOtd +ZJVMa2rYCk8CAwEAAaNQME4wHQYDVR0OBBYEFA/CtiP8Z5Fk4aWDIb2j3FPwh9pg +MB8GA1UdIwQYMBaAFA/CtiP8Z5Fk4aWDIb2j3FPwh9pgMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBACBupRddIR9zYBFLGFTzeiW+H1tRRKz+B3SWnCJH +89ijEdMYlKKLYT0R18lCV0vHnl29bU1CPlkLn+GQkvdfIjKguWEQKTP+GLzoa9TV +zOKAJ8NttCyW3YqriUOUGKqra1Fdt8nvrAyZUF+v/k8pTInmCvwu3l5HrVhkKHER +IbCIohKi/2mk1JZS9reWvZhqLoUIw5IDFlqtBDYOfMaqm8XF01YjEDBM6OuyQzYN +gDFVUZx0At4zzRjGTvqpLTkDYL1A3v4QYXZcwZiKeEVbFuNkauXgD+8pEZMB8yL4 +h1feIH+aucsAKBz1Ne5fTiTCannlKvLl8xWz5IdzP7gF0LIxggLoMIIC5AIBATCB +1TCBxzELMAkGA1UEBhMCTkwxCzAJBgNVBAgMAk9WMRYwFAYDVQQHDA1Mb2NhbGl0 +eSBOYW1lMSEwHwYDVQQLDBhPcmdhbml6YXRpb25hbCBVbml0IE5hbWUxIDAeBgNV +BAoMF0V4YW1wbGUgQ0EgT3JnYW5pemF0aW9uMR8wHQYDVQQDDBZFeGFtcGxlIFBl +cm1pc3Npb25zIENBMS0wKwYJKoZIhvcNAQkBFh5hdXRob3JpdHlAcGVybWlzc2lv +bnNjYWx0ZC5vcmcCCQDN8gLVC3GhCDANBglghkgBZQMEAgEFAKCB5DAYBgkqhkiG +9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xOTEyMDcxNjAxMjZa +MC8GCSqGSIb3DQEJBDEiBCAX5wSM0Og83gWKRmru9iCOm8h85e9oZ7rBebmSbLVN +1TB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglghkgBZQMEARYwCwYJ +YIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDANBggqhkiG9w0D +AgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG9w0BAQEFAASCAQAT +QZbljrtQs/FcBUJBYoenquAQ5++twy5LE6A06dASaHFDxSxPsAe0KBl9EWJzE59X +4k73u+4bJZiuLHUPztuXIUt3gEKM72DDT+ET/13dWdM2vtITW6HZ27nvkngE35cc +kdUqkLyeM5dzsSDpr3Ba8epulThlwl7bw9dUd2FUOBCc266da+q1lcChjwfC5GBu +GB7oWODhSAk6L9dici8w5q9ybygBkFJHXTZVtsXQWuNmDtXWB2ury++WQlvtNK0s +aF+dtQlyEx2vvi5tV195vncAt514uHJ9optdEbaIyMo51G53QD0Cq62QhuFusug0 +nz2pgcEZ35JCd4gESMkL + +------51AB97062CF028E6EBDDAA31699954BC-- + diff --git a/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Bob.p7s b/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Bob.p7s new file mode 100644 index 0000000..f5ab923 --- /dev/null +++ b/src/security/builtin_plugins/tests/listeners_authentication/etc/Example_Permissions_Bob.p7s @@ -0,0 +1,98 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----EDFB3CE1089204FED046E2D32968C669" + +This is an S/MIME signed message + +------EDFB3CE1089204FED046E2D32968C669 +Content-Type: text/plain + + + + + + /C=NL/ST=OV/L=Locality Name/OU=Organizational Unit Name/O=Example Organization/CN=Bob Example/emailAddress=bob@exampleltd.com + + + 2015-09-15T01:00:00 + 2115-09-15T01:00:00 + + + + + 0 + 230 + + + + + * + + + * + + + + + * + + + * + + + + + DENY + + + + +------EDFB3CE1089204FED046E2D32968C669 +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIHiwYJKoZIhvcNAQcCoIIHfDCCB3gCAQExDzANBglghkgBZQMEAgEFADALBgkq +hkiG9w0BBwGgggRnMIIEYzCCA0ugAwIBAgIJAM3yAtULcaEIMA0GCSqGSIb3DQEB +CwUAMIHHMQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2Fs +aXR5IE5hbWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4G +A1UECgwXRXhhbXBsZSBDQSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUg +UGVybWlzc2lvbnMgQ0ExLTArBgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNz +aW9uc2NhbHRkLm9yZzAeFw0xOTAyMTIxMzUyMzJaFw0yOTAyMDkxMzUyMzJaMIHH +MQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5h +bWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4GA1UECgwX +RXhhbXBsZSBDQSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUgUGVybWlz +c2lvbnMgQ0ExLTArBgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNzaW9uc2Nh +bHRkLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKD6nYCszMha +h3xGfJy8f3lowPHIj6zcldVYs5Krg7zXxZn+20lAMHUfgQcWZAauKbCnokYfTvXV +v0j9HCpQ3mRynNTyjLjc7HxAe6kfaJ75PoIoOMMQMEGvPOqRUq0tomVVJvcgzZZk +pwE30E6xvZrlQcrkQY/aOQ0sbje+RN8RKQ9vf6O45Np/0m2K5ohZPlBqg4F539v2 +iXGZczCr9AqAszc/7rOPX1aqZmmRDou0T+Zhx3ZZSAwZYQtr7uvvlUeGmDhNh+8p +LC+1FQPtkKmcVXO8oZWm5N8piOvH3M+v3qhyPtLv30cpl0bDiFl+PN7nZ6InOOtd +ZJVMa2rYCk8CAwEAAaNQME4wHQYDVR0OBBYEFA/CtiP8Z5Fk4aWDIb2j3FPwh9pg +MB8GA1UdIwQYMBaAFA/CtiP8Z5Fk4aWDIb2j3FPwh9pgMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBACBupRddIR9zYBFLGFTzeiW+H1tRRKz+B3SWnCJH +89ijEdMYlKKLYT0R18lCV0vHnl29bU1CPlkLn+GQkvdfIjKguWEQKTP+GLzoa9TV +zOKAJ8NttCyW3YqriUOUGKqra1Fdt8nvrAyZUF+v/k8pTInmCvwu3l5HrVhkKHER +IbCIohKi/2mk1JZS9reWvZhqLoUIw5IDFlqtBDYOfMaqm8XF01YjEDBM6OuyQzYN +gDFVUZx0At4zzRjGTvqpLTkDYL1A3v4QYXZcwZiKeEVbFuNkauXgD+8pEZMB8yL4 +h1feIH+aucsAKBz1Ne5fTiTCannlKvLl8xWz5IdzP7gF0LIxggLoMIIC5AIBATCB +1TCBxzELMAkGA1UEBhMCTkwxCzAJBgNVBAgMAk9WMRYwFAYDVQQHDA1Mb2NhbGl0 +eSBOYW1lMSEwHwYDVQQLDBhPcmdhbml6YXRpb25hbCBVbml0IE5hbWUxIDAeBgNV +BAoMF0V4YW1wbGUgQ0EgT3JnYW5pemF0aW9uMR8wHQYDVQQDDBZFeGFtcGxlIFBl +cm1pc3Npb25zIENBMS0wKwYJKoZIhvcNAQkBFh5hdXRob3JpdHlAcGVybWlzc2lv +bnNjYWx0ZC5vcmcCCQDN8gLVC3GhCDANBglghkgBZQMEAgEFAKCB5DAYBgkqhkiG +9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xOTEyMDcxNjAxMjZa +MC8GCSqGSIb3DQEJBDEiBCCEqUh7CpMRXpSMDeuCmSMz+I6WXjXpO2HRkCdRSczj +1TB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglghkgBZQMEARYwCwYJ +YIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDANBggqhkiG9w0D +AgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG9w0BAQEFAASCAQAL +ExoTydhBE/8GgnqGp39cRVQ0Z1YIc55uACZK1V37R2b8rY4upLA7iHyzCBXQOwCz +mhjHfaNdW8twWru34EvD17RTfk49Lvmge4ceipgmqKwGVyTO57P5xzDaC+2F2KEi ++s6/YWIslixMhlQyuxZsmQDbRWcmQ1FRy7LJ80cctlDA44IviaEfv/u2+sqJgPNL +Z5AHMEv/qceKjtm/Wh7sdFhjfM4ZnfUWFB6Ni/sdNSmO9O3j9OHfpkzMJHxM4B5r +G5pMNDn2xibxwlx41he7mfENIjuk4Z3VDaTCTs++8GyivvvsCZSVimd0iuI1kVmd +JL58DFeKqgEZ358rN9/5 + +------EDFB3CE1089204FED046E2D32968C669-- + diff --git a/src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Cert.pem b/src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Cert.pem new file mode 100644 index 0000000..cce5c91 --- /dev/null +++ b/src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEOTCCAyGgAwIBAgIJAPq0b61+PT2WMA0GCSqGSIb3DQEBCwUAMIGyMQswCQYD +VQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5hbWUxITAf +BgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEaMBgGA1UECgwRRXhhbXBs +ZSBTaWduZXIgQ0ExEzARBgNVBAMMCkV4YW1wbGUgQ0ExKjAoBgkqhkiG9w0BCQEW +G2F1dGhvcml0eUBpZGVudGl0eWNhbHRkLm9yZzAeFw0xOTAyMTIxMDIxNTJaFw0y +OTAyMDkxMDIxNTJaMIGyMQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNV +BAcMDUxvY2FsaXR5IE5hbWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQg +TmFtZTEaMBgGA1UECgwRRXhhbXBsZSBTaWduZXIgQ0ExEzARBgNVBAMMCkV4YW1w +bGUgQ0ExKjAoBgkqhkiG9w0BCQEWG2F1dGhvcml0eUBpZGVudGl0eWNhbHRkLm9y +ZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKCBJ1r/2AcSHorpA2G2 +WR0CvGHPhhY2x93twW91LCJVOVzO0LuOscZXSkWDtAhyhy1EZN6r+4aLbMku/wVJ +kdjHPD+WSVEZn70LxYSgxiUwXalpa5RQeTkEHll5cSgtE8kSD4/HIxBsbwizeDVV +g8SWpBVb044GM4O3TDbCug9F7GJFzqcbSHQZnHO+3nWu6f21BEU7PZjrFox1NREN +g3H7WmNISx4DOK9bJcWS/i4qJjTxjQPPFmzGvRgO2FfWP+xYb70x/iOeKsML2y+d +XZqL99yzfP1dnpDtBzCTqJJizfuNMD6gvIXyk2PUy3FpAYoI9BvUehdWCP/okikx +5jsCAwEAAaNQME4wHQYDVR0OBBYEFL7LTHLvMsEeUDjMYeW4+DcXn62PMB8GA1Ud +IwQYMBaAFL7LTHLvMsEeUDjMYeW4+DcXn62PMAwGA1UdEwQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAIDJ4g6aVGIVXDSQ5R2yY9I82zsRf3k+yRF/BBkqBP1XXYRA +6lk7Wk4y6+DmL9qbVG/xrkTCC066J8kVblOyfFP1LHAzlNOQE7aU+tyrAufW4fpz +f/Gv8PBQUTQGr8vNqLUuEdoQjzARm8g7L3qeXhIKjiWsWi99ibnm/jTjol1GleIX +RudKSSGyMcB2VgRjCEEIYrkXdkIfrznKcJxzUw3dsGx277dB+4iFLcqf1YDpoRe2 +aSwbtgx+lLZ4KXWtikBSmLSRBq9j2aGtKO08kru0U3jQo6B4Bvzp1KuJCBiktueY +yNRfgh8ggNERYF/SpVr/ivm3RM+mnWd3QpmVolw= +-----END CERTIFICATE----- diff --git a/src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Private_Key.pem b/src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Private_Key.pem new file mode 100644 index 0000000..16bfbf7 --- /dev/null +++ b/src/security/builtin_plugins/tests/listeners_authentication/etc/Identity_CA_Private_Key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAoIEnWv/YBxIeiukDYbZZHQK8Yc+GFjbH3e3Bb3UsIlU5XM7Q +u46xxldKRYO0CHKHLURk3qv7hotsyS7/BUmR2Mc8P5ZJURmfvQvFhKDGJTBdqWlr +lFB5OQQeWXlxKC0TyRIPj8cjEGxvCLN4NVWDxJakFVvTjgYzg7dMNsK6D0XsYkXO +pxtIdBmcc77eda7p/bUERTs9mOsWjHU1EQ2DcftaY0hLHgM4r1slxZL+LiomNPGN +A88WbMa9GA7YV9Y/7FhvvTH+I54qwwvbL51dmov33LN8/V2ekO0HMJOokmLN+40w +PqC8hfKTY9TLcWkBigj0G9R6F1YI/+iSKTHmOwIDAQABAoIBAAc5iRH5jjnTQPiz +wGk3kg9SPjSQ6NI7KQf+WcSwm4n4GBrrXE31AF+TMk6qvQHcVeVdvMShLTNDN2Re +7y/Hvf7qCPY7x5UU+DHEQ+HSctjdsnmbuzHz5WEBpHQWmVdboBZe78BjEFr+5oiX +u4N7E/FXbo9fkMhF0y/MomucnE9vnhFsCj/Qz+gqKJDz7n+jY1G9loGJpoZoGllK +s2+HzbY5qVKrrpDzD5FO5i+M/Obk4uwZVDSnFL316SKe9MzdlrH9ochdtsGlver8 +YsYtetqHy4QgE/WZLSgwQoYY7nlKnkAKUnGvTJ8pnmO2FkO9SAQsBIl32rURMQFY +2C7ka5ECgYEAz13hOWwsefCkMTpXOXpeagCACN86Oqel+gV+UYDWnRdwDrUKBhjA +u40+NVaxuJSNKV3mC0N2PxwTuYzQ6BOQgmNzlxv0xyKwkGW/d6F8VunV2mqb3EAL +m9qzN1k08V30RikSMCt1OV5isuUiC4ox3ToboLTibXKnbEFWjT3juM8CgYEAxiW0 ++CvqJQjrjJ/valshCQDF4fYLa2uTJcdDifyU3HVTn06yy0z42tLBhHCv8RY/SBRK +IqR3RDhYJbBgLhG7oBDvoGWUEhdGJ+z6qcw9v1tDj9QD1bQF7RJvuh2JA7mhbFe5 +cIptcDJNRN7PCrjqGksQfy8Gg6ABOGFhz3xZPtUCgYBeFpKio1pq2a0mSPpashM0 +tZVicSbShk7g6q0t/e9ix8eoZKxvp7uLXcLkILnyrjR+mIRQiAOXDv5EKoh/RKFF +CCriXWTrFepXGlONzE/Gf8Lwn36oqMabqNe4PVmwSpkTXH9MK+u8Y/8UfLK92a5W +Wo8+k9RJJMSiceL7oyE4MQKBgQCkVg2bbkCJaraBMPxNxzrEzsFPwNKDyvqFcJhR +TwzfMuehzpF3D2WthvI8t4EUgJEHZNx/ksvf5qMkzv1V+BsWjDVRYC3IO0lSP7c9 +MEld9YE5PmvXx7DKiGnlgC1sy35X7wG7lvNhBDcVkX1BtU9jczJBaW0LqZ6Zdhq7 +DLSv6QKBgQDNZpHEwi2P2LdlTRgbc4IWYjZZJaj+RrG881lgi+v8SI4E8eizlxLw +9HlG1nydvRqtU3T5h8UuqLOlXbfvQ7GOxVO2uJjtjJHZ8KbsFUH5i3UwZ+llyrRW +Y1ydvvE9Hux6I7I3L42J11jphNYKw/YwARkp8/Bc/wzKsGlnh3Oh+w== +-----END RSA PRIVATE KEY----- diff --git a/src/security/builtin_plugins/tests/listeners_authentication/etc/Permissions_CA_Cert.pem b/src/security/builtin_plugins/tests/listeners_authentication/etc/Permissions_CA_Cert.pem new file mode 100644 index 0000000..7420bc4 --- /dev/null +++ b/src/security/builtin_plugins/tests/listeners_authentication/etc/Permissions_CA_Cert.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIJAM3yAtULcaEIMA0GCSqGSIb3DQEBCwUAMIHHMQswCQYD +VQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5hbWUxITAf +BgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4GA1UECgwXRXhhbXBs +ZSBDQSBPcmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUgUGVybWlzc2lvbnMg +Q0ExLTArBgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNzaW9uc2NhbHRkLm9y +ZzAeFw0xOTAyMTIxMzUyMzJaFw0yOTAyMDkxMzUyMzJaMIHHMQswCQYDVQQGEwJO +TDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5hbWUxITAfBgNVBAsM +GE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEgMB4GA1UECgwXRXhhbXBsZSBDQSBP +cmdhbml6YXRpb24xHzAdBgNVBAMMFkV4YW1wbGUgUGVybWlzc2lvbnMgQ0ExLTAr +BgkqhkiG9w0BCQEWHmF1dGhvcml0eUBwZXJtaXNzaW9uc2NhbHRkLm9yZzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKD6nYCszMhah3xGfJy8f3lowPHI +j6zcldVYs5Krg7zXxZn+20lAMHUfgQcWZAauKbCnokYfTvXVv0j9HCpQ3mRynNTy +jLjc7HxAe6kfaJ75PoIoOMMQMEGvPOqRUq0tomVVJvcgzZZkpwE30E6xvZrlQcrk +QY/aOQ0sbje+RN8RKQ9vf6O45Np/0m2K5ohZPlBqg4F539v2iXGZczCr9AqAszc/ +7rOPX1aqZmmRDou0T+Zhx3ZZSAwZYQtr7uvvlUeGmDhNh+8pLC+1FQPtkKmcVXO8 +oZWm5N8piOvH3M+v3qhyPtLv30cpl0bDiFl+PN7nZ6InOOtdZJVMa2rYCk8CAwEA +AaNQME4wHQYDVR0OBBYEFA/CtiP8Z5Fk4aWDIb2j3FPwh9pgMB8GA1UdIwQYMBaA +FA/CtiP8Z5Fk4aWDIb2j3FPwh9pgMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACBupRddIR9zYBFLGFTzeiW+H1tRRKz+B3SWnCJH89ijEdMYlKKLYT0R +18lCV0vHnl29bU1CPlkLn+GQkvdfIjKguWEQKTP+GLzoa9TVzOKAJ8NttCyW3Yqr +iUOUGKqra1Fdt8nvrAyZUF+v/k8pTInmCvwu3l5HrVhkKHERIbCIohKi/2mk1JZS +9reWvZhqLoUIw5IDFlqtBDYOfMaqm8XF01YjEDBM6OuyQzYNgDFVUZx0At4zzRjG +TvqpLTkDYL1A3v4QYXZcwZiKeEVbFuNkauXgD+8pEZMB8yL4h1feIH+aucsAKBz1 +Ne5fTiTCannlKvLl8xWz5IdzP7gF0LI= +-----END CERTIFICATE----- diff --git a/src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c b/src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c new file mode 100644 index 0000000..a039d25 --- /dev/null +++ b/src/security/builtin_plugins/tests/listeners_authentication/src/listeners_authentication_utests.c @@ -0,0 +1,2105 @@ +/** @file qos_utests.c + * @brief Unit tests for qos APIs + * + */ +/* CUnit includes. */ +#include "CUnit/CUnit.h" +#include "CUnit/Test.h" + +#include + +/* Test helper includes. */ +#include "common/src/loader.h" + +#include "config_env.h" + +#include "dds/ddsrt/time.h" +#include "dds/security/dds_security_api.h" +#include "dds/security/dds_security_api_authentication.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/misc.h" +#include "dds/ddsrt/endian.h" +#include "dds/ddsrt/io.h" +#include "dds/security/core/dds_security_serialize.h" +#include "dds/security/core/dds_security_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if OPENSSL_VERSION_NUMBER >= 0x1000200fL +#define AUTH_INCLUDE_EC +#include +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#define AUTH_INCLUDE_DH_ACCESSORS +#endif +#else +#error "version not found" +#endif + + +static const char * ACCESS_PERMISSIONS_TOKEN_ID = "DDS:Access:Permissions:1.0"; +static const char * AUTH_PROTOCOL_CLASS_ID = "DDS:Auth:PKI-DH:1.0"; + +static const char * PROPERTY_IDENTITY_CA = "dds.sec.auth.identity_ca"; +static const char * PROPERTY_PRIVATE_KEY = "dds.sec.auth.private_key"; +static const char * PROPERTY_IDENTITY_CERT = "dds.sec.auth.identity_certificate"; +static const char * PROPERTY_PERMISSIONS_CA = "dds.sec.access.permissions_ca"; +static const char * PROPERTY_PERMISSIONS = "dds.sec.access.permissions"; +static const char * PROPERTY_GOVERNANCE = "dds.sec.access.governance"; + +static const char * PROPERTY_PERMISSIONS_CA_SN = "dds.perm_ca.sn"; +static const char * PROPERTY_PERMISSIONS_CA_ALGO = "dds.perm_ca.algo"; +static const char * PROPERTY_C_ID = "c.id"; +static const char * PROPERTY_C_PERM = "c.perm"; + + +static const char * SUBJECT_NAME_PERMISSIONS_CA = "/C=NL/ST=OV/L=Locality Name/OU=Organizational Unit Name/O=Example Signer CA/CN=Example CA/emailAddress=authority@identitycaltd.org"; +static const char * RSA_2048_ALGORITHM_NAME = "RSA-2048"; + +static const char * PERMISSIONS_CA_CERT_FILE = "Permissions_CA_Cert.pem"; +static const char * ALICE_PERMISSIONS_FILE = "Example_Permissions_Alice.p7s"; +static const char * BOB_PERMISSIONS_FILE = "Example_Permissions_Bob.p7s"; +static const char * ALICE_IDENTITY_CERT_FILE = "Example_Alice_Cert.pem"; +static const char * BOB_IDENTITY_CERT_FILE = "Example_Bob_Cert.pem"; +static const char * AUTH_DSIGN_ALGO_RSA_NAME = "RSASSA-PSS-SHA256"; +static const char * AUTH_KAGREE_ALGO_ECDH_NAME = "ECDH+prime256v1-CEUM"; +static DDS_Security_PermissionsHandle remote_permissions_handle = DDS_SECURITY_HANDLE_NIL; +static dds_security_authentication_listener auth_listener; +static dds_security_access_control_listener access_control_listener; + +#define IDENTITY_CA_FILE "Identity_CA_Cert.pem" +#define IDENTITY_CA_KEY_FILE "Identity_CA_Private_Key.pem" + +static const char *identity_ca =/*Identity_CA_Cert.pem*/ + "data:,-----BEGIN CERTIFICATE-----\n" + "MIIEOTCCAyGgAwIBAgIJAPq0b61+PT2WMA0GCSqGSIb3DQEBCwUAMIGyMQswCQYD\n" + "VQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNVBAcMDUxvY2FsaXR5IE5hbWUxITAf\n" + "BgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQgTmFtZTEaMBgGA1UECgwRRXhhbXBs\n" + "ZSBTaWduZXIgQ0ExEzARBgNVBAMMCkV4YW1wbGUgQ0ExKjAoBgkqhkiG9w0BCQEW\n" + "G2F1dGhvcml0eUBpZGVudGl0eWNhbHRkLm9yZzAeFw0xOTAyMTIxMDIxNTJaFw0y\n" + "OTAyMDkxMDIxNTJaMIGyMQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxFjAUBgNV\n" + "BAcMDUxvY2FsaXR5IE5hbWUxITAfBgNVBAsMGE9yZ2FuaXphdGlvbmFsIFVuaXQg\n" + "TmFtZTEaMBgGA1UECgwRRXhhbXBsZSBTaWduZXIgQ0ExEzARBgNVBAMMCkV4YW1w\n" + "bGUgQ0ExKjAoBgkqhkiG9w0BCQEWG2F1dGhvcml0eUBpZGVudGl0eWNhbHRkLm9y\n" + "ZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKCBJ1r/2AcSHorpA2G2\n" + "WR0CvGHPhhY2x93twW91LCJVOVzO0LuOscZXSkWDtAhyhy1EZN6r+4aLbMku/wVJ\n" + "kdjHPD+WSVEZn70LxYSgxiUwXalpa5RQeTkEHll5cSgtE8kSD4/HIxBsbwizeDVV\n" + "g8SWpBVb044GM4O3TDbCug9F7GJFzqcbSHQZnHO+3nWu6f21BEU7PZjrFox1NREN\n" + "g3H7WmNISx4DOK9bJcWS/i4qJjTxjQPPFmzGvRgO2FfWP+xYb70x/iOeKsML2y+d\n" + "XZqL99yzfP1dnpDtBzCTqJJizfuNMD6gvIXyk2PUy3FpAYoI9BvUehdWCP/okikx\n" + "5jsCAwEAAaNQME4wHQYDVR0OBBYEFL7LTHLvMsEeUDjMYeW4+DcXn62PMB8GA1Ud\n" + "IwQYMBaAFL7LTHLvMsEeUDjMYeW4+DcXn62PMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" + "hvcNAQELBQADggEBAIDJ4g6aVGIVXDSQ5R2yY9I82zsRf3k+yRF/BBkqBP1XXYRA\n" + "6lk7Wk4y6+DmL9qbVG/xrkTCC066J8kVblOyfFP1LHAzlNOQE7aU+tyrAufW4fpz\n" + "f/Gv8PBQUTQGr8vNqLUuEdoQjzARm8g7L3qeXhIKjiWsWi99ibnm/jTjol1GleIX\n" + "RudKSSGyMcB2VgRjCEEIYrkXdkIfrznKcJxzUw3dsGx277dB+4iFLcqf1YDpoRe2\n" + "aSwbtgx+lLZ4KXWtikBSmLSRBq9j2aGtKO08kru0U3jQo6B4Bvzp1KuJCBiktueY\n" + "yNRfgh8ggNERYF/SpVr/ivm3RM+mnWd3QpmVolw=\n" + "-----END CERTIFICATE-----\n"; + +static const char *alice_private_key = + "data:,-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEpAIBAAKCAQEA0Vn9YYllmrC/VVkxWFq6TzsmWn/niMydsE0hhm4Eam00gw3v\n" + "M4xScvBexI0td6tbStnWKz8vBiSVtWY1GDX8ICCBDufJcNIypu9L3DsjBoVTpcjx\n" + "XmfSpcxsepNaS7IqFPoRd+J+tzrl5qUR0Q52ObI02csp6CwecL8CvfXfc02U+tpP\n" + "b7iSsT/AcCeAAc10vdSXtnfcOGVLwy+D527kNr5r2VhE2FYdWbrGSOj8hw5eUfRs\n" + "KpnWlermWy1wzYfmMqkIII1hhY1sRDmMDrLpFeiYkf9B/7HQF+R2tFFFok1dYVpg\n" + "ZiZUNkONQnDQueThypzu3XB/PwHExILZnBwEtwIDAQABAoIBAHEVxCoQtuKlgOUQ\n" + "hfgtIiC0WdZe6unZZYCbWXWtLhNzI/964nAc51iRAQ/5Fstis7CuFONNgRA3aOsQ\n" + "57NJTgToqe4sRIL9+EB2WKsBAr19/Z46+i69tGq9DwfzWr4y4kpsfk0c+sftN8yr\n" + "9ADSaAhoe+X9uYhhdJwAgfGsw+Qa1BLM5jEexjcLwy1kqXwWKNHrPWU7NW40bPhV\n" + "Ne/UguklSp43sKoB1esTgRZe+OlQDCsQoXpyjtPYcKzF3Ion6e5rT8xQ1IkAtLTf\n" + "QJJTGMJGCguXxuDo2VRaa5pwbdRAamp63wD0IAPAf+ClCz4JLwOnOYsgSCZoY3l3\n" + "3GxWDAkCgYEA/scs7Ft50QOicnJ/DoCjxmpjba0hiqxbz0qAdCyl1llogUKuyCS7\n" + "sxQQvVTt6jk3gP0UYa3FJREToIGZuqaEu6qdY4GI61woNN5hXbkJC6G3FXI/VB8v\n" + "Actkas0kp6J8YWsmTqnsihE5Yii0WCBn+AnIpoU3S2N9WT7U8eA6B7sCgYEA0lsJ\n" + "xqB6NCkKbr+E+V0CGp+S+7zH5dxZtAhDPSKwy2kCYWtDlSVhAzXabTIzF2SW9tJQ\n" + "JV3FhRfiCWTBrBm/I7AmNbNtXnrexYyXPVBhN6uqzYCB8fcLy+HPNZYF3KtQtU3c\n" + "WxAyO6ZxSLgtcP3UB6J8Ac6CYB25cRWNsnrvETUCgYA1HpHfNbNQQNG9yuFyxJ9g\n" + "3w2b8Fzt7MG3lnDxx91Ls5h2WtDWKdJ4o9ZZozt3ejZ4TkvRkclo0QamkF7c65sB\n" + "BbGK7Zb+e1hmrXbfc5TPOAhUEF3jzByg4ycsnVjnGpmUNiLmg8ctginUrWfsd9U1\n" + "gdSz41KEBVo9ITyEsZtnwQKBgQCOgIfd3CcNIORlZC8D8wMS4BllmlzdFepa8OIE\n" + "D3UvR2MKdezho+HVl+zx3nkIFufCK3WJ6r19TVGeRXiCSyrWVWV9KaEkyR4TPAvU\n" + "yJgja5MZBj6BmXePVdjWl1w/Qns5Z5aoxg8Ro87IkaSPEBVMWsGhQ7HExT40IoLM\n" + "b0V3JQKBgQCnZRrzaY9xOy72rtyacWjQB2QxnmkZgwDUq0iQwU/EdP72fPV/TtG8\n" + "PxQqKVPM57XO7qDbyKBt9L3vvmkiC0bABlcMN7UX9H5cHGhnJn6+6muitJlxmtvU\n" + "IiwlYmN2hcA52Ft9cRVC8+8W6Knx019vBnJozjhzhy7wxwqggmxsxg==\n" + "-----END RSA PRIVATE KEY-----\n"; + +static const char *bob_private_key = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEogIBAAKCAQEA5Piv5VnOqg9vAWXGrdxH2Ax1svypJNVmNUlM95qGQloeJQPk\n" + "jSzAEHIBVYAE0eU5gHL3l9EI2mw/bVLsT/REXipj9STPN9NYOVNH2yeD8+KHWNXX\n" + "miTYJ5YjHP9GHDdKiZ52dn7BYktqUlghlxuY0pjWrqhnNkcJep7YZq4QTbCQcyUV\n" + "l+9v+lE6/DuSG5K1KNRCQmmnRVjdWmGQogrW8eZ1xNFwHJuZYgKP/q7ieQSYI+YR\n" + "Mrt1pScjj6FjdL5OMYShrBO7OBYrwDjMnpmox9omF+1S1Gmi1y03b3m1COKX4lID\n" + "Qpc7gvpwq02ZozEX+kfIs0Ua8EKbVgi23V/2OQIDAQABAoIBACXLry1Kr8R+m7I9\n" + "XJhiXjGZjOworLr5xs9Q9DWC+lqFiahOhjGPi3yrdPDqGuGS1vUPBTO4O5/icm3X\n" + "XE6uYYKxuKJEmzf52PxNdPUGBtABOpo9YkN9hXizXcRxlt8deV5SG/ffYIibLke9\n" + "aH4K/iT1OarG/ZKGE1h8U/hPDz3jcVGpqhwn7K4RtRJO7brYKw1jDJwH64g5gDZ7\n" + "Y2zcj5zh1JsnOYPx/1HWxDDIbBN9RbOTyKZIMP9OwglbS5RhIblTgM8zT8ZEHQ1s\n" + "h5dF1jt5pKtcqQelYbfACsTmVCvtJR9Uz98mYE/xpwvJTXbzeycmEccdfuWWFkFB\n" + "xzQroKECgYEA/VeD9T3/zJ9uls0DBuj+LBu+7mL/RrPuoJrqBIuXvIvddYgmvEkf\n" + "IhB7OLgLeMv5KvHRn8XWoEcPGoglfbY4jqIML855gFolyXSNJlbSiOPit8Ea9dKi\n" + "60fHhaa1U+E2xdDOeUilQVCEgnnqSBls1kGqB+81os5GVgo7MzW1+Y0CgYEA51+2\n" + "PYKLC5KU8r/bWlwjF2DmVJq6tD3O8SonqKsPv9MwGz0AimLO+iNtvEkh2rLVidtK\n" + "oP0tvIgsu70xqgX4wRBpZB+rk5IS8y3dCVf6TGVFYK9La5/L5BHLAzbf5jybRzH7\n" + "lT3O94oE7w7gkUiexSM37Wp8FoQG4EPl7MXXBl0CgYBDLE5H232U4v0urQNNdL/Y\n" + "MC8rBELNm239VbYRKHY+PxOkU0p6CCViId6aRmp8SBE0KtQ7OfjTnKPLlCfksklC\n" + "wILctjGPL9fvF6FJdiHyvAHkWSZt4cDjA7BKps5ThFbCkr/8dp+itte7xNmy7lLm\n" + "aJjN68Zb+be6npHd3TL4DQKBgBxHXHTEIc52SfIpdNvkav2OgFhS2QLykvpy1ooM\n" + "7k3ZuAV8PTaswPNdpSngHl0mgmbpAIQQrahfVGhVxV4sgKzIHrl4DXZp4hsKvftI\n" + "X3U643Hfuu4ah8cGTbPE3zS6r5fSChfBiCxFGDlHrjbTk2Qw28MOwr/Vvyll4xI/\n" + "U/qZAoGARuIs5CqcL3NTLyXQGCa3OIeUoqlpMHyy9niJb/S4z6ew6BvI2/uuI//j\n" + "zyZyRdexTF7rOIFDMqsCz7EpJDO9jjwTeKGZ1n25kFJS2AXHhFIU9mdYF9rZ9yuE\n" + "yLB7ISyuiPNMhsOOHMHWWTKiqmQdGBc/HTCKRA1Pu34Bcem55PA=\n" + "-----END RSA PRIVATE KEY-----\n"; + +static const char *alice_csr = + "-----BEGIN CERTIFICATE REQUEST-----\n" + "MIIC9zCCAd8CAQAwgbExCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJPVjEWMBQGA1UE\n" + "BwwNTG9jYWxpdHkgTmFtZTEhMB8GA1UECwwYT3JnYW5pemF0aW9uYWwgVW5pdCBO\n" + "YW1lMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjEWMBQGA1UEAwwNQWxp\n" + "Y2UgRXhhbXBsZTEjMCEGCSqGSIb3DQEJARYUYWxpY2VAZXhhbXBsZWx0ZC5jb20w\n" + "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRWf1hiWWasL9VWTFYWrpP\n" + "OyZaf+eIzJ2wTSGGbgRqbTSDDe8zjFJy8F7EjS13q1tK2dYrPy8GJJW1ZjUYNfwg\n" + "IIEO58lw0jKm70vcOyMGhVOlyPFeZ9KlzGx6k1pLsioU+hF34n63OuXmpRHRDnY5\n" + "sjTZyynoLB5wvwK99d9zTZT62k9vuJKxP8BwJ4ABzXS91Je2d9w4ZUvDL4PnbuQ2\n" + "vmvZWETYVh1ZusZI6PyHDl5R9GwqmdaV6uZbLXDNh+YyqQggjWGFjWxEOYwOsukV\n" + "6JiR/0H/sdAX5Ha0UUWiTV1hWmBmJlQ2Q41CcNC55OHKnO7dcH8/AcTEgtmcHAS3\n" + "AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAOqzDicnVFXBhsfRI/Gcmk0kyKAjg\n" + "UAfADqDT7EyqX31O4C+Flj+G++p4/Yo0W8yP01nSMOF5yB76Eep+hXuLldfL1aKs\n" + "krnZgIrCXyUSb5pVYHrbhI76eet6TMD8P9gj0okPLOfzyTHrQz9wCAv9FfiNl2y+\n" + "cK/meQPAByyxSiyW41owlHaMkSgIL/xULJHjR07QRCiKIAY3/mwUQ5I3k4qKibzQ\n" + "eV4Cus2SEqqXhNsFwZPWQZQmZOXLcEX7g9OsC4iVyGOunUwZdv8BRVThQk+5rGWk\n" + "dHjeWYmS7pWc8EjLnaSairQiw9tmZ0SQcNc7DjnPdkBU78MHxMW54sKBrw==\n" + "-----END CERTIFICATE REQUEST-----\n"; + + +static const char *bob_csr = + "-----BEGIN CERTIFICATE REQUEST-----\n" + "MIIC8zCCAdsCAQAwga0xCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJPVjEWMBQGA1UE\n" + "BwwNTG9jYWxpdHkgTmFtZTEhMB8GA1UECwwYT3JnYW5pemF0aW9uYWwgVW5pdCBO\n" + "YW1lMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjEUMBIGA1UEAwwLQm9i\n" + "IEV4YW1wbGUxITAfBgkqhkiG9w0BCQEWEmJvYkBleGFtcGxlbHRkLmNvbTCCASIw\n" + "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOT4r+VZzqoPbwFlxq3cR9gMdbL8\n" + "qSTVZjVJTPeahkJaHiUD5I0swBByAVWABNHlOYBy95fRCNpsP21S7E/0RF4qY/Uk\n" + "zzfTWDlTR9sng/Pih1jV15ok2CeWIxz/Rhw3SomednZ+wWJLalJYIZcbmNKY1q6o\n" + "ZzZHCXqe2GauEE2wkHMlFZfvb/pROvw7khuStSjUQkJpp0VY3VphkKIK1vHmdcTR\n" + "cBybmWICj/6u4nkEmCPmETK7daUnI4+hY3S+TjGEoawTuzgWK8A4zJ6ZqMfaJhft\n" + "UtRpotctN295tQjil+JSA0KXO4L6cKtNmaMxF/pHyLNFGvBCm1YItt1f9jkCAwEA\n" + "AaAAMA0GCSqGSIb3DQEBCwUAA4IBAQBr85eN2h2q1dLfSeaJHmyVqmwdj2igMOcK\n" + "4RllC2LZ1aorfCvMSb5VzAUbVDFwKJOCfM5vk4hXmt9Uxxmr5qHpnBWi5XGoevuf\n" + "iQ+hdZqS9HIn1/vzNyX6OlCJwVd4qo42RLJFnxyKYnFtZrhA/kdB33Rf+UyRxfoB\n" + "/Su7pUUR+iIMZeu/C3LT3cZy5phqaWzOsw83m3Hap/UzTt5WAhynRfaYRdXuwACU\n" + "QscNSTJsYUfSlynzxY2GHgOw3N34x5pLlVGdOBoG4BjjdZVTeyPc/KgpkUYFY3mD\n" + "jDnSobyp5xr4wcR4RHJCUxCd3/bAAmqKwXY+GnRvOrdKG35Eii0Z\n" + "-----END CERTIFICATE REQUEST-----\n"; + + +static char *bob_identity_cert = NULL; + +typedef enum { + HANDSHAKE_REQUEST, + HANDSHAKE_REPLY, + HANDSHAKE_FINAL +} HandshakeStep_t; + + +struct octet_seq { + unsigned char *data; + uint32_t length; +}; + +static struct plugins_hdl *plugins = NULL; +static dds_security_authentication *auth = NULL; +static dds_security_access_control *access_control = NULL; +static DDS_Security_IdentityHandle local_identity_handle = DDS_SECURITY_HANDLE_NIL; +static DDS_Security_IdentityHandle remote_identity_handle = DDS_SECURITY_HANDLE_NIL; +static DDS_Security_IdentityHandle remote_identity_handle2 = DDS_SECURITY_HANDLE_NIL; +static DDS_Security_PermissionsHandle local_permissions_handle = DDS_SECURITY_HANDLE_NIL; +static char *path_to_etc_dir = NULL; +static char *g_path_build_dir = NULL; +static DDS_Security_IdentityHandle identity_handle_for_callback1=DDS_SECURITY_HANDLE_NIL; +static DDS_Security_IdentityHandle identity_handle_for_callback2=DDS_SECURITY_HANDLE_NIL; +static dds_time_t local_expiry_date; +static dds_time_t remote_expiry_date; + +#define HANDSHAKE_SIGNATURE_SIZE 6 + +#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN +static unsigned bswap4u (unsigned x) +{ + return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); +} +#define toBE4u(x) bswap4u (x) +#define fromBE4u(x) bswap4u (x) +#else +#define toBE4u(x) (x) +#define fromBE4u(x) (x) +#endif + +static const char * PROPERTY_CERT_SUBJECT_NAME = "dds.cert.sn"; +static const char * PROPERTY_CERT_ALGORITHM = "dds.cert.algo"; +static const char * PROPERTY_CA_SUBJECT_NAME = "dds.ca.sn"; +static const char * PROPERTY_CA_ALGORITHM = "dds.ca.aglo"; + +static const char * AUTH_REQUEST_TOKEN_CLASS_ID = "DDS:Auth:PKI-DH:1.0+AuthReq"; +static const char * AUTH_REQUEST_TOKEN_FUTURE_PROP_NAME = "future_challenge"; + +static const char * AUTH_HANDSHAKE_REQUEST_TOKEN_CLASS_ID = "DDS:Auth:PKI-DH:1.0+Req"; +static const char * AUTH_HANDSHAKE_REPLY_TOKEN_CLASS_ID = "DDS:Auth:PKI-DH:1.0+Reply"; +static const char * AUTH_HANDSHAKE_FINAL_TOKEN_CLASS_ID = "DDS:Auth:PKI-DH:1.0+Final"; +static DDS_Security_AuthRequestMessageToken g_local_auth_request_token = DDS_SECURITY_TOKEN_INIT; +static DDS_Security_AuthRequestMessageToken g_remote_auth_request_token = DDS_SECURITY_TOKEN_INIT; +static const DDS_Security_BinaryProperty_t *challenge1_predefined_glb = NULL; +static const DDS_Security_BinaryProperty_t *challenge2_predefined_glb = NULL; +static DDS_Security_OctetSeq serialized_participant_data = DDS_SECURITY_SEQUENCE_INIT; +static DDS_Security_ParticipantBuiltinTopicData *remote_participant_data1 = NULL; +static DDS_Security_ParticipantBuiltinTopicData *remote_participant_data2 = NULL; +static DDS_Security_ParticipantBuiltinTopicData *remote_participant_data3 = NULL; +static DDS_Security_GUID_t candidate_participant_guid; +static DDS_Security_GUID_t remote_participant_guid1; +static DDS_Security_GUID_t remote_participant_guid2; + +static EVP_PKEY *dh_modp_key = NULL; +static EVP_PKEY *dh_ecdh_key = NULL; +static struct octet_seq dh_modp_pub_key = {NULL, 0}; +static struct octet_seq dh_ecdh_pub_key = {NULL, 0}; +static struct octet_seq invalid_dh_pub_key = {NULL, 0}; + + +static void +dds_security_property_init( + DDS_Security_PropertySeq *seq, + DDS_Security_unsigned_long size) +{ + seq->_length = size; + seq->_maximum = size; + seq->_buffer = ddsrt_malloc(size * sizeof(DDS_Security_Property_t)); + memset(seq->_buffer, 0, size * sizeof(DDS_Security_Property_t)); +} + +static void +dds_security_property_deinit( + DDS_Security_PropertySeq *seq) +{ + uint32_t i; + + for (i = 0; i < seq->_length; i++) { + ddsrt_free(seq->_buffer[i].name); + ddsrt_free(seq->_buffer[i].value); + } + ddsrt_free(seq->_buffer); +} + +static void +reset_exception( + DDS_Security_SecurityException *ex) +{ + ex->code = 0; + ex->minor_code = 0; + ddsrt_free(ex->message); + ex->message = NULL; +} + + +static dds_time_t +get_certificate_expiry( + /*_In_*/ X509 *cert) +{ + dds_time_t expiry = DDS_TIME_INVALID; + ASN1_TIME *ans1; + + assert(cert); + + ans1 = X509_get_notAfter(cert); + if (ans1 != NULL) { + int days; + int seconds; + if (ASN1_TIME_diff(&days, &seconds, NULL, ans1) != 0) { + static const dds_duration_t secs_per_day = 86400; + dds_duration_t delta = DDS_SECS(((dds_duration_t)seconds + ((dds_duration_t)days * secs_per_day))); + expiry = dds_time() + delta; + { + BIO *b; + b = BIO_new_fp(stdout, BIO_NOCLOSE); + BIO_printf(b, "[asn1time] "); + ASN1_TIME_print(b, ans1); + BIO_printf(b, "\n"); + BIO_free(b); + } + } + } + + return expiry; +} + + +/* Generate a CA-signed certificate from CSR (Certificate Signing Request) */ +static DDS_Security_boolean create_certificate_from_csr(const char* csr, long valid_secs, + const char* outfile, dds_time_t *expiry) +{ + + ASN1_INTEGER *aserial = NULL; + EVP_PKEY *ca_privkey, *req_pubkey; + EVP_MD const *digest = NULL; + X509 *newcert, *cacert; + X509_NAME *name; + X509V3_CTX ctx; + BIO *fp; + BIO *reqbio = NULL; + BIO *outbio = NULL; + X509_REQ *certreq = NULL; + char *identity_ca_cert_file; + char *identity_ca_key_file; + char* certificate_file; + + outbio = BIO_new(BIO_s_file()); + + /* ---------------------------------------------------------- * + * Load the request data in a BIO, then in a x509_REQ struct. * + * ---------------------------------------------------------- */ + reqbio = BIO_new_mem_buf(csr, -1); + + if (!(certreq = PEM_read_bio_X509_REQ(reqbio, NULL, NULL, NULL))) { + BIO_printf(outbio, "Error can't read X509 request data into memory\n"); + return false; + } + + /* -------------------------------------------------------- * + * Load the signing CA Certificate file * + * ---------------------------------------------------------*/ + + ddsrt_asprintf(&identity_ca_cert_file, "%s%s", path_to_etc_dir, IDENTITY_CA_FILE); + + if (!(fp = BIO_new_file(identity_ca_cert_file, "r"))) { + BIO_printf(outbio, "Error reading CA cert file\n"); + return false; + } + + if (!(cacert = PEM_read_bio_X509(fp, NULL, NULL, NULL))) { + BIO_printf(outbio, "Error loading CA cert into memory\n"); + return false; + } + + BIO_free(fp); + + /* -------------------------------------------------------- * + * Import CA private key file for signing * + * ---------------------------------------------------------*/ + + ddsrt_asprintf(&identity_ca_key_file, "%s%s", path_to_etc_dir, IDENTITY_CA_KEY_FILE); + + if (!(fp = BIO_new_file(identity_ca_key_file, "r"))) { + BIO_printf(outbio, "Error reading CA private key file\n"); + return false; + } + + if (!(ca_privkey = PEM_read_bio_PrivateKey(fp, NULL, NULL, NULL))) { + BIO_printf(outbio, "Error importing key content from file\n"); + return false; + } + + BIO_free(fp); + + /* --------------------------------------------------------- * + * Build Certificate with data from request * + * ----------------------------------------------------------*/ + if (!(newcert = X509_new())) { + BIO_printf(outbio, "Error creating new X509 object\n"); + return false; + } + + if (X509_set_version(newcert, 2) != 1) { + BIO_printf(outbio, "Error setting certificate version\n"); + return false; + } + + /* --------------------------------------------------------- * + * set the certificate serial number here * + * If there is a problem, the value defaults to '0' * + * ----------------------------------------------------------*/ + aserial = ASN1_INTEGER_new(); + ASN1_INTEGER_set(aserial, 0); + if (!X509_set_serialNumber(newcert, aserial)) { + BIO_printf(outbio, "Error setting serial number of the certificate\n"); + return false; + } + + /* --------------------------------------------------------- * + * Extract the subject name from the request * + * ----------------------------------------------------------*/ + if (!(name = X509_REQ_get_subject_name(certreq))) + BIO_printf(outbio, "Error getting subject from cert request\n"); + + /* --------------------------------------------------------- * + * Set the new certificate subject name * + * ----------------------------------------------------------*/ + if (X509_set_subject_name(newcert, name) != 1) { + BIO_printf(outbio, "Error setting subject name of certificate\n"); + return false; + } + + /* --------------------------------------------------------- * + * Extract the subject name from the signing CA cert * + * ----------------------------------------------------------*/ + if (!(name = X509_get_subject_name(cacert))) { + BIO_printf(outbio, "Error getting subject from CA certificate\n"); + return false; + } + + /* --------------------------------------------------------- * + * Set the new certificate issuer name * + * ----------------------------------------------------------*/ + if (X509_set_issuer_name(newcert, name) != 1) { + BIO_printf(outbio, "Error setting issuer name of certificate\n"); + return false; + } + + /* --------------------------------------------------------- * + * Extract the public key data from the request * + * ----------------------------------------------------------*/ + if (!(req_pubkey = X509_REQ_get_pubkey(certreq))) { + BIO_printf(outbio, "Error unpacking public key from request\n"); + return false; + } + + /* --------------------------------------------------------- * + * Optionally: Use the public key to verify the signature * + * ----------------------------------------------------------*/ + if (X509_REQ_verify(certreq, req_pubkey) != 1) { + BIO_printf(outbio, "Error verifying signature on request\n"); + return false; + } + + /* --------------------------------------------------------- * + * Set the new certificate public key * + * ----------------------------------------------------------*/ + if (X509_set_pubkey(newcert, req_pubkey) != 1) { + BIO_printf(outbio, "Error setting public key of certificate\n"); + return false; + } + + /* ---------------------------------------------------------- * + * Set X509V3 start date (now) and expiration date (+365 days)* + * -----------------------------------------------------------*/ + if (!(X509_gmtime_adj(X509_get_notBefore(newcert), -10))) { + BIO_printf(outbio, "Error setting start time\n"); + return false; + } + + if (!(X509_gmtime_adj(X509_get_notAfter(newcert), valid_secs))) { + BIO_printf(outbio, "Error setting expiration time\n"); + return false; + } + + /* ----------------------------------------------------------- * + * Add X509V3 extensions * + * ------------------------------------------------------------*/ + X509V3_set_ctx(&ctx, cacert, newcert, NULL, NULL, 0); + + /* ----------------------------------------------------------- * + * Set digest type, sign new certificate with CA's private key * + * ------------------------------------------------------------*/ + digest = EVP_sha256(); + + if (!X509_sign(newcert, ca_privkey, digest)) { + BIO_printf(outbio, "Error signing the new certificate\n"); + return false; + } + + /* ------------------------------------------------------------ * + * write the certificate to file * + * -------------------------------------------------------------*/ + ddsrt_asprintf(&certificate_file, "%s%s", g_path_build_dir, outfile); + + if (!(fp = BIO_new_file(certificate_file, "w"))) { + BIO_printf(outbio, "Error opening certificate file for write\n"); + return false; + } + if (!PEM_write_bio_X509( fp, newcert)) { + BIO_printf(outbio, "Error writing the signed certificate\n"); + return false; + } + BIO_free(fp); + + *expiry = get_certificate_expiry( newcert ); + + EVP_PKEY_free(req_pubkey); + EVP_PKEY_free(ca_privkey); + X509_REQ_free(certreq); + ASN1_INTEGER_free( aserial ); + X509_free(newcert); + X509_free(cacert); + BIO_free_all(reqbio); + BIO_free_all(outbio); + ddsrt_free(certificate_file); + ddsrt_free( identity_ca_cert_file ); + ddsrt_free( identity_ca_key_file ); + return true; +} + +/* fills the participant properties and return identity cert expiry */ +static void +fill_participant_qos( + DDS_Security_Qos *qos, + long validity_duration, + const char *governance_filename, + dds_time_t *identity_expiry) +{ + char *permission_uri; + char *governance_uri; + char *permissions_ca_cert_file; + char *permissions_ca_uri; + char *identity_file; + char *identity_uri; + char *permissions_file; + + create_certificate_from_csr( alice_csr, validity_duration , ALICE_IDENTITY_CERT_FILE, identity_expiry); + + /*permissions ca cert*/ + ddsrt_asprintf(&permissions_ca_cert_file, "%s%s", path_to_etc_dir, PERMISSIONS_CA_CERT_FILE); + + ddsrt_asprintf(&permissions_ca_uri, "file:%s", permissions_ca_cert_file); + + /*Alice Identity*/ + ddsrt_asprintf(&identity_file, "%s%s", g_path_build_dir, ALICE_IDENTITY_CERT_FILE); + + ddsrt_asprintf(&identity_uri, "file:%s", identity_file); + + /*Alice Permissions */ + ddsrt_asprintf(&permissions_file, "%s%s", path_to_etc_dir, ALICE_PERMISSIONS_FILE); + + ddsrt_asprintf(&permission_uri, "file:%s", permissions_file); + + ddsrt_asprintf(&governance_uri, "file:%s%s", path_to_etc_dir, governance_filename); + + memset(qos, 0, sizeof(*qos)); + dds_security_property_init(&qos->property.value, 6); + qos->property.value._buffer[0].name = ddsrt_strdup(PROPERTY_IDENTITY_CERT); + qos->property.value._buffer[0].value = ddsrt_strdup(identity_uri); + qos->property.value._buffer[1].name = ddsrt_strdup(PROPERTY_IDENTITY_CA); + qos->property.value._buffer[1].value = ddsrt_strdup(identity_ca); + qos->property.value._buffer[2].name = ddsrt_strdup(PROPERTY_PRIVATE_KEY); + qos->property.value._buffer[2].value = ddsrt_strdup(alice_private_key); + qos->property.value._buffer[3].name = ddsrt_strdup(PROPERTY_PERMISSIONS_CA); + qos->property.value._buffer[3].value = ddsrt_strdup(permissions_ca_uri); + qos->property.value._buffer[4].name = ddsrt_strdup(PROPERTY_PERMISSIONS); + qos->property.value._buffer[4].value = ddsrt_strdup(permission_uri); + qos->property.value._buffer[5].name = ddsrt_strdup(PROPERTY_GOVERNANCE); + qos->property.value._buffer[5].value = ddsrt_strdup(governance_uri); + + ddsrt_free(permission_uri); + ddsrt_free(governance_uri); + ddsrt_free( permissions_ca_cert_file ); + ddsrt_free( permissions_file ); + ddsrt_free ( identity_file ); + ddsrt_free( identity_uri ); + ddsrt_free( permissions_ca_uri ); + + +} + +static void +fill_permissions_token( + DDS_Security_PermissionsToken *token) +{ + memset(token, 0, sizeof(DDS_Security_PermissionsToken)); + + token->class_id = ddsrt_strdup(ACCESS_PERMISSIONS_TOKEN_ID); + token->properties._length = token->properties._maximum = 2; + token->properties._buffer = DDS_Security_PropertySeq_allocbuf(2); + + token->properties._buffer[0].name = ddsrt_strdup(PROPERTY_PERMISSIONS_CA_SN); + token->properties._buffer[0].value = ddsrt_strdup(SUBJECT_NAME_PERMISSIONS_CA); + + token->properties._buffer[1].name = ddsrt_strdup(PROPERTY_PERMISSIONS_CA_ALGO); + token->properties._buffer[1].value = ddsrt_strdup(RSA_2048_ALGORITHM_NAME); +} + + +static int +fill_peer_credential_token( + DDS_Security_AuthenticatedPeerCredentialToken *token) +{ + int result = 1; + char *permission_data; + char *permissions_ca_cert_file; + char *permissions_file; + + + /*permissions ca cert*/ + ddsrt_asprintf(&permissions_ca_cert_file, "%s%s", path_to_etc_dir, PERMISSIONS_CA_CERT_FILE); + + /*permissions ca key*/ + ddsrt_asprintf(&permissions_file, "%s%s", path_to_etc_dir, BOB_PERMISSIONS_FILE); + + + memset(token, 0, sizeof(DDS_Security_AuthenticatedPeerCredentialToken)); + + permission_data = load_file_contents(permissions_file); + + if (permission_data) { + token->class_id = ddsrt_strdup(AUTH_PROTOCOL_CLASS_ID); + token->properties._length = token->properties._maximum = 2; + token->properties._buffer = DDS_Security_PropertySeq_allocbuf(2); + + token->properties._buffer[0].name = ddsrt_strdup(PROPERTY_C_ID); + token->properties._buffer[0].value = ddsrt_strdup(&bob_identity_cert[0]); + + token->properties._buffer[1].name = ddsrt_strdup(PROPERTY_C_PERM); + token->properties._buffer[1].value = permission_data; + } else { + ddsrt_free(permission_data); + result = 0; + } + + ddsrt_free( permissions_ca_cert_file ); + ddsrt_free( permissions_file ); + return result; +} + + +static void +serializer_participant_data( + DDS_Security_ParticipantBuiltinTopicData *pdata, + unsigned char **buffer, + size_t *size) +{ + DDS_Security_Serializer serializer; + serializer = DDS_Security_Serializer_new(1024, 1024); + + DDS_Security_Serialize_ParticipantBuiltinTopicData(serializer, pdata); + DDS_Security_Serializer_buffer(serializer, buffer, size); + DDS_Security_Serializer_free(serializer); +} + +static void +initialize_identity_token( + DDS_Security_IdentityToken *token, + const char *certAlgo, + const char *caAlgo) +{ + memset(token, 0, sizeof(*token)); + + token->class_id = ddsrt_strdup(AUTH_PROTOCOL_CLASS_ID); + token->properties._maximum = 4; + token->properties._length = 4; + token->properties._buffer = DDS_Security_PropertySeq_allocbuf(4); + + token->properties._buffer[0].name = ddsrt_strdup(PROPERTY_CERT_SUBJECT_NAME); + token->properties._buffer[0].value = ddsrt_strdup("/C=NL/ST=OV/L=Locality Name/OU=Organizational Unit Name/O=Example Organization/CN=Bob Example/emailAddress=bob@exampleltd.com"); + token->properties._buffer[0].propagate = true; + + token->properties._buffer[1].name = ddsrt_strdup(PROPERTY_CERT_ALGORITHM); + token->properties._buffer[1].value = ddsrt_strdup(certAlgo); + token->properties._buffer[1].propagate = true; + + token->properties._buffer[2].name = ddsrt_strdup(PROPERTY_CA_SUBJECT_NAME); + token->properties._buffer[2].value = ddsrt_strdup("/C=NL/ST=OV/L=Locality Name/OU=Organizational Unit Name/O=Example Signer CA/CN=Example CA/emailAddress=authority@identitycaltd.org"); + token->properties._buffer[2].propagate = true; + + token->properties._buffer[3].name = ddsrt_strdup(PROPERTY_CA_ALGORITHM); + token->properties._buffer[3].value = ddsrt_strdup(caAlgo); + token->properties._buffer[3].propagate = true; +} + +static DDS_Security_long +validate_local_identity_and_permissions( uint32_t identity_expiry_duration, dds_time_t *identity_expiry ) +{ + DDS_Security_long res = DDS_SECURITY_ERR_OK_CODE; + DDS_Security_ValidationResult_t result; + DDS_Security_DomainId domain_id = 0; + DDS_Security_Qos participant_qos; + DDS_Security_SecurityException exception = {NULL, 0, 0}; + DDS_Security_GuidPrefix_t prefix = {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb}; + DDS_Security_EntityId_t entityId = {{0xb0,0xb1,0xb2},0x1}; + DDS_Security_GUID_t local_participant_guid; + DDS_Security_ParticipantBuiltinTopicData *local_participant_data; + unsigned char *sdata; + size_t sz; + + memset(&local_participant_guid, 0, sizeof(local_participant_guid)); + memcpy(&candidate_participant_guid.prefix, &prefix, sizeof(prefix)); + memcpy(&candidate_participant_guid.entityId, &entityId, sizeof(entityId)); + + fill_participant_qos(&participant_qos, identity_expiry_duration, "Example_Governance.p7s", identity_expiry ); + + /* Now call the function. */ + result = auth->validate_local_identity( + auth, + &local_identity_handle, + &local_participant_guid, + domain_id, + &participant_qos, + &candidate_participant_guid, + &exception); + + if (result != DDS_SECURITY_VALIDATION_OK) { + res = DDS_SECURITY_ERR_UNDEFINED_CODE; + printf("validate_local_identity_failed: (%d) %s\n", (int)exception.code, exception.message ? exception.message : "Error message missing"); + } + + reset_exception(&exception); + + if (res == 0) { + local_permissions_handle = access_control->validate_local_permissions( + access_control, + auth, + local_identity_handle, + 0, + &participant_qos, + &exception); + + if (local_permissions_handle == DDS_SECURITY_HANDLE_NIL) { + printf("validate_local_permissions_failed: (%d) %s\n", (int)exception.code, exception.message ? exception.message : "Error message missing"); + if (exception.code == DDS_SECURITY_ERR_VALIDITY_PERIOD_EXPIRED_CODE) { + /* This can happen on very slow platforms or when doing a valgrind run. */ + res = DDS_SECURITY_ERR_VALIDITY_PERIOD_EXPIRED_CODE; + } else { + res = DDS_SECURITY_ERR_UNDEFINED_CODE; + } + } + } + + dds_security_property_deinit(&participant_qos.property.value); + reset_exception(&exception); + + local_participant_data = DDS_Security_ParticipantBuiltinTopicData_alloc(); + memcpy(&local_participant_data->key[0], &local_participant_guid, 12); + /* convert from big-endian format to native format */ + local_participant_data->key[0] = fromBE4u(local_participant_data->key[0]); + local_participant_data->key[1] = fromBE4u(local_participant_data->key[1]); + local_participant_data->key[2] = fromBE4u(local_participant_data->key[2]); + + initialize_identity_token(&local_participant_data->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME); + fill_permissions_token(&local_participant_data->permissions_token ); + + local_participant_data->security_info.participant_security_attributes = 0x01; + local_participant_data->security_info.plugin_participant_security_attributes = 0x02; + + serializer_participant_data(local_participant_data, &sdata, &sz); + + serialized_participant_data._length = serialized_participant_data._maximum = (DDS_Security_unsigned_long) sz; + serialized_participant_data._buffer = sdata; + + DDS_Security_ParticipantBuiltinTopicData_free(local_participant_data); + + + + return res; +} + +static void +clear_local_identity_and_permissions(void) +{ + DDS_Security_SecurityException exception = {NULL, 0, 0}; + DDS_Security_boolean success; + + if (local_permissions_handle != DDS_SECURITY_HANDLE_NIL) { + success = access_control->return_permissions_handle(access_control, local_permissions_handle, &exception); + if (!success) { + printf("return_permission_handle failed: %s\n", exception.message ? exception.message : "Error message missing"); + } + reset_exception(&exception); + } + + if (local_identity_handle != DDS_SECURITY_HANDLE_NIL) { + success = auth->return_identity_handle(auth, local_identity_handle, &exception); + if (!success) { + printf("return_identity_handle failed: %s\n", exception.message ? exception.message : "Error message missing"); + } + reset_exception(&exception); + } + + DDS_Security_OctetSeq_deinit(&serialized_participant_data); +} + +static int +set_path_to_etc_dir(void) +{ + int res = 0; + size_t len; + + len = 1024; + path_to_etc_dir = ddsrt_malloc(len); + snprintf(path_to_etc_dir, 1024, "%s/listeners_authentication/etc/", CONFIG_ENV_TESTS_DIR); + + return res; +} + +static void set_path_build_dir(void) +{ + ddsrt_asprintf(&g_path_build_dir, "%s/", CONFIG_ENV_BUILD_DIR); +} + +/* handshake helper functions */ + + +static DDS_Security_BinaryProperty_t * +find_binary_property( + DDS_Security_DataHolder *token, + const char *name) +{ + DDS_Security_BinaryProperty_t *result = NULL; + uint32_t i; + + for (i = 0; i < token->binary_properties._length && !result; i++) { + if (token->binary_properties._buffer[i].name && (strcmp(token->binary_properties._buffer[i].name, name) == 0)) { + result = &token->binary_properties._buffer[i]; + } + } + + return result; +} + + +static void +octet_seq_init( + struct octet_seq *seq, + unsigned char *data, + uint32_t size) +{ + seq->data = ddsrt_malloc(size); + memcpy(seq->data, data, size); + seq->length = size; +} + +static void +octet_seq_deinit( + struct octet_seq *seq) +{ + ddsrt_free(seq->data); +} +static char * +get_openssl_error_message_for_test( + void) +{ + BIO *bio = BIO_new(BIO_s_mem()); + char *msg; + char *buf = NULL; + size_t len; + + if (bio) { + ERR_print_errors(bio); + len = (uint32_t)BIO_get_mem_data (bio, &buf); + msg = ddsrt_malloc(len + 1); + memset(msg, 0, len+1); + memcpy(msg, buf, len); + BIO_free(bio); + } else { + msg = ddsrt_strdup("BIO_new failed"); + } + + return msg; +} + + +static const BIGNUM * +dh_get_public_key( + /*_In_ */DH *dhkey) +{ +#ifdef AUTH_INCLUDE_DH_ACCESSORS + const BIGNUM *pubkey, *privkey; + DH_get0_key(dhkey, &pubkey, &privkey); + return pubkey; +#else + return dhkey->pub_key; +#endif +} + + + +/* DH Helper Functions */ + +static int +create_dh_key_modp_2048( + EVP_PKEY **pkey) +{ + int r = 0; + EVP_PKEY *params = NULL; + EVP_PKEY_CTX *kctx = NULL; + DH *dh = NULL; + + *pkey = NULL; + + if ((params = EVP_PKEY_new()) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate EVP_PKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((dh = DH_get_2048_256()) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate DH parameter: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_set1_DH(params, dh) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to set DH parameter to MODP_2048_256: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate KEY context %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen_init(kctx) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to initialize KEY context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to generate :MODP_2048_256 keys %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (params) EVP_PKEY_free(params); + if (kctx) EVP_PKEY_CTX_free(kctx); + if (dh) DH_free(dh); + + return r; +} + +static int +get_dh_public_key_modp_2048( + EVP_PKEY *pkey, + struct octet_seq *pubkey) +{ + int r = 0; + DH *dhkey; + unsigned char *buffer = NULL; + uint32_t size; + ASN1_INTEGER *asn1int; + + dhkey = EVP_PKEY_get1_DH(pkey); + if (!dhkey) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get DH key from PKEY: %s", msg); + ddsrt_free(msg); + r = -1; + goto fail_get_dhkey; + } + + asn1int = BN_to_ASN1_INTEGER( dh_get_public_key(dhkey) , NULL); + if (!asn1int) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to convert DH key to ASN1 integer: %s", msg); + ddsrt_free(msg); + r = -1; + goto fail_get_pubkey; + } + + size = (uint32_t)i2d_ASN1_INTEGER(asn1int, &buffer); + octet_seq_init(pubkey, buffer, size); + + ASN1_INTEGER_free(asn1int); + OPENSSL_free(buffer); + +fail_get_pubkey: + DH_free(dhkey); +fail_get_dhkey: + return r; +} + +static int +create_dh_key_ecdh( + EVP_PKEY **pkey) +{ + int r = 0; + EVP_PKEY *params = NULL; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *kctx = NULL; + + *pkey = NULL; + + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate DH parameter context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_paramgen_init(pctx) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to initialize DH generation context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to set DH generation parameter generation method: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to generate DH parameters: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to allocate KEY context %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen_init(kctx) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to initialize KEY context: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (EVP_PKEY_keygen(kctx, pkey) <= 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to generate :MODP_2048_256 keys %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (kctx) EVP_PKEY_CTX_free(kctx); + if (params) EVP_PKEY_free(params); + if (pctx) EVP_PKEY_CTX_free(pctx); + + return r; +} + +static int +get_dh_public_key_ecdh( + EVP_PKEY *pkey, + struct octet_seq *pubkey) +{ + int r = 0; + EC_KEY *eckey = NULL; + const EC_GROUP *group = NULL; + const EC_POINT *point = NULL; + size_t sz; + + if (!(eckey = EVP_PKEY_get1_EC_KEY(pkey))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get EC key from PKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (!(point = EC_KEY_get0_public_key(eckey))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get public key from ECKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if (!(group = EC_KEY_get0_group(eckey))) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to get group from ECKEY: %s", msg); + ddsrt_free(msg); + r = -1; + } else if ((sz = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL)) != 0) { + pubkey->data = ddsrt_malloc(sz); + pubkey->length = (uint32_t)EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey->data, sz, NULL); + if (pubkey->length == 0) { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to serialize public EC key: %s", msg); + ddsrt_free(msg); + octet_seq_deinit(pubkey); + r = -1; + } + } else { + char *msg = get_openssl_error_message_for_test(); + printf("Failed to serialize public EC key: %s", msg); + ddsrt_free(msg); + r = -1; + } + + if (eckey) EC_KEY_free(eckey); + + return r; +} + +CU_Init(ddssec_builtin_listeners_auth) +{ + int res = 0; + + plugins = load_plugins(&access_control /* Access Control */, + &auth /* Authentication */, + NULL /* Cryptograpy */); + if (plugins) { + set_path_build_dir(); + res = set_path_to_etc_dir(); + if (res >= 0) { + res = create_dh_key_modp_2048(&dh_modp_key); + } + if (res >= 0) { + res = get_dh_public_key_modp_2048(dh_modp_key, &dh_modp_pub_key); + } + if (res >= 0) { + res = create_dh_key_ecdh(&dh_ecdh_key); + } + if (res >= 0) { + res = get_dh_public_key_ecdh(dh_ecdh_key, &dh_ecdh_pub_key); + } + if (res >= 0) { + octet_seq_init(&invalid_dh_pub_key, dh_modp_pub_key.data, dh_modp_pub_key.length); + invalid_dh_pub_key.data[0] = 0x08; + } + } else { + res = -1; + } + + /* Openssl init */ + OpenSSL_add_all_algorithms(); + ERR_load_BIO_strings(); + ERR_load_crypto_strings(); + + return res; +} + +CU_Clean(ddssec_builtin_listeners_auth) +{ + octet_seq_deinit(&dh_modp_pub_key); + octet_seq_deinit(&dh_ecdh_pub_key); + octet_seq_deinit(&invalid_dh_pub_key); + if (dh_modp_key) { + EVP_PKEY_free(dh_modp_key); + } + if (dh_ecdh_key) { + EVP_PKEY_free(dh_ecdh_key); + } + unload_plugins(plugins); + + ddsrt_free(path_to_etc_dir); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + return 0; +} + + + +static void +set_binary_property_value( + DDS_Security_BinaryProperty_t *bp, + const char *name, + const unsigned char *data, + uint32_t length) +{ + assert(bp); + assert(name); + assert(data); + + bp->name = ddsrt_strdup(name); + bp->value._maximum = bp->value._length = length; + if (length) { + bp->value._buffer = ddsrt_malloc(length); + memcpy(bp->value._buffer, data, length); + } else { + bp->value._buffer = NULL; + } +} + +static void +set_binary_property_string( + DDS_Security_BinaryProperty_t *bp, + const char *name, + const char *data) +{ + uint32_t length; + + assert(bp); + assert(name); + assert(data); + + length = (uint32_t)strlen(data) + 1; + set_binary_property_value(bp, name, (const unsigned char *)data, length); +} + + +static DDS_Security_ValidationResult_t +create_asymmetrical_signature_for_test( + EVP_PKEY *pkey, + void *data, + size_t dataLen, + unsigned char **signature, + size_t *signatureLen, + DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *kctx = NULL; + + if (!(mdctx = EVP_MD_CTX_create())) { + char *msg = get_openssl_error_message_for_test(); + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to create signing context: %s", msg); + ddsrt_free(msg); + goto err_create_ctx; + } + + if (EVP_DigestSignInit(mdctx, &kctx, EVP_sha256(), NULL, pkey) != 1) { + char *msg = get_openssl_error_message_for_test(); + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize signing context: %s", msg); + ddsrt_free(msg); + goto err_sign; + } + + if (EVP_PKEY_CTX_set_rsa_padding(kctx, RSA_PKCS1_PSS_PADDING) < 1) { + char *msg = get_openssl_error_message_for_test(); + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize signing context: %s", msg); + ddsrt_free(msg); + goto err_sign; + } + + if (EVP_DigestSignUpdate(mdctx, data, dataLen) != 1) { + char *msg = get_openssl_error_message_for_test(); + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to update signing context: %s", msg); + ddsrt_free(msg); + goto err_sign; + } + + if (EVP_DigestSignFinal(mdctx, NULL, signatureLen) != 1) { + char *msg = get_openssl_error_message_for_test(); + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to finalize signing context: %s", msg); + ddsrt_free(msg); + goto err_sign; + } + + //*signature = ddsrt_malloc(sizeof(unsigned char) * (*signatureLen)); + *signature = OPENSSL_malloc(*signatureLen); + if (EVP_DigestSignFinal(mdctx, *signature, signatureLen) != 1) { + char *msg = get_openssl_error_message_for_test(); + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, "Authentication", DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to finalize signing context: %s", msg); + ddsrt_free(msg); + ddsrt_free(signature); + } + +err_sign: + EVP_MD_CTX_destroy(mdctx); +err_create_ctx: + return result; +} + + +static X509 * +load_certificate( + const char *data) +{ + X509 *cert = NULL; + BIO *bio; + + bio = BIO_new_mem_buf((void *) data, -1); + if (!bio) { + return NULL; + } + + cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); + + BIO_free(bio); + + return cert; +} + +static int +get_adjusted_participant_guid( + X509 *cert, + const DDS_Security_GUID_t *candidate, + DDS_Security_GUID_t *adjusted) +{ + int result = 0; + unsigned char high[SHA256_DIGEST_LENGTH], low[SHA256_DIGEST_LENGTH]; + unsigned char *subject; + DDS_Security_octet hb = 0x80; + X509_NAME *name; + unsigned char *tmp = NULL; + int i; + int sz; + + name = X509_get_subject_name(cert); + sz = i2d_X509_NAME(name, &tmp); + if (sz > 0) { + subject = ddsrt_malloc((size_t)sz); + memcpy(subject, tmp, (size_t)sz); + OPENSSL_free(tmp); + + SHA256(subject, (size_t)sz, high); + SHA256(&candidate->prefix[0], sizeof(DDS_Security_GuidPrefix_t), low); + + adjusted->entityId = candidate->entityId; + for (i = 0; i < 6; i++) { + adjusted->prefix[i] = hb | high[i]>>1; + hb = (DDS_Security_octet)(high[i]<<7); + } + for (i = 0; i < 6; i++) { + adjusted->prefix[i+6] = low[i]; + } + ddsrt_free(subject); + result = 1; + } + + return result; +} + +static DDS_Security_ValidationResult_t +create_signature_for_test( + EVP_PKEY *pkey, + const DDS_Security_BinaryProperty_t **binary_properties, + const uint32_t binary_properties_length, + unsigned char **signature, + size_t *signatureLen, + DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t result; + DDS_Security_Serializer serializer; + unsigned char *buffer; + size_t size; + + serializer = DDS_Security_Serializer_new(4096, 4096); + + DDS_Security_Serialize_BinaryPropertyArray(serializer,binary_properties, binary_properties_length); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + + result = create_asymmetrical_signature_for_test(pkey, buffer, size, signature, signatureLen, ex); + + ddsrt_free(buffer); + DDS_Security_Serializer_free(serializer); + + return result; +} + + +static void +deinitialize_identity_token( + DDS_Security_IdentityToken *token) +{ + DDS_Security_DataHolder_deinit(token); +} + + + +static void +fill_auth_request_token( + DDS_Security_AuthRequestMessageToken *token) +{ + uint32_t i; + uint32_t len = 32; + unsigned char *challenge; + + challenge = ddsrt_malloc(len); + + for (i = 0; i < len; i++) { + challenge[i] = (unsigned char)(0xFF - i); + } + + memset(token, 0, sizeof(*token)); + + token->class_id = ddsrt_strdup(AUTH_REQUEST_TOKEN_CLASS_ID); + token->binary_properties._maximum = 1; + token->binary_properties._length = 1; + token->binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1); + token->binary_properties._buffer->name = ddsrt_strdup(AUTH_REQUEST_TOKEN_FUTURE_PROP_NAME); + + token->binary_properties._buffer->value._maximum = len; + token->binary_properties._buffer->value._length = len; + token->binary_properties._buffer->value._buffer = challenge; +} + +static int +validate_remote_identity (const char *remote_id_certificate) +{ + int res = 0; + DDS_Security_ValidationResult_t result; + DDS_Security_IdentityToken remote_identity_token; + static DDS_Security_AuthRequestMessageToken local_auth_request_token = DDS_SECURITY_TOKEN_INIT; + DDS_Security_GUID_t guid1; + DDS_Security_GUID_t guid2; + DDS_Security_SecurityException exception = {NULL, 0, 0}; + DDS_Security_GuidPrefix_t prefix1 = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab}; + DDS_Security_GuidPrefix_t prefix2 = {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb}; + DDS_Security_EntityId_t entityId = {{0xb0,0xb1,0xb2},0x1}; + X509 *cert; + + memcpy(&guid1.prefix, &prefix1, sizeof(prefix1)); + memcpy(&guid1.entityId, &entityId, sizeof(entityId)); + memcpy(&guid2.prefix, &prefix2, sizeof(prefix2)); + memcpy(&guid2.entityId, &entityId, sizeof(entityId)); + + if (local_identity_handle == DDS_SECURITY_HANDLE_NIL) { + return -1; + } + + cert = load_certificate(remote_id_certificate); + if (!cert) { + return -1; + } + + if (!get_adjusted_participant_guid(cert, &guid1, &remote_participant_guid1)) { + X509_free(cert); + return -1; + } + + if (!get_adjusted_participant_guid(cert, &guid2, &remote_participant_guid2)) { + X509_free(cert); + return -1; + } + + X509_free(cert); + + initialize_identity_token(&remote_identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME); + + result = auth->validate_remote_identity( + auth, + &remote_identity_handle, + &g_local_auth_request_token, + NULL, + local_identity_handle, + &remote_identity_token, + &remote_participant_guid1, + &exception); + + if ((result != DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST) && + (result != DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE)) { + printf("validate_remote_identity_failed: %s\n", exception.message ? exception.message : "Error message missing"); + } + + reset_exception(&exception); + fill_auth_request_token(&g_remote_auth_request_token); + + result = auth->validate_remote_identity( + auth, + &remote_identity_handle2, + &local_auth_request_token, + &g_remote_auth_request_token, + local_identity_handle, + &remote_identity_token, + &remote_participant_guid2, + &exception); + + if ((result != DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST) && + (result != DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE)) { + printf("validate_remote_identity_failed: %s\n", exception.message ? exception.message : "Error message missing"); + } + + reset_exception(&exception); + deinitialize_identity_token(&remote_identity_token); + DDS_Security_DataHolder_deinit(&local_auth_request_token); + + remote_participant_data1 = DDS_Security_ParticipantBuiltinTopicData_alloc(); + memcpy(&remote_participant_data1->key[0], &remote_participant_guid1, 12); + remote_participant_data1->key[0] = fromBE4u(remote_participant_data1->key[0]); + remote_participant_data1->key[1] = fromBE4u(remote_participant_data1->key[1]); + remote_participant_data1->key[2] = fromBE4u(remote_participant_data1->key[2]); + + initialize_identity_token(&remote_participant_data1->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME); + fill_permissions_token(&remote_participant_data1->permissions_token ); + + remote_participant_data1->security_info.participant_security_attributes = 0x01; + remote_participant_data1->security_info.plugin_participant_security_attributes = 0x02; + + remote_participant_data2 = DDS_Security_ParticipantBuiltinTopicData_alloc(); + memcpy(&remote_participant_data2->key[0], &remote_participant_guid2, 12); + remote_participant_data2->key[0] = fromBE4u(remote_participant_data2->key[0]); + remote_participant_data2->key[1] = fromBE4u(remote_participant_data2->key[1]); + remote_participant_data2->key[2] = fromBE4u(remote_participant_data2->key[2]); + + initialize_identity_token(&remote_participant_data2->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME); + fill_permissions_token(&remote_participant_data2->permissions_token ); + + remote_participant_data2->security_info.participant_security_attributes = 0x01; + remote_participant_data2->security_info.plugin_participant_security_attributes = 0x02; + + remote_participant_data3 = DDS_Security_ParticipantBuiltinTopicData_alloc(); + memcpy(&remote_participant_data3->key[0], &candidate_participant_guid, 12); + + initialize_identity_token(&remote_participant_data3->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME); + fill_permissions_token(&remote_participant_data3->permissions_token ); + + remote_participant_data2->security_info.participant_security_attributes = 0x01; + remote_participant_data2->security_info.plugin_participant_security_attributes = 0x02; + + challenge1_predefined_glb = find_binary_property(&g_remote_auth_request_token, AUTH_REQUEST_TOKEN_FUTURE_PROP_NAME); + challenge2_predefined_glb = challenge1_predefined_glb; + + return res; +} + +static void +release_remote_identities(void) +{ + DDS_Security_SecurityException exception = {NULL, 0, 0}; + DDS_Security_boolean success; + + if (remote_identity_handle != DDS_SECURITY_HANDLE_NIL) { + success = auth->return_identity_handle(auth, remote_identity_handle, &exception); + if (!success) { + printf("return_identity_handle failed: %s\n", exception.message ? exception.message : "Error message missing"); + } + reset_exception(&exception); + } + + if (remote_identity_handle2 != DDS_SECURITY_HANDLE_NIL) { + success = auth->return_identity_handle(auth, remote_identity_handle2, &exception); + if (!success) { + printf("return_identity_handle failed: %s\n", exception.message ? exception.message : "Error message missing"); + } + reset_exception(&exception); + } + + DDS_Security_DataHolder_deinit(&g_local_auth_request_token); + DDS_Security_DataHolder_deinit(&g_remote_auth_request_token); + + DDS_Security_ParticipantBuiltinTopicData_free(remote_participant_data1); + DDS_Security_ParticipantBuiltinTopicData_free(remote_participant_data2); + DDS_Security_ParticipantBuiltinTopicData_free(remote_participant_data3); +} + + +static void +fill_handshake_message_token( + DDS_Security_HandshakeMessageToken *token, + DDS_Security_ParticipantBuiltinTopicData *pdata, + const char *certificate, + const char *dsign, + const char *kagree, + const struct octet_seq *diffie_hellman1, + const unsigned char *challengeData, + unsigned int challengeDataSize, + const struct octet_seq *diffie_hellman2, + const unsigned char *challengeData2, + unsigned int challengeDataSize2, + const DDS_Security_BinaryProperty_t *hash1_from_request, + const DDS_Security_BinaryProperty_t *hash2_from_reply, + HandshakeStep_t step) +{ + DDS_Security_BinaryProperty_t *tokens; + DDS_Security_BinaryProperty_t *c_id; + DDS_Security_BinaryProperty_t *c_perm; + DDS_Security_BinaryProperty_t *c_pdata; + DDS_Security_BinaryProperty_t *c_dsign_algo; + DDS_Security_BinaryProperty_t *c_kagree_algo; + DDS_Security_BinaryProperty_t *hash_c1; + DDS_Security_BinaryProperty_t *hash_c2; + DDS_Security_BinaryProperty_t *dh1; + DDS_Security_BinaryProperty_t *dh2; + DDS_Security_BinaryProperty_t *challenge1; + DDS_Security_BinaryProperty_t *challenge2; + DDS_Security_BinaryProperty_t *signature; + DDS_Security_SecurityException exception = {NULL, 0, 0}; + unsigned idx; + unsigned char *serialized_local_participant_data; + size_t serialized_local_participant_data_size; + /*unsigned hash[32];*/ + + switch( step ) + { + + case HANDSHAKE_REQUEST: + tokens = DDS_Security_BinaryPropertySeq_allocbuf(8); + c_id = &tokens[0]; + c_perm = &tokens[1]; + c_pdata = &tokens[2]; + c_dsign_algo = &tokens[3]; + c_kagree_algo = &tokens[4]; + hash_c1 = &tokens[5]; + dh1 = &tokens[6]; + challenge1 = &tokens[7]; + + serializer_participant_data(pdata, &serialized_local_participant_data, &serialized_local_participant_data_size); + + /* Store the Identity Certificate associated with the local identify in c.id property */ + if (certificate) { + set_binary_property_string(c_id, "c.id", certificate); + } else { + set_binary_property_string(c_id, "c.idx", "rubbish"); + } + + /* Store the permission document in the c.perm property */ + set_binary_property_string(c_perm, "c.perm", "permissions_document"); + + /* Store the provided local_participant_data in the c.pdata property */ + set_binary_property_value(c_pdata, "c.pdata", serialized_local_participant_data, (uint32_t)serialized_local_participant_data_size); + ddsrt_free(serialized_local_participant_data); + + /* Set the used signing algorithm descriptor in c.dsign_algo */ + if (dsign) { + set_binary_property_string(c_dsign_algo, "c.dsign_algo", dsign); + } else { + set_binary_property_string(c_dsign_algo, "c.dsign_algox", "rubbish"); + } + + /* Set the used key algorithm descriptor in c.kagree_algo */ + if (kagree) { + set_binary_property_string(c_kagree_algo, "c.kagree_algo", kagree); + } else { + set_binary_property_string(c_kagree_algo, "c.kagree_algox", "rubbish"); + } + + /* Calculate the hash_c1 */ + { + DDS_Security_BinaryPropertySeq bseq; + DDS_Security_Serializer serializer; + unsigned char hash1_sent_in_request_arr[32]; + unsigned char *buffer; + size_t size; + + bseq._length = bseq._maximum = 5; + bseq._buffer = tokens; + + serializer = DDS_Security_Serializer_new(1024, 1024); + + DDS_Security_Serialize_BinaryPropertySeq(serializer, &bseq); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + SHA256(buffer, size, hash1_sent_in_request_arr); + ddsrt_free(buffer); + DDS_Security_Serializer_free(serializer); + + set_binary_property_value(hash_c1, "hash_c1", hash1_sent_in_request_arr, sizeof(hash1_sent_in_request_arr)); + } + + /* Set the DH public key associated with the local participant in dh1 property */ + if (diffie_hellman1) { + set_binary_property_value(dh1, "dh1", diffie_hellman1->data, diffie_hellman1->length); + } else { + set_binary_property_string(dh1, "dh1x", "rubbish"); + } + + /* Set the challenge in challenge1 property */ + if (challengeData) { + set_binary_property_value(challenge1, "challenge1", challengeData, challengeDataSize); + } else { + set_binary_property_value(challenge1, "challenge1x", challenge1_predefined_glb->value._buffer, challenge1_predefined_glb->value._length); + } + + token->class_id = ddsrt_strdup(AUTH_HANDSHAKE_REQUEST_TOKEN_CLASS_ID); + token->binary_properties._length = token->binary_properties._maximum = 8; + token->binary_properties._buffer = tokens; + break; + + case HANDSHAKE_REPLY: + tokens = DDS_Security_BinaryPropertySeq_allocbuf(12); + idx = 0; + c_id = &tokens[idx++]; + c_perm = &tokens[idx++]; + c_pdata = &tokens[idx++]; + c_dsign_algo = &tokens[idx++]; + c_kagree_algo = &tokens[idx++]; + hash_c2 = &tokens[idx++]; + challenge2 = &tokens[idx++]; + dh2 = &tokens[idx++]; + challenge1 = &tokens[idx++]; + dh1 = &tokens[idx++]; + hash_c1 = &tokens[idx++] ; + signature = &tokens[idx++]; + + serializer_participant_data(pdata, &serialized_local_participant_data, &serialized_local_participant_data_size); + + /* Store the Identity Certificate associated with the local identify in c.id property */ + if (certificate) { + set_binary_property_string(c_id, "c.id", certificate); + } else { + set_binary_property_string(c_id, "c.idx", "rubbish"); + } + + /* Store the permission document in the c.perm property */ + set_binary_property_string(c_perm, "c.perm", "permissions_document"); + + /* Store the provided local_participant_data in the c.pdata property */ + set_binary_property_value(c_pdata, "c.pdata", serialized_local_participant_data, (uint32_t)serialized_local_participant_data_size); + ddsrt_free(serialized_local_participant_data); + + /* Set the used signing algorithm descriptor in c.dsign_algo */ + if (dsign) { + set_binary_property_string(c_dsign_algo, "c.dsign_algo", dsign); + } else { + set_binary_property_string(c_dsign_algo, "c.dsign_algox", "rubbish"); + } + + /* Set the used key algorithm descriptor in c.kagree_algo */ + if (kagree) { + set_binary_property_string(c_kagree_algo, "c.kagree_algo", kagree); + } else { + set_binary_property_string(c_kagree_algo, "c.kagree_algox", "rubbish"); + } + + CU_ASSERT(hash1_from_request != NULL); + + set_binary_property_value(hash_c1, "hash_c1", hash1_from_request->value._buffer, hash1_from_request->value._length); + + /* Calculate the hash_c2 */ + { + DDS_Security_BinaryPropertySeq bseq; + DDS_Security_Serializer serializer; + unsigned char hash2_sent_in_reply_arr[32]; + unsigned char *buffer; + size_t size; + + bseq._length = bseq._maximum = 5; + bseq._buffer = tokens; + + serializer = DDS_Security_Serializer_new(1024, 1024); + + DDS_Security_Serialize_BinaryPropertySeq(serializer, &bseq); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + SHA256(buffer, size, hash2_sent_in_reply_arr); + + ddsrt_free(buffer); + DDS_Security_Serializer_free(serializer); + + set_binary_property_value(hash_c2, "hash_c2", hash2_sent_in_reply_arr, sizeof(hash2_sent_in_reply_arr)); + } + + /* Set the challenge in challenge1 property */ + if (challengeData) { + set_binary_property_value(challenge1, "challenge1", challengeData, challengeDataSize); + } else { + set_binary_property_value(challenge1, "challenge1x", challenge2->value._buffer, challenge2->value._length); + } + + /* Set the challenge in challenge2 property */ + if (challengeData2) { + set_binary_property_value(challenge2, "challenge2", challengeData2, challengeDataSize2); + } else { + set_binary_property_value(challenge2, "challenge2x", challenge2->value._buffer, challenge2->value._length); + } + + + /* Set the DH public key associated with the local participant in dh1 property */ + if (diffie_hellman1) { + set_binary_property_value(dh1, "dh1", diffie_hellman1->data, diffie_hellman1->length); + } else { + set_binary_property_string(dh1, "dh1x", "rubbish"); + } + + /* Set the DH public key associated with the local participant in dh2 property */ + if (diffie_hellman2) { + set_binary_property_value(dh2, "dh2", diffie_hellman2->data, diffie_hellman2->length); + } else { + set_binary_property_string(dh2, "dh2x", "rubbish"); + } + + /* Calculate the signature */ + { + BIO *bio; + EVP_PKEY *private_key_x509; + unsigned char *sign; + size_t signlen; + + const DDS_Security_BinaryProperty_t * binary_properties[ HANDSHAKE_SIGNATURE_SIZE ]; + + /* load certificate in buffer */ + bio = BIO_new_mem_buf((const char *) bob_private_key, -1); + assert( bio ); + private_key_x509 = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + assert (private_key_x509 ); + + binary_properties[0] = hash_c2; + binary_properties[1] = challenge2; + binary_properties[2] = dh2; + binary_properties[3] = challenge1; + binary_properties[4] = dh1; + binary_properties[5] = hash_c1; + + if (create_signature_for_test(private_key_x509, binary_properties, HANDSHAKE_SIGNATURE_SIZE , &sign, &signlen, &exception) != DDS_SECURITY_VALIDATION_OK) + { + printf("Exception: %s\n", exception.message); + } + set_binary_property_value(signature, "signature", sign, (uint32_t)signlen); + + ddsrt_free(sign); + EVP_PKEY_free(private_key_x509); + BIO_free(bio); + } + + token->class_id = ddsrt_strdup(AUTH_HANDSHAKE_REPLY_TOKEN_CLASS_ID); + token->binary_properties._length = token->binary_properties._maximum = 12; + token->binary_properties._buffer = tokens; + break; + + case HANDSHAKE_FINAL: + tokens = DDS_Security_BinaryPropertySeq_allocbuf(7); + idx = 0; + signature = &tokens[idx++]; + hash_c1 = &tokens[idx++]; + challenge1 = &tokens[idx++]; + dh1 = &tokens[idx++]; + challenge2 = &tokens[idx++]; + dh2 = &tokens[idx++]; + hash_c2 = &tokens[idx++]; + + CU_ASSERT(hash1_from_request != NULL); + CU_ASSERT(hash2_from_reply != NULL); + + set_binary_property_value(hash_c1, "hash_c1", hash1_from_request->value._buffer, hash1_from_request->value._length); + set_binary_property_value(hash_c2, "hash_c2", hash2_from_reply->value._buffer, hash2_from_reply->value._length); + + printf("process: %s\n", hash_c1->name); + + /* Set the challenge in challenge1 property */ + if (challengeData) { + set_binary_property_value(challenge1, "challenge1", challengeData, challengeDataSize); + } else { + set_binary_property_value(challenge1, "challenge1x", challenge2->value._buffer, challenge2->value._length); + } + + /* Set the challenge in challenge2 property */ + if (challengeData2) { + set_binary_property_value(challenge2, "challenge2", challengeData2, challengeDataSize2); + } else { + set_binary_property_value(challenge2, "challenge2x", challenge2->value._buffer, challenge2->value._length); + } + + + /* Set the DH public key associated with the local participant in dh1 property */ + if (diffie_hellman1) { + set_binary_property_value(dh1, "dh1", diffie_hellman1->data, diffie_hellman1->length); + } else { + set_binary_property_string(dh1, "dh1x", "rubbish"); + } + + /* Set the DH public key associated with the local participant in dh2 property */ + if (diffie_hellman2) { + set_binary_property_value(dh2, "dh2", diffie_hellman2->data, diffie_hellman2->length); + } else { + set_binary_property_string(dh2, "dh2x", "rubbish"); + } + + /* Calculate the signature */ + { + BIO *bio; + EVP_PKEY *private_key_x509; + unsigned char *sign; + size_t signlen; + const DDS_Security_BinaryProperty_t * binary_properties[ HANDSHAKE_SIGNATURE_SIZE ]; + + /* load certificate in buffer */ + bio = BIO_new_mem_buf((const char *) bob_private_key, -1); + assert( bio ); + private_key_x509 = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + assert (private_key_x509 ); + + binary_properties[0] = hash_c1; + binary_properties[1] = challenge1; + binary_properties[2] = dh1; + binary_properties[3] = challenge2; + binary_properties[4] = dh2; + binary_properties[5] = hash_c2; + + if (create_signature_for_test(private_key_x509, binary_properties, HANDSHAKE_SIGNATURE_SIZE, &sign, &signlen, &exception) != DDS_SECURITY_VALIDATION_OK) + { + printf("Exception: %s\n", exception.message); + } + set_binary_property_value(signature, "signature", sign, (uint32_t)signlen); + + ddsrt_free(sign); + EVP_PKEY_free(private_key_x509); + BIO_free(bio); + } + token->class_id = ddsrt_strdup(AUTH_HANDSHAKE_FINAL_TOKEN_CLASS_ID); + token->binary_properties._length = token->binary_properties._maximum = 7; + token->binary_properties._buffer = tokens; + break; + } +} + + +static DDS_Security_boolean +on_revoke_identity_cb( dds_security_authentication_listener *instance, + const dds_security_authentication *plugin, + const DDS_Security_IdentityHandle handle) +{ + DDSRT_UNUSED_ARG( instance ); + DDSRT_UNUSED_ARG( plugin ); + if (identity_handle_for_callback1 == DDS_SECURITY_HANDLE_NIL) { + identity_handle_for_callback1 = handle; + } else if (identity_handle_for_callback2 == DDS_SECURITY_HANDLE_NIL) { + identity_handle_for_callback2 = handle; + } + printf( "Listener called for handle: %lld Local:%lld Remote:%lld\n", (long long) handle, (long long) local_identity_handle, (long long) remote_identity_handle2); + + return true; +} + + +/* sets listener for authentication expiry and checks if the listener triggered after a while */ +CU_Test(ddssec_builtin_listeners_auth, local_remote_set_before_validation) +{ + DDS_Security_PermissionsHandle result; + DDS_Security_PermissionsToken permissions_token; + DDS_Security_AuthenticatedPeerCredentialToken credential_token; + DDS_Security_SecurityException exception = {NULL, 0, 0}; + DDS_Security_long valid; + int r; + dds_duration_t time_left = DDS_MSECS(10000); + DDS_Security_boolean local_expired = false; + DDS_Security_boolean remote_expired = false; + DDS_Security_HandshakeHandle handshake_handle; + DDS_Security_HandshakeMessageToken handshake_reply_token_in = DDS_SECURITY_TOKEN_INIT; + DDS_Security_HandshakeMessageToken handshake_token_out = DDS_SECURITY_TOKEN_INIT; + DDS_Security_HandshakeMessageToken handshake_reply_token_out = DDS_SECURITY_TOKEN_INIT; + const DDS_Security_BinaryProperty_t *hash1_sent_in_request; + const DDS_Security_BinaryProperty_t *dh1; + const DDS_Security_BinaryProperty_t *challenge1_glb; + struct octet_seq dh1_pub_key; + char *remote_certificate_file; + + local_expiry_date = DDS_TIME_INVALID; + remote_expiry_date = DDS_TIME_INVALID; + + auth_listener.on_revoke_identity = &on_revoke_identity_cb; + + auth->set_listener( auth, &auth_listener, &exception); + access_control->set_listener( access_control, + &access_control_listener, + &exception); + + + valid = validate_local_identity_and_permissions( 3, &local_expiry_date); + if (valid == DDS_SECURITY_ERR_VALIDITY_PERIOD_EXPIRED_CODE) { + /* This can happen on very slow platforms or when doing a valgrind run. + * Just take our losses and quit, simulating a success. */ + return; + } + CU_ASSERT_FATAL (valid == DDS_SECURITY_ERR_OK_CODE); + + /*Generate remote certificate*/ + create_certificate_from_csr( bob_csr, 4, BOB_IDENTITY_CERT_FILE, &remote_expiry_date ); + + ddsrt_asprintf(&remote_certificate_file, "%s%s", g_path_build_dir, BOB_IDENTITY_CERT_FILE); + bob_identity_cert = load_file_contents( remote_certificate_file ); + + validate_remote_identity( bob_identity_cert ); + + + /* Check if we actually have validate_remote_permissions function. */ + CU_ASSERT_FATAL (access_control != NULL); + CU_ASSERT_FATAL (local_identity_handle != DDS_SECURITY_HANDLE_NIL); + CU_ASSERT_FATAL (access_control->validate_remote_permissions != NULL); + CU_ASSERT_FATAL (access_control->return_permissions_handle != NULL); + + fill_permissions_token(&permissions_token); + r = fill_peer_credential_token(&credential_token); + CU_ASSERT_FATAL (r); + + + + /*handshake*/ + result = auth->begin_handshake_request( + auth, + &handshake_handle, + &handshake_token_out, + local_identity_handle, + remote_identity_handle2, + &serialized_participant_data, + &exception); + + if (result != DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE) { + printf("begin_handshake_request failed: %s\n", exception.message ? exception.message : "Error message missing"); + } + + /* get challenge 1 from the message */ + challenge1_glb = find_binary_property(&handshake_token_out, "challenge1"); + + /*Get DH1 value */ + dh1 = find_binary_property(&handshake_token_out, "dh1"); + + hash1_sent_in_request = find_binary_property(&handshake_token_out, "hash_c1"); + + CU_ASSERT_FATAL(dh1 != NULL); + CU_ASSERT_FATAL(dh1->value._length > 0); + CU_ASSERT_FATAL(dh1->value._buffer != NULL); + + dh1_pub_key.data = dh1->value._buffer; + dh1_pub_key.length = dh1->value._length; + + /* prepare reply */ + fill_handshake_message_token( + &handshake_reply_token_in, remote_participant_data2, bob_identity_cert, + AUTH_DSIGN_ALGO_RSA_NAME, AUTH_KAGREE_ALGO_ECDH_NAME, + &dh1_pub_key, challenge1_glb->value._buffer, challenge1_glb->value._length, + &dh_ecdh_pub_key, challenge2_predefined_glb->value._buffer, challenge2_predefined_glb->value._length, hash1_sent_in_request, NULL, HANDSHAKE_REPLY); + + reset_exception(&exception); + + result = auth->process_handshake( + auth, + &handshake_reply_token_out, + &handshake_reply_token_in, + handshake_handle, + &exception); + + CU_ASSERT_FATAL(result == DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE); + CU_ASSERT(handshake_handle != DDS_SECURITY_HANDLE_NIL); + + result = access_control->validate_remote_permissions( + access_control, + auth, + local_identity_handle, + remote_identity_handle, + &permissions_token, + &credential_token, + &exception); + + if (result == 0) { + printf("validate_remote_permissions_failed: %s\n", exception.message ? exception.message : "Error message missing"); + //TODO: Clean-up before failing + CU_ASSERT_FATAL (exception.code == DDS_SECURITY_ERR_VALIDITY_PERIOD_EXPIRED_CODE); +// goto end; + + } + + remote_permissions_handle = result; + + reset_exception(&exception); + + while( time_left > 0 && (!local_expired || !remote_expired) ){ + /* Normally, it is expected that the remote expiry is triggered before the + * local one. However, that can change on slow platforms. */ + // TODO: Check for time compare + if (remote_expiry_date < local_expiry_date) { + if (identity_handle_for_callback1 == remote_identity_handle2) { + remote_expired = true; + } + if (identity_handle_for_callback2 == local_identity_handle) { + local_expired = true; + } + } else { + if (identity_handle_for_callback2 == remote_identity_handle2) { + remote_expired = true; + } + if (identity_handle_for_callback1 == local_identity_handle) { + local_expired = true; + } + } + + dds_sleepfor(DDS_MSECS(100)); + time_left -= DDS_MSECS(100); + } + + CU_ASSERT (local_expired); + CU_ASSERT (remote_expired); + + + reset_exception(&exception); + + result = auth->return_handshake_handle(auth, handshake_handle, &exception); + release_remote_identities(); + + DDS_Security_DataHolder_deinit((DDS_Security_DataHolder *) &permissions_token); + DDS_Security_DataHolder_deinit((DDS_Security_DataHolder *) &credential_token); + + + CU_ASSERT_TRUE (result == 1); + + reset_exception(&exception); + + DDS_Security_DataHolder_deinit(&handshake_token_out); + DDS_Security_DataHolder_deinit(&handshake_reply_token_in); + DDS_Security_DataHolder_deinit(&handshake_reply_token_out); + + clear_local_identity_and_permissions(); + ddsrt_free( bob_identity_cert ); + ddsrt_free ( remote_certificate_file ); +} diff --git a/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c b/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c index 9eaf2d1..5b2f5d6 100644 --- a/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c +++ b/src/security/builtin_plugins/tests/process_handshake/src/process_handshake_utests.c @@ -523,7 +523,7 @@ validate_local_identity(const char* trusted_ca_dir) char trusted_ca_dir_path[1024]; dds_security_property_init(&participant_qos.property.value, 4); #ifdef WIN32 - snprintf(trusted_ca_dir_path, 1024, "%s\\testsuite\\dbt\\security_plugin\\tests\\validate_begin_handshake_reply\\etc\\%s", CONFIG_ENV_TESTS_DIR,trusted_ca_dir); + snprintf(trusted_ca_dir_path, 1024, "%s\\validate_begin_handshake_reply\\etc\\%s", CONFIG_ENV_TESTS_DIR, trusted_ca_dir); #else snprintf(trusted_ca_dir_path, 1024, "%s/validate_begin_handshake_reply/etc/%s", CONFIG_ENV_TESTS_DIR, trusted_ca_dir); #endif diff --git a/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c b/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c index b3871db..90cb2a7 100644 --- a/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c +++ b/src/security/builtin_plugins/tests/validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c @@ -220,7 +220,7 @@ static const char *unrelated_identity = "B7DMeaVlLClGQaKZZ7aexEx9se+IyLn2\n" "-----END CERTIFICATE-----\n"; -#ifdef TRUSTED_CA_DIR_IMPLEMENTED + static const char *remote_identity_trusted = "-----BEGIN CERTIFICATE-----\n" "MIIDcDCCAligAwIBAgIBBTANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJOTDEL\n" @@ -297,7 +297,6 @@ static const char *remote_identity_trusted_expired = "O3gAjPUL0jzRztp5Yj3dYPV8YyJHLEKr75IXNedV9YKhT4f6kTS3UEjMTqYbYsix\n" "MtqgY283RjsExzjNvw==\n" "-----END CERTIFICATE-----\n"; -#endif static struct plugins_hdl *plugins = NULL; static dds_security_authentication *auth = NULL; @@ -1968,10 +1967,7 @@ CU_Test(ddssec_builtin_validate_begin_handshake_reply,return_handle, .init = in } -/*TODO: test is waiting for Trusted CA parsing function */ - -#if(0) -CU _ Test(validate_begin_handshake_reply,extended_certificate_check ) +CU_Test(validate_begin_handshake_reply,extended_certificate_check, .init = init_testcase, .fini = fini_testcase ) { DDS_Security_ValidationResult_t result; DDS_Security_HandshakeHandle handshake_handle; @@ -2107,4 +2103,3 @@ CU _ Test(validate_begin_handshake_reply,extended_certificate_check ) handshake_message_deinit(&handshake_token_out); reset_exception(&exception); } -#endif diff --git a/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c b/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c index 5d17ebd..59a5567 100644 --- a/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c +++ b/src/security/builtin_plugins/tests/validate_local_identity/src/validate_local_identity_utests.c @@ -2017,10 +2017,8 @@ CU_Test(ddssec_builtin_validate_local_identity,no_file) } -/* TODO: Should be enabled after implementing trusted ca dir parsing*/ -#if(0) -CU _ Test(validate_local_identity,with_extended_certificate_check) -{ +CU_Test(ddssec_builtin_validate_local_identity,with_extended_certificate_check) +{ DDS_Security_ValidationResult_t result; DDS_Security_IdentityHandle local_identity_handle = DDS_SECURITY_HANDLE_NIL; DDS_Security_GUID_t adjusted_participant_guid; @@ -2042,7 +2040,7 @@ CU _ Test(validate_local_identity,with_extended_certificate_check) fill_participant_qos(&participant_qos, false, identity_certificate, false, identity_ca, - false, private_key, + false, private_key_pem, NULL, "trusted_ca_dir"); /* Now call the function. */ @@ -2106,4 +2104,3 @@ CU _ Test(validate_local_identity,with_extended_certificate_check) } -#endif diff --git a/src/security/core/include/dds/security/core/dds_security_timed_cb.h b/src/security/core/include/dds/security/core/dds_security_timed_cb.h index 6a883d6..93b2eb4 100644 --- a/src/security/core/include/dds/security/core/dds_security_timed_cb.h +++ b/src/security/core/include/dds/security/core/dds_security_timed_cb.h @@ -25,7 +25,11 @@ extern "C" { */ struct dds_security_timed_dispatcher_t; -struct dds_security_timed_cb_data_t; +/** + * The timed callback structure holds a list of dispatchers and manages + * the thread that calls the dispatchers callbacks. + */ +struct dds_security_timed_cb_data; /** * The callback is triggered by two causes: diff --git a/src/security/core/src/dds_security_utils.c b/src/security/core/src/dds_security_utils.c index 8a5cef7..42610af 100644 --- a/src/security/core/src/dds_security_utils.c +++ b/src/security/core/src/dds_security_utils.c @@ -1291,3 +1291,4 @@ DDS_Security_parse_xml_date( return DDS_TIME_INVALID; } +