From 3ea2cea318d760aebaf43b99b73b441955fb91b5 Mon Sep 17 00:00:00 2001 From: Dennis Potman <45659984+dennis-adlink@users.noreply.github.com> Date: Wed, 18 Mar 2020 10:01:20 +0100 Subject: [PATCH] Code formatting fixes and clean-up authentication plugin (#439) * Fix code formatting, fix for memory leak in validate_handshake_reply_token and make error handling and return values more consistent with the other two plugins. Signed-off-by: Dennis Potman * Processed review comments: fixed memory leaks and more consistent error handling and function returns Signed-off-by: Dennis Potman * Fix trusted ca dir max exceeded Signed-off-by: Dennis Potman --- docs/manual/security.rst | 2 + .../dds/security/dds_security_api_err.h | 2 + .../authentication/src/auth_utils.c | 1961 +++---- .../authentication/src/auth_utils.h | 186 +- .../authentication/src/authentication.c | 5021 +++++++---------- .../authentication/src/authentication.h | 152 +- 6 files changed, 2914 insertions(+), 4410 deletions(-) diff --git a/docs/manual/security.rst b/docs/manual/security.rst index 078a013..725de07 100644 --- a/docs/manual/security.rst +++ b/docs/manual/security.rst @@ -793,6 +793,8 @@ dds_security_api_err.h header file contains the code and message constants. +-------+----------------------------------------------------------------+ | 151 | The payload is not aligned at 4 bytes | +-------+----------------------------------------------------------------+ +| 152 | Cannot open trusted CA directory: maximum number exceeded | ++-------+----------------------------------------------------------------+ | 200 | Undefined Error Message | +-------+----------------------------------------------------------------+ diff --git a/src/security/api/include/dds/security/dds_security_api_err.h b/src/security/api/include/dds/security/dds_security_api_err.h index 9246ba5..b93cc62 100644 --- a/src/security/api/include/dds/security/dds_security_api_err.h +++ b/src/security/api/include/dds/security/dds_security_api_err.h @@ -106,6 +106,8 @@ extern "C" { #define DDS_SECURITY_ERR_URI_TYPE_NOT_SUPPORTED_MESSAGE "Unsupported URI type: %s" #define DDS_SECURITY_ERR_INVALID_CRYPTO_DATA_NOT_ALIGNED_CODE 151 #define DDS_SECURITY_ERR_INVALID_CRYPTO_DATA_NOT_ALIGNED_MESSAGE "The payload is not aligned at 4 bytes" +#define DDS_SECURITY_ERR_TRUSTED_CA_DIR_MAX_EXCEEDED_CODE 152 +#define DDS_SECURITY_ERR_TRUSTED_CA_DIR_MAX_EXCEEDED_MESSAGE "Cannot open trusted CA directory: maximum number of CA directories (%d) exceeded" #define DDS_SECURITY_ERR_UNDEFINED_CODE 200 #define DDS_SECURITY_ERR_UNDEFINED_MESSAGE "Undefined Error Message" diff --git a/src/security/builtin_plugins/authentication/src/auth_utils.c b/src/security/builtin_plugins/authentication/src/auth_utils.c index ef9d768..54e94b2 100644 --- a/src/security/builtin_plugins/authentication/src/auth_utils.c +++ b/src/security/builtin_plugins/authentication/src/auth_utils.c @@ -10,6 +10,8 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ +#include +#include #include #include #include @@ -18,6 +20,7 @@ #include #include #include +#include #if OPENSSL_VERSION_NUMBER >= 0x1000200fL #define AUTH_INCLUDE_EC #include @@ -27,15 +30,17 @@ #else #error "OpenSSL version is not supported" #endif -#include #include "dds/ddsrt/time.h" #include "dds/ddsrt/heap.h" #include "dds/ddsrt/filesystem.h" #include "dds/ddsrt/retcode.h" +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/atomics.h" +#include "dds/ddsrt/string.h" +#include "dds/ddsrt/io.h" #include "dds/security/dds_security_api_defs.h" #include "dds/security/core/dds_security_utils.h" -#include - +#include "auth_utils.h" /* There is a problem when compiling on windows w.r.t. X509_NAME. * The windows api already defines the type X509_NAME which @@ -46,1329 +51,999 @@ #undef X509_NAME #endif -#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 * -get_openssl_error_message( - void) +char *get_openssl_error_message(void) { - BIO *bio = BIO_new(BIO_s_mem()); - char *msg; - char *buf = NULL; - size_t len; /*BIO_get_mem_data requires long int */ + char *msg, *buf = NULL; + size_t len; + BIO *bio = BIO_new(BIO_s_mem()); + if (!bio) + return ddsrt_strdup("BIO_new failed"); - if (bio) { - ERR_print_errors(bio); - len = (size_t)BIO_get_mem_data (bio, &buf); - msg = ddsrt_malloc(len + 1); - memcpy(msg, buf, len); - msg[len] = '\0'; - BIO_free(bio); - } else { - msg = ddsrt_strdup("BIO_new failed"); - } - - return msg; + ERR_print_errors(bio); + len = (size_t)BIO_get_mem_data(bio, &buf); + msg = ddsrt_malloc(len + 1); + memcpy(msg, buf, len); + msg[len] = '\0'; + BIO_free(bio); + return msg; } -char * -get_certificate_subject_name( - X509 *cert, - DDS_Security_SecurityException *ex) +char *get_certificate_subject_name(X509 *cert, DDS_Security_SecurityException *ex) { - X509_NAME *name; - char *subject = NULL; - char *subject_openssl = NULL; - - assert(cert); - - name = X509_get_subject_name(cert); - if (!name) { - goto err_get_subject; - } - - subject_openssl = X509_NAME_oneline( name, NULL, 0 ); - subject = ddsrt_strdup( subject_openssl ); - OPENSSL_free( subject_openssl ); - - return subject; - -err_get_subject: + X509_NAME *name; + assert(cert); + if (!(name = X509_get_subject_name(cert))) + { DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_get_subject_name failed : "); return NULL; + } + char *subject_openssl = X509_NAME_oneline(name, NULL, 0); + char *subject = ddsrt_strdup(subject_openssl); + OPENSSL_free(subject_openssl); + return subject; } -dds_time_t -get_certificate_expiry( - const X509 *cert) +dds_time_t get_certificate_expiry(const X509 *cert) { - dds_time_t expiry = DDS_TIME_INVALID; - ASN1_TIME *asn1; - - assert(cert); - - asn1 = X509_get_notAfter(cert); - if (asn1 != NULL) { - int days; - int seconds; - if (ASN1_TIME_diff(&days, &seconds, NULL, asn1) == 1 ) { - static const dds_duration_t secs_in_day = 86400; - const dds_time_t now = dds_time(); - const int64_t max_valid_days_to_wait = (INT64_MAX - now) / DDS_NSECS_IN_SEC / secs_in_day; - - if ( days < max_valid_days_to_wait ){ - dds_duration_t delta = ((dds_duration_t)seconds + ((dds_duration_t)days * secs_in_day)) * DDS_NSECS_IN_SEC; - expiry = now + delta; - } else { - return DDS_NEVER; - } - } + assert(cert); + ASN1_TIME *asn1 = X509_get_notAfter(cert); + if (asn1 != NULL) + { + int days, seconds; + if (ASN1_TIME_diff(&days, &seconds, NULL, asn1) == 1) + { + static const dds_duration_t secs_in_day = 86400; + const dds_time_t now = dds_time(); + const int64_t max_valid_days_to_wait = (INT64_MAX - now) / DDS_NSECS_IN_SEC / secs_in_day; + if (days < max_valid_days_to_wait) + { + dds_duration_t delta = ((dds_duration_t)seconds + ((dds_duration_t)days * secs_in_day)) * DDS_NSECS_IN_SEC; + return now + delta; + } + return DDS_NEVER; } - - return expiry; + } + return DDS_TIME_INVALID; } -DDS_Security_ValidationResult_t -get_subject_name_DER_encoded( - const X509 *cert, - unsigned char **buffer, - size_t *size, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t get_subject_name_DER_encoded(const X509 *cert, unsigned char **buffer, size_t *size, DDS_Security_SecurityException *ex) { - unsigned char *tmp = NULL; - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_FAILED; - int32_t sz; - X509_NAME *name; + unsigned char *tmp = NULL; + int32_t sz; + X509_NAME *name; - assert(cert); - assert(buffer); - assert(size); + assert(cert); + assert(buffer); + assert(size); - *size = 0; + *size = 0; + if (!(name = X509_get_subject_name((X509 *)cert))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_get_subject_name failed : "); + return DDS_SECURITY_VALIDATION_FAILED; + } + if ((sz = i2d_X509_NAME(name, &tmp)) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "i2d_X509_NAME failed : "); + return DDS_SECURITY_VALIDATION_FAILED; + } - name = X509_get_subject_name((X509 *)cert); - if (name) { - sz = i2d_X509_NAME(name, &tmp); - if (sz > 0) { - *size = (size_t)sz; - *buffer = ddsrt_malloc(*size); - memcpy(*buffer, tmp, *size); - OPENSSL_free(tmp); - result = DDS_SECURITY_VALIDATION_OK; - } else if (sz < 0) { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "i2d_X509_NAME failed : "); - } - } else { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_get_subject_name failed : "); - } - - return result; + *size = (size_t)sz; + *buffer = ddsrt_malloc(*size); + memcpy(*buffer, tmp, *size); + OPENSSL_free(tmp); + return DDS_SECURITY_VALIDATION_OK; } - -static DDS_Security_ValidationResult_t -check_key_type_and_size( - EVP_PKEY *key, - int isPrivate, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t check_key_type_and_size(EVP_PKEY *key, int isPrivate, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - const char *sub = isPrivate ? "private key" : "certificate"; - - assert(key); - - switch (EVP_PKEY_id(key)) { - case EVP_PKEY_RSA: - if (EVP_PKEY_bits(key) != 2048) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "RSA %s has unsupported key size (%d)", sub, EVP_PKEY_bits(key)); - } else if (isPrivate) { - RSA *rsaKey = EVP_PKEY_get1_RSA(key); - if (rsaKey) { - if (RSA_check_key(rsaKey) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "RSA key not correct : "); - } - } - RSA_free(rsaKey); - } - break; - case EVP_PKEY_EC: - if (EVP_PKEY_bits(key) != 256) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "EC %s has unsupported key size (%d)", sub, EVP_PKEY_bits(key)); - } else { - EC_KEY *ecKey = EVP_PKEY_get1_EC_KEY(key); - if (ecKey) { - if (EC_KEY_check_key(ecKey) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "EC key not correct : "); - } - } - EC_KEY_free(ecKey); - } - break; - default: - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "%s has not supported type", sub); - break; + const char *sub = isPrivate ? "private key" : "certificate"; + assert(key); + switch (EVP_PKEY_id(key)) + { + case EVP_PKEY_RSA: + if (EVP_PKEY_bits(key) != 2048) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "RSA %s has unsupported key size (%d)", sub, EVP_PKEY_bits(key)); + return DDS_SECURITY_VALIDATION_FAILED; } + if (isPrivate) + { + RSA *rsaKey = EVP_PKEY_get0_RSA(key); + if (rsaKey && RSA_check_key(rsaKey) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "RSA key not correct : "); + return DDS_SECURITY_VALIDATION_FAILED; + } + } + return DDS_SECURITY_VALIDATION_OK; - return result; + case EVP_PKEY_EC: + if (EVP_PKEY_bits(key) != 256) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EC %s has unsupported key size (%d)", sub, EVP_PKEY_bits(key)); + return DDS_SECURITY_VALIDATION_FAILED; + } + EC_KEY *ecKey = EVP_PKEY_get0_EC_KEY(key); + if (ecKey && EC_KEY_check_key(ecKey) != 1) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "EC key not correct : "); + return DDS_SECURITY_VALIDATION_FAILED; + } + return DDS_SECURITY_VALIDATION_OK; + + default: + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "%s has not supported type", sub); + return DDS_SECURITY_VALIDATION_FAILED; + } } -static DDS_Security_ValidationResult_t -check_certificate_type_and_size( - X509 *cert, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t check_certificate_type_and_size(X509 *cert, DDS_Security_SecurityException *ex) { - EVP_PKEY *pkey; - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - - assert(cert); - - pkey = X509_get_pubkey(cert); - if (pkey) { - result = check_key_type_and_size(pkey, false, ex); - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "X509_get_pubkey failed"); - } - EVP_PKEY_free(pkey); - - return result; + assert(cert); + EVP_PKEY *pkey = X509_get_pubkey(cert); + if (!pkey) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_get_pubkey failed"); + return DDS_SECURITY_VALIDATION_FAILED; + } + DDS_Security_ValidationResult_t result = check_key_type_and_size(pkey, false, ex); + EVP_PKEY_free(pkey); + return result; } -DDS_Security_ValidationResult_t -check_certificate_expiry( - const X509 *cert, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t check_certificate_expiry(const X509 *cert, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - - assert(cert); - - if( X509_cmp_current_time(X509_get_notBefore( cert )) == 0 ){ - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_STARTDATE_IN_FUTURE_CODE, (int)result, DDS_SECURITY_ERR_CERT_STARTDATE_IN_FUTURE_MESSAGE); - - } - if( X509_cmp_current_time(X509_get_notAfter( cert )) == 0 ){ - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_EXPIRED_CODE, (int)result, DDS_SECURITY_ERR_CERT_EXPIRED_MESSAGE); - - } - - return result; + assert(cert); + if (X509_cmp_current_time(X509_get_notBefore(cert)) == 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_STARTDATE_IN_FUTURE_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_CERT_STARTDATE_IN_FUTURE_MESSAGE); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (X509_cmp_current_time(X509_get_notAfter(cert)) == 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_EXPIRED_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_CERT_EXPIRED_MESSAGE); + return DDS_SECURITY_VALIDATION_FAILED; + } + return DDS_SECURITY_VALIDATION_OK; } - -DDS_Security_ValidationResult_t -load_X509_certificate_from_data( - const char *data, - int len, - X509 **x509Cert, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t load_X509_certificate_from_data(const char *data, int len, X509 **x509Cert, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - BIO *bio; + BIO *bio; + assert(data); + assert(len >= 0); + assert(x509Cert); - assert(data); - assert(len >= 0); - assert(x509Cert); - - /* load certificate in buffer */ - bio = BIO_new_mem_buf((void *) data, len); - if (!bio) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "BIO_new_mem_buf failed"); - goto err_bio_alloc; - } - - *x509Cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); - if (!(*x509Cert)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to parse certificate: "); - goto err_cert_read; - } - - /* check authentication algorithm */ - if( get_auhentication_algo_kind( *x509Cert ) == AUTH_ALGO_KIND_UNKNOWN ){ - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_CODE, (int)result, - DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_MESSAGE); - X509_free(*x509Cert); - goto err_cert_read; - } - -err_cert_read: + if (!(bio = BIO_new_mem_buf((void *)data, len))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "BIO_new_mem_buf failed"); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (!(*x509Cert = PEM_read_bio_X509(bio, NULL, NULL, NULL))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to parse certificate: "); BIO_free(bio); -err_bio_alloc: - return result; + return DDS_SECURITY_VALIDATION_FAILED; + } + BIO_free(bio); + + if (get_authentication_algo_kind(*x509Cert) == AUTH_ALGO_KIND_UNKNOWN) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_MESSAGE); + X509_free(*x509Cert); + return DDS_SECURITY_VALIDATION_FAILED; + } + + return DDS_SECURITY_VALIDATION_OK; } - - -DDS_Security_ValidationResult_t -load_X509_certificate_from_file( - const char *filename, - X509 **x509Cert, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t load_X509_certificate_from_file(const char *filename, X509 **x509Cert, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - FILE *file_ptr; + assert(filename); + assert(x509Cert); - assert(filename); - assert(x509Cert); - - /*check the file*/ DDSRT_WARNING_MSVC_OFF(4996); - file_ptr = fopen( filename, "r"); + FILE *file_ptr = fopen(filename, "r"); DDSRT_WARNING_MSVC_ON(4996); - if( file_ptr == NULL ){ - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_FILE_PATH_CODE, (int)result, DDS_SECURITY_ERR_INVALID_FILE_PATH_MESSAGE, filename); - goto err_invalid_path; - } + if (file_ptr == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_FILE_PATH_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_INVALID_FILE_PATH_MESSAGE, filename); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (!(*x509Cert = PEM_read_X509(file_ptr, NULL, NULL, NULL))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to parse certificate: "); + (void)fclose(file_ptr); + return DDS_SECURITY_VALIDATION_FAILED; + } + (void)fclose(file_ptr); - /*load certificate from file*/ - *x509Cert = PEM_read_X509(file_ptr,NULL,NULL,NULL); - if (!(*x509Cert)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to parse certificate: "); - goto err_invalid_content; - } + if (get_authentication_algo_kind(*x509Cert) == AUTH_ALGO_KIND_UNKNOWN) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_MESSAGE); + X509_free(*x509Cert); + return DDS_SECURITY_VALIDATION_FAILED; + } - /* check authentication algorithm */ - if( get_auhentication_algo_kind( *x509Cert ) == AUTH_ALGO_KIND_UNKNOWN ){ - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_CODE, (int)result, - DDS_SECURITY_ERR_CERT_AUTH_ALGO_KIND_UNKNOWN_MESSAGE); - X509_free(*x509Cert); - goto err_invalid_content; - } - - -err_invalid_content: - (void)fclose( file_ptr ); -err_invalid_path: - - return result; + return DDS_SECURITY_VALIDATION_OK; } -static DDS_Security_ValidationResult_t -load_private_key_from_data( - const char *data, - const char *password, - EVP_PKEY **privateKey, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t load_private_key_from_data(const char *data, const char *password, EVP_PKEY **privateKey, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - BIO *bio; - const char *pw = (password ? password : ""); + BIO *bio; + assert(data); + assert(privateKey); - assert(data); - assert(privateKey); - - /* load certificate in buffer */ - bio = BIO_new_mem_buf((void *) data, -1); - if (!bio) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "BIO_new_mem_buf failed"); - goto err_bio_alloc; - } - - *privateKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)pw); - if (!(*privateKey)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to parse private key: "); - goto err_key_read; - } - -err_key_read: + if (!(bio = BIO_new_mem_buf((void *)data, -1))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "BIO_new_mem_buf failed"); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (!(*privateKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)(password ? password : "")))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to parse private key: "); BIO_free(bio); -err_bio_alloc: - return result; + return DDS_SECURITY_VALIDATION_FAILED; + } + + BIO_free(bio); + return DDS_SECURITY_VALIDATION_OK; } - -static DDS_Security_ValidationResult_t -load_private_key_from_file( - const char *filepath, - const char *password, - EVP_PKEY **privateKey, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t load_private_key_from_file(const char *filepath, const char *password, EVP_PKEY **privateKey, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - const char *pw = (password ? password : ""); - FILE *file_ptr; + FILE *file_ptr; + assert(filepath); + assert(privateKey); - assert(filepath); - assert(privateKey); - - /*check the file*/ DDSRT_WARNING_MSVC_OFF(4996); - file_ptr = fopen( filepath, "r"); + file_ptr = fopen(filepath, "r"); DDSRT_WARNING_MSVC_ON(4996); + if (file_ptr == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_FILE_PATH_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_INVALID_FILE_PATH_MESSAGE, filepath); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (!(*privateKey = PEM_read_PrivateKey(file_ptr, NULL, NULL, (void *)(password ? password : "")))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to parse certificate: "); + (void)fclose(file_ptr); + return DDS_SECURITY_VALIDATION_FAILED; + } - if( file_ptr == NULL ){ - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_FILE_PATH_CODE, (int)result, DDS_SECURITY_ERR_INVALID_FILE_PATH_MESSAGE, filepath); - goto err_invalid_path; - } - - /*load private key from file*/ - *privateKey = PEM_read_PrivateKey(file_ptr, NULL, NULL, (void *)pw); - if (!(*privateKey)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to parse certificate: "); - goto err_invalid_content; - } - -err_invalid_content: - (void)fclose( file_ptr ); -err_invalid_path: - - return result; + (void)fclose(file_ptr); + return DDS_SECURITY_VALIDATION_OK; } - /* * Gets the URI string (as referred in DDS Security spec) and returns the URI type * data: data part of the URI. Typically It contains different format according to URI type. */ -AuthConfItemPrefix_t -get_conf_item_type( - const char *str, - char **data) +AuthConfItemPrefix_t get_conf_item_type(const char *str, char **data) { - AuthConfItemPrefix_t kind = AUTH_CONF_ITEM_PREFIX_UNKNOWN; - const char *AUTH_CONF_FILE_PREFIX = "file:"; - const char *AUTH_CONF_DATA_PREFIX = "data:,"; - const char *AUTH_CONF_PKCS11_PREFIX = "pkcs11:"; - size_t AUTH_CONF_FILE_PREFIX_LEN = strlen(AUTH_CONF_FILE_PREFIX); - size_t AUTH_CONF_DATA_PREFIX_LEN = strlen(AUTH_CONF_DATA_PREFIX); - size_t AUTH_CONF_PKCS11_PREFIX_LEN = strlen(AUTH_CONF_PKCS11_PREFIX); - char *ptr; + const char *f = "file:", *d = "data:,", *p = "pkcs11:"; + size_t sf = strlen(f), sd = strlen(d), sp = strlen(p); + assert(str); + assert(data); - assert(str); - assert(data); + char *ptr = ddssec_strchrs(str, " \t", false); + if (strncmp(ptr, f, sf) == 0) + { + size_t e = strncmp(ptr + sf, "//", 2) == 0 ? 2 : 0; + *data = ddsrt_strdup(ptr + sf + e); + return AUTH_CONF_ITEM_PREFIX_FILE; + } + if (strncmp(ptr, d, sd) == 0) + { + *data = ddsrt_strdup(ptr + sd); + return AUTH_CONF_ITEM_PREFIX_DATA; + } + if (strncmp(ptr, p, sp) == 0) + { + *data = ddsrt_strdup(ptr + sp); + return AUTH_CONF_ITEM_PREFIX_PKCS11; + } - ptr = ddssec_strchrs(str, " \t", false); - - if (strncmp(ptr, AUTH_CONF_FILE_PREFIX, AUTH_CONF_FILE_PREFIX_LEN) == 0) { - const char *DOUBLE_SLASH = "//"; - size_t DOUBLE_SLASH_LEN = 2; - if (strncmp(&(ptr[AUTH_CONF_FILE_PREFIX_LEN]), DOUBLE_SLASH, DOUBLE_SLASH_LEN) == 0) { - *data = ddsrt_strdup(&(ptr[AUTH_CONF_FILE_PREFIX_LEN + DOUBLE_SLASH_LEN])); - } else { - *data = ddsrt_strdup(&(ptr[AUTH_CONF_FILE_PREFIX_LEN])); - } - kind = AUTH_CONF_ITEM_PREFIX_FILE; - } else if (strncmp(ptr, AUTH_CONF_DATA_PREFIX, AUTH_CONF_DATA_PREFIX_LEN) == 0) { - kind = AUTH_CONF_ITEM_PREFIX_DATA; - *data = ddsrt_strdup(&(ptr[AUTH_CONF_DATA_PREFIX_LEN])); - } else if (strncmp(ptr, AUTH_CONF_PKCS11_PREFIX, AUTH_CONF_PKCS11_PREFIX_LEN) == 0) { - kind = AUTH_CONF_ITEM_PREFIX_PKCS11; - *data = ddsrt_strdup(&(ptr[AUTH_CONF_PKCS11_PREFIX_LEN])); - } - - return kind; + return AUTH_CONF_ITEM_PREFIX_UNKNOWN; } -DDS_Security_ValidationResult_t -load_X509_certificate( - const char *data, - X509 **x509Cert, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t load_X509_certificate(const char *data, X509 **x509Cert, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - char *contents = NULL; + DDS_Security_ValidationResult_t result; + char *contents = NULL; + assert(data); + assert(x509Cert); - assert(data); - assert(x509Cert); + switch (get_conf_item_type(data, &contents)) + { + case AUTH_CONF_ITEM_PREFIX_FILE: + result = load_X509_certificate_from_file(contents, x509Cert, ex); + break; + case AUTH_CONF_ITEM_PREFIX_DATA: + result = load_X509_certificate_from_data(contents, (int)strlen(contents), x509Cert, ex); + break; + case AUTH_CONF_ITEM_PREFIX_PKCS11: + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Certificate pkcs11 format currently not supported:\n%s", data); + break; + default: + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Specified certificate has wrong format:\n%s", data); + break; + } + ddsrt_free(contents); - switch (get_conf_item_type(data, &contents)) { - case AUTH_CONF_ITEM_PREFIX_FILE: - result = load_X509_certificate_from_file(contents, x509Cert, ex); - break; - case AUTH_CONF_ITEM_PREFIX_DATA: - result = load_X509_certificate_from_data(contents, (int)strlen(contents), x509Cert, ex); - break; - case AUTH_CONF_ITEM_PREFIX_PKCS11: - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Certificate pkcs11 format currently not supported:\n%s", data); - break; - default: - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Specified certificate has wrong format:\n%s", data); - break; + if (result == DDS_SECURITY_VALIDATION_OK) + { + if (check_certificate_type_and_size(*x509Cert, ex) != DDS_SECURITY_VALIDATION_OK || + check_certificate_expiry(*x509Cert, ex) != DDS_SECURITY_VALIDATION_OK) + { + result = DDS_SECURITY_VALIDATION_FAILED; + X509_free(*x509Cert); } - ddsrt_free(contents); - - if (result == DDS_SECURITY_VALIDATION_OK) { - if ( check_certificate_type_and_size(*x509Cert, ex) != DDS_SECURITY_VALIDATION_OK || - check_certificate_expiry(*x509Cert, ex) != DDS_SECURITY_VALIDATION_OK - ) { - result = DDS_SECURITY_VALIDATION_FAILED; - X509_free(*x509Cert); - } - } - return result; + } + return result; } -DDS_Security_ValidationResult_t -load_X509_private_key( - const char *data, - const char *password, - EVP_PKEY **privateKey, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t load_X509_private_key(const char *data, const char *password, EVP_PKEY **privateKey, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - char *contents = NULL; + DDS_Security_ValidationResult_t result; + char *contents = NULL; + assert(data); + assert(privateKey); - assert(data); - assert(privateKey); + switch (get_conf_item_type(data, &contents)) + { + case AUTH_CONF_ITEM_PREFIX_FILE: + result = load_private_key_from_file(contents, password, privateKey, ex); + break; + case AUTH_CONF_ITEM_PREFIX_DATA: + result = load_private_key_from_data(contents, password, privateKey, ex); + break; + case AUTH_CONF_ITEM_PREFIX_PKCS11: + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "PrivateKey pkcs11 format currently not supported:\n%s", data); + break; + default: + result = DDS_SECURITY_VALIDATION_FAILED; + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Specified PrivateKey has wrong format:\n%s", data); + break; + } + ddsrt_free(contents); - switch (get_conf_item_type(data, &contents)) { - case AUTH_CONF_ITEM_PREFIX_FILE: - result = load_private_key_from_file(contents, password, privateKey, ex); - break; - case AUTH_CONF_ITEM_PREFIX_DATA: - result = load_private_key_from_data(contents, password, privateKey, ex); - break; - case AUTH_CONF_ITEM_PREFIX_PKCS11: - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "PrivateKey pkcs11 format currently not supported:\n%s", data); - break; - default: - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Specified PrivateKey has wrong format:\n%s", data); - break; + if (result == DDS_SECURITY_VALIDATION_OK) + { + if (check_key_type_and_size(*privateKey, true, ex) != DDS_SECURITY_VALIDATION_OK) + { + result = DDS_SECURITY_VALIDATION_FAILED; + EVP_PKEY_free(*privateKey); } - ddsrt_free(contents); + } - if (result == DDS_SECURITY_VALIDATION_OK) { - if ((result = check_key_type_and_size(*privateKey, true, ex)) != DDS_SECURITY_VALIDATION_OK) { - EVP_PKEY_free(*privateKey); - } - } - - return result; + return result; } -DDS_Security_ValidationResult_t -verify_certificate( - X509 *identityCert, - X509 *identityCa, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t verify_certificate(X509 *identityCert, X509 *identityCa, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - int r; - X509_STORE *store; - X509_STORE_CTX *ctx; + X509_STORE_CTX *ctx; + X509_STORE *store; + assert(identityCert); + assert(identityCa); + /* Currently only a self signed indentiyCa is supported. Verification of against a certificate chain is not yet supported */ + /* Verification of the certificate expiry using a CRL is not yet supported */ - - assert(identityCert); - assert(identityCa); - - /* Currently only a self signed indentiyCa is supported */ - /* Verification of against a certificate chain is not yet supported */ - /* Verification of the certificate expiry using a CRL is not yet supported */ - - store = X509_STORE_new(); - - - if (!store) { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "X509_STORE_new failed : "); - goto err_store_new; - } - - if (X509_STORE_add_cert(store, identityCa) != 1) { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "X509_STORE_add_cert failed : "); - goto err_add_cert; - } - - ctx = X509_STORE_CTX_new(); - if (!ctx) { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "X509_STORE_CTX_new failed : "); - goto err_ctx_new; - } - - if (X509_STORE_CTX_init(ctx, store, identityCert, NULL) != 1) { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "X509_STORE_CTX_init failed : "); - goto err_ctx_init; - } - - r = X509_verify_cert(ctx); - if (r != 1) { - const char *msg = X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)); - char *subject = NULL; - - result = DDS_SECURITY_VALIDATION_FAILED; - subject = get_certificate_subject_name(identityCert, NULL); - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Certificate not valid: error: %s subject: %s", msg, subject ? subject : "not found"); - ddsrt_free(subject); - } + if (!(store = X509_STORE_new())) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_STORE_new failed : "); + goto err_store_new; + } + if (X509_STORE_add_cert(store, identityCa) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_STORE_add_cert failed : "); + goto err_add_cert; + } + if (!(ctx = X509_STORE_CTX_new())) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_STORE_CTX_new failed : "); + goto err_ctx_new; + } + if (X509_STORE_CTX_init(ctx, store, identityCert, NULL) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_STORE_CTX_init failed : "); + goto err_ctx_init; + } + if (X509_verify_cert(ctx) != 1) + { + const char *msg = X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)); + char *subject = get_certificate_subject_name(identityCert, NULL); + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Certificate not valid: error: %s; subject: %s", msg, subject ? subject : "[not found]"); + ddsrt_free(subject); + goto err_ctx_init; + } + X509_STORE_CTX_free(ctx); + X509_STORE_free(store); + return DDS_SECURITY_VALIDATION_OK; err_ctx_init: - X509_STORE_CTX_free(ctx); + X509_STORE_CTX_free(ctx); err_ctx_new: err_add_cert: - X509_STORE_free(store); + X509_STORE_free(store); err_store_new: - return result; + return DDS_SECURITY_VALIDATION_FAILED; } -AuthenticationAlgoKind_t -get_auhentication_algo_kind( - X509 *cert) +AuthenticationAlgoKind_t get_authentication_algo_kind(X509 *cert) { - AuthenticationAlgoKind_t kind = AUTH_ALGO_KIND_UNKNOWN; - EVP_PKEY *pkey; - - assert(cert); - - pkey = X509_get_pubkey(cert); - - if (pkey) { - switch (EVP_PKEY_id(pkey)) { - case EVP_PKEY_RSA: - if (EVP_PKEY_bits(pkey) == 2048) { - kind = AUTH_ALGO_KIND_RSA_2048; - } - break; - case EVP_PKEY_EC: - if (EVP_PKEY_bits(pkey) == 256) { - kind = AUTH_ALGO_KIND_EC_PRIME256V1; - } - break; - default: - break; - } - EVP_PKEY_free(pkey); + AuthenticationAlgoKind_t kind = AUTH_ALGO_KIND_UNKNOWN; + assert(cert); + EVP_PKEY *pkey = X509_get_pubkey(cert); + if (pkey) + { + switch (EVP_PKEY_id(pkey)) + { + case EVP_PKEY_RSA: + if (EVP_PKEY_bits(pkey) == 2048) + kind = AUTH_ALGO_KIND_RSA_2048; + break; + case EVP_PKEY_EC: + if (EVP_PKEY_bits(pkey) == 256) + kind = AUTH_ALGO_KIND_EC_PRIME256V1; + break; } - - return kind; + EVP_PKEY_free(pkey); + } + return kind; } -AuthenticationChallenge * -generate_challenge( - DDS_Security_SecurityException *ex) +AuthenticationChallenge * generate_challenge(DDS_Security_SecurityException *ex) { - AuthenticationChallenge *result; - - result = ddsrt_malloc(sizeof(*result)); - if (RAND_bytes(result->value, sizeof(result->value)) < 0 ) { - - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "Failed to generate a 256 bit random number "); - ddsrt_free(result); - result = NULL; - } - - return result; + AuthenticationChallenge *result = ddsrt_malloc(sizeof(*result)); + if (RAND_bytes(result->value, sizeof(result->value)) < 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to generate a 256 bit random number "); + ddsrt_free(result); + return NULL; + } + return result; } -DDS_Security_ValidationResult_t -get_certificate_contents( - X509 *cert, - unsigned char **data, - uint32_t *size, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t get_certificate_contents(X509 *cert, unsigned char **data, uint32_t *size, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - BIO *bio = NULL; - size_t sz; - char *ptr; + BIO *bio = NULL; + char *ptr; + if ((bio = BIO_new(BIO_s_mem())) == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "BIO_new_mem_buf failed"); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (!PEM_write_bio_X509(bio, cert)) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "PEM_write_bio_X509 failed: "); + BIO_free(bio); + return DDS_SECURITY_VALIDATION_FAILED; + } - if ((bio = BIO_new(BIO_s_mem())) == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "BIO_new_mem_buf failed"); - } else if (!PEM_write_bio_X509(bio, cert)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "PEM_write_bio_X509 failed: "); - } else { - sz = (size_t)BIO_get_mem_data(bio, &ptr); - *data = ddsrt_malloc(sz +1); - memcpy(*data, ptr, sz); - (*data)[sz] = '\0'; - *size = (uint32_t)sz; - } - - if (bio) BIO_free(bio); - - return result; + size_t sz = (size_t)BIO_get_mem_data(bio, &ptr); + *data = ddsrt_malloc(sz + 1); + memcpy(*data, ptr, sz); + (*data)[sz] = '\0'; + *size = (uint32_t)sz; + BIO_free(bio); + return DDS_SECURITY_VALIDATION_OK; } -static DDS_Security_ValidationResult_t -get_rsa_dh_parameters( - EVP_PKEY **params, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t get_rsa_dh_parameters(EVP_PKEY **params, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - DH *dh = NULL; + DH *dh = NULL; + *params = NULL; + if ((*params = EVP_PKEY_new()) == NULL) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate DH generation parameters: "); + return DDS_SECURITY_VALIDATION_FAILED; + } + if ((dh = DH_get_2048_256()) == NULL) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate DH parameter using DH_get_2048_256: "); + EVP_PKEY_free(*params); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (EVP_PKEY_set1_DH(*params, dh) <= 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to set DH generation parameters using EVP_PKEY_set1_DH: "); + EVP_PKEY_free(*params); + DH_free(dh); + return DDS_SECURITY_VALIDATION_FAILED; + } - *params = NULL; - - if ((*params = EVP_PKEY_new()) == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to allocate DH generation parameters: "); - } else if ((dh = DH_get_2048_256()) == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to allocate DH parameter using DH_get_2048_256: "); - } else if (EVP_PKEY_set1_DH(*params, dh) <= 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to set DH generation parameters using EVP_PKEY_set1_DH: "); - EVP_PKEY_free(*params); - } - - if (dh) DH_free(dh); - - return result; + DH_free(dh); + return DDS_SECURITY_VALIDATION_OK; } -static DDS_Security_ValidationResult_t -get_ec_dh_parameters( - EVP_PKEY **params, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t get_ec_dh_parameters(EVP_PKEY **params, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate DH parameter context: "); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (EVP_PKEY_paramgen_init(pctx) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to initialize DH generation context: "); + EVP_PKEY_CTX_free(pctx); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to set DH generation parameter generation method: "); + EVP_PKEY_CTX_free(pctx); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (EVP_PKEY_paramgen(pctx, params) <= 0) + { + char *msg = get_openssl_error_message(); + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to generate DH parameters: "); + ddsrt_free(msg); + EVP_PKEY_CTX_free(pctx); + return DDS_SECURITY_VALIDATION_FAILED; + } - if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to allocate DH parameter context: "); - } else if (EVP_PKEY_paramgen_init(pctx) <= 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to initialize DH generation context: "); - } else if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1) <= 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to set DH generation parameter generation method: "); - } else if (EVP_PKEY_paramgen(pctx, params) <= 0) { - char *msg = get_openssl_error_message(); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to generate DH parameters: "); - ddsrt_free(msg); - } - - if (pctx) EVP_PKEY_CTX_free(pctx); - - return result; + EVP_PKEY_CTX_free(pctx); + return DDS_SECURITY_VALIDATION_OK; } - -DDS_Security_ValidationResult_t -generate_dh_keys( - EVP_PKEY **dhkey, - AuthenticationAlgoKind_t authKind, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t generate_dh_keys(EVP_PKEY **dhkey, AuthenticationAlgoKind_t authKind, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_FAILED; - EVP_PKEY *params = NULL; - EVP_PKEY_CTX *kctx = NULL; + EVP_PKEY *params = NULL; + EVP_PKEY_CTX *kctx = NULL; + *dhkey = NULL; + switch (authKind) + { + case AUTH_ALGO_KIND_RSA_2048: + if (get_rsa_dh_parameters(¶ms, ex) != DDS_SECURITY_VALIDATION_OK) + goto failed; + break; + case AUTH_ALGO_KIND_EC_PRIME256V1: + if (get_ec_dh_parameters(¶ms, ex) != DDS_SECURITY_VALIDATION_OK) + goto failed; + break; + default: + assert(0); + goto failed; + } - *dhkey = NULL; + if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate DH generation context: "); + goto failed_params; + } + if (EVP_PKEY_keygen_init(kctx) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to initialize DH generation context: "); + goto failed_kctx; + } + if (EVP_PKEY_keygen(kctx, dhkey) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to generate DH key pair: "); + goto failed_kctx; + } + EVP_PKEY_CTX_free(kctx); + EVP_PKEY_free(params); + return DDS_SECURITY_VALIDATION_OK; - switch(authKind) { - case AUTH_ALGO_KIND_RSA_2048: - result = get_rsa_dh_parameters(¶ms, ex); - break; - case AUTH_ALGO_KIND_EC_PRIME256V1: - result = get_ec_dh_parameters(¶ms, ex); - break; - default: - assert(0); - break; - } - - if (result != DDS_SECURITY_VALIDATION_OK) { - return result; - } else if ((kctx = EVP_PKEY_CTX_new(params, NULL)) == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to allocate DH generation context: "); - } else if (EVP_PKEY_keygen_init(kctx) <= 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to initialize DH generation context: "); - } else if (EVP_PKEY_keygen(kctx, dhkey) <= 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "Failed to generate DH key pair: "); - } - - if (kctx) EVP_PKEY_CTX_free(kctx); - if (params) EVP_PKEY_free(params); - - return result; +failed_kctx: + EVP_PKEY_CTX_free(kctx); +failed_params: + EVP_PKEY_free(params); +failed: + return DDS_SECURITY_VALIDATION_FAILED; } -static const BIGNUM * -dh_get_public_key( - DH *dhkey) +static const BIGNUM *dh_get_public_key(DH *dhkey) { #ifdef AUTH_INCLUDE_DH_ACCESSORS - const BIGNUM *pubkey, *privkey; - DH_get0_key(dhkey, &pubkey, &privkey); - return pubkey; + const BIGNUM *pubkey, *privkey; + DH_get0_key(dhkey, &pubkey, &privkey); + return pubkey; #else - return dhkey->pub_key; + return dhkey->pub_key; #endif } -static int -dh_set_public_key( - DH *dhkey, - BIGNUM *pubkey) +static int dh_set_public_key(DH *dhkey, BIGNUM *pubkey) { #ifdef AUTH_INCLUDE_DH_ACCESSORS - return DH_set0_key(dhkey, pubkey, NULL); + return DH_set0_key(dhkey, pubkey, NULL); #else - dhkey->pub_key = pubkey; + dhkey->pub_key = pubkey; #endif - return 1; + return 1; } -static DDS_Security_ValidationResult_t -dh_public_key_to_oct_modp( - EVP_PKEY *pkey, - unsigned char **buffer, - uint32_t *length, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t dh_public_key_to_oct_modp(EVP_PKEY *pkey, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - DH *dhkey; - ASN1_INTEGER *asn1int; - - *buffer = NULL; - - dhkey = EVP_PKEY_get1_DH(pkey); - if (!dhkey) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to get DH key from PKEY: "); - goto fail_get_dhkey; - } - - asn1int = BN_to_ASN1_INTEGER(dh_get_public_key(dhkey), NULL); - if (!asn1int) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to convert DH key to ASN1 integer: "); - goto fail_get_asn1int; - } - - *length = (uint32_t) i2d_ASN1_INTEGER(asn1int, buffer); - - ASN1_INTEGER_free(asn1int); - -fail_get_asn1int: + DH *dhkey; + ASN1_INTEGER *asn1int; + *buffer = NULL; + if (!(dhkey = EVP_PKEY_get1_DH(pkey))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to get DH key from PKEY: "); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (!(asn1int = BN_to_ASN1_INTEGER(dh_get_public_key(dhkey), NULL))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert DH key to ASN1 integer: "); DH_free(dhkey); -fail_get_dhkey: - return result; + return DDS_SECURITY_VALIDATION_FAILED; + } + *length = (uint32_t)i2d_ASN1_INTEGER(asn1int, buffer); + ASN1_INTEGER_free(asn1int); + DH_free(dhkey); + return DDS_SECURITY_VALIDATION_OK; } -static DDS_Security_ValidationResult_t -dh_public_key_to_oct_ecdh( - EVP_PKEY *pkey, - unsigned char **buffer, - uint32_t *length, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t dh_public_key_to_oct_ecdh(EVP_PKEY *pkey, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - EC_KEY *eckey; - const EC_GROUP *group; - const EC_POINT *point; - size_t sz; + EC_KEY *eckey; + const EC_GROUP *group; + const EC_POINT *point; + size_t sz; - eckey = EVP_PKEY_get1_EC_KEY(pkey); - if (!eckey) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to get EC key from PKEY: "); - goto fail_get_eckey; - } - - point = EC_KEY_get0_public_key(eckey); - if (!point) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to get public key from ECKEY: "); - goto fail_get_point; - } - - group = EC_KEY_get0_group(eckey); - if (!group) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to get group from ECKEY: "); - goto fail_get_group; - } - - sz = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - if (sz == 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to serialize public EC key: "); - goto fail_point2oct1; - } - - *buffer = ddsrt_malloc(sz); - - *length = (uint32_t)EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, *buffer, sz, NULL); - if (*length == 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to serialize public EC key: "); - goto fail_point2oct2; - } - - EC_KEY_free(eckey); - - return result; - -fail_point2oct2: + if (!(eckey = EVP_PKEY_get1_EC_KEY(pkey))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to get EC key from PKEY: "); + goto failed_key; + } + if (!(point = EC_KEY_get0_public_key(eckey))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to get public key from ECKEY: "); + goto failed; + } + if (!(group = EC_KEY_get0_group(eckey))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to get group from ECKEY: "); + goto failed; + } + if ((sz = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL)) == 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to serialize public EC key: "); + goto failed; + } + *buffer = ddsrt_malloc(sz); + if ((*length = (uint32_t)EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, *buffer, sz, NULL)) == 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to serialize public EC key: "); ddsrt_free(*buffer); -fail_point2oct1: -fail_get_group: -fail_get_point: -fail_get_eckey: - EC_KEY_free(eckey); - return result; + goto failed; + } + EC_KEY_free(eckey); + return DDS_SECURITY_VALIDATION_OK; + +failed: + EC_KEY_free(eckey); +failed_key: + return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_ValidationResult_t -dh_public_key_to_oct( - EVP_PKEY *pkey, - AuthenticationAlgoKind_t algo, - unsigned char **buffer, - uint32_t *length, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t dh_public_key_to_oct(EVP_PKEY *pkey, AuthenticationAlgoKind_t algo, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - - assert(pkey); - assert(buffer); - assert(length); - - switch (algo) { - case AUTH_ALGO_KIND_RSA_2048: - result = dh_public_key_to_oct_modp(pkey, buffer, length, ex); - break; - case AUTH_ALGO_KIND_EC_PRIME256V1: - result = dh_public_key_to_oct_ecdh(pkey, buffer, length, ex); - break; - default: - assert(0); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Invalid key algorithm specified"); - break; - } - - return result; + assert(pkey); + assert(buffer); + assert(length); + switch (algo) + { + case AUTH_ALGO_KIND_RSA_2048: + return dh_public_key_to_oct_modp(pkey, buffer, length, ex); + case AUTH_ALGO_KIND_EC_PRIME256V1: + return dh_public_key_to_oct_ecdh(pkey, buffer, length, ex); + default: + assert(0); + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Invalid key algorithm specified"); + return DDS_SECURITY_VALIDATION_FAILED; + } } -static DDS_Security_ValidationResult_t -dh_oct_to_public_key_modp( - EVP_PKEY **pkey, - const unsigned char *keystr, - uint32_t size, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t dh_oct_to_public_key_modp(EVP_PKEY **pkey, const unsigned char *keystr, uint32_t size, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - DH *dhkey; - ASN1_INTEGER *asn1int; - BIGNUM *pubkey; + DH *dhkey; + ASN1_INTEGER *asn1int; + BIGNUM *pubkey; - *pkey = EVP_PKEY_new(); - if (!(*pkey)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to convert octet sequence to ASN1 integer: "); - goto fail_alloc_pkey; - } + if (!(*pkey = EVP_PKEY_new())) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert octet sequence to ASN1 integer: "); + goto fail_alloc_pkey; + } + if (!(asn1int = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&keystr, size))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert octet sequence to ASN1 integer: "); + goto fail_get_asn1int; + } + if (!(pubkey = ASN1_INTEGER_to_BN(asn1int, NULL))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert ASN1 integer to BIGNUM: "); + goto fail_get_pubkey; + } - asn1int = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&keystr, size); - if (!asn1int) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to convert octet sequence to ASN1 integer: "); - goto fail_get_asn1int; - } - - pubkey = ASN1_INTEGER_to_BN(asn1int, NULL); - if (!pubkey) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to convert ASN1 integer to BIGNUM: "); - goto fail_get_pubkey; - } - - dhkey = DH_get_2048_256(); - - if (dh_set_public_key(dhkey, pubkey) == 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to set DH public key: "); - } else if (EVP_PKEY_set1_DH(*pkey, dhkey) == 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to convert DH to PKEY: "); - } - - ASN1_INTEGER_free(asn1int); + dhkey = DH_get_2048_256(); + if (dh_set_public_key(dhkey, pubkey) == 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to set DH public key: "); + goto fail_get_pubkey; + } + if (EVP_PKEY_set1_DH(*pkey, dhkey) == 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to convert DH to PKEY: "); DH_free(dhkey); - - return result; + goto fail_get_pubkey; + } + ASN1_INTEGER_free(asn1int); + DH_free(dhkey); + return DDS_SECURITY_VALIDATION_OK; fail_get_pubkey: - ASN1_INTEGER_free(asn1int); + ASN1_INTEGER_free(asn1int); fail_get_asn1int: - EVP_PKEY_free(*pkey); + EVP_PKEY_free(*pkey); fail_alloc_pkey: - return result; + return DDS_SECURITY_VALIDATION_FAILED; } -static DDS_Security_ValidationResult_t -dh_oct_to_public_key_ecdh( - EVP_PKEY **pkey, - const unsigned char *keystr, - uint32_t size, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t dh_oct_to_public_key_ecdh(EVP_PKEY **pkey, const unsigned char *keystr, uint32_t size, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - EC_KEY *eckey; - EC_GROUP *group; - EC_POINT *point; - - group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); - if (!group) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to allocate EC group: "); - goto fail_alloc_group; - } - - point = EC_POINT_new(group); - if (!point) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to allocate EC point: "); - goto fail_alloc_point; - } - - - if (EC_POINT_oct2point(group, point, keystr, size, NULL) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to deserialize EC public key to EC point: "); - goto fail_oct2point; - } - - eckey = EC_KEY_new(); - if (!eckey) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to allocate EC KEY: "); - goto fail_alloc_eckey; - } - - if (EC_KEY_set_group(eckey, group) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to convert octet sequence to ASN1 integer: "); - goto fail_eckey_set_group; - } - - if (EC_KEY_set_public_key(eckey, point) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to set EC public key: "); - goto fail_eckey_set_pubkey; - } - - *pkey = EVP_PKEY_new(); - if (!(*pkey)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to allocate EVP key: "); - goto fail_alloc_pkey; - } - - if (EVP_PKEY_set1_EC_KEY(*pkey, eckey) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to set EVP key to EC public key: "); - goto fail_pkey_set_eckey; - } - - EC_KEY_free(eckey); - EC_POINT_free(point); - EC_GROUP_free(group); - - return result; + EC_KEY *eckey; + EC_GROUP *group; + EC_POINT *point; + if (!(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate EC group: "); + goto fail_alloc_group; + } + if (!(point = EC_POINT_new(group))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate EC point: "); + goto fail_alloc_point; + } + if (EC_POINT_oct2point(group, point, keystr, size, NULL) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to deserialize EC public key to EC point: "); + goto fail_oct2point; + } + if (!(eckey = EC_KEY_new())) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate EC KEY: "); + goto fail_alloc_eckey; + } + if (EC_KEY_set_group(eckey, group) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to set EC group: "); + goto fail_eckey_set; + } + if (EC_KEY_set_public_key(eckey, point) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to set EC public key: "); + goto fail_eckey_set; + } + if (!(*pkey = EVP_PKEY_new())) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to allocate EVP key: "); + goto fail_alloc_pkey; + } + if (EVP_PKEY_set1_EC_KEY(*pkey, eckey) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to set EVP key to EC public key: "); + goto fail_pkey_set_eckey; + } + EC_KEY_free(eckey); + EC_POINT_free(point); + EC_GROUP_free(group); + return DDS_SECURITY_VALIDATION_OK; fail_pkey_set_eckey: - EVP_PKEY_free(*pkey); + EVP_PKEY_free(*pkey); fail_alloc_pkey: -fail_eckey_set_pubkey: -fail_eckey_set_group: - EC_KEY_free(eckey); +fail_eckey_set: + EC_KEY_free(eckey); fail_alloc_eckey: fail_oct2point: - EC_POINT_free(point); + EC_POINT_free(point); fail_alloc_point: - EC_GROUP_free(group); + EC_GROUP_free(group); fail_alloc_group: - return result; + return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_ValidationResult_t -dh_oct_to_public_key( - EVP_PKEY **data, - AuthenticationAlgoKind_t algo, - const unsigned char *str, - uint32_t size, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t dh_oct_to_public_key(EVP_PKEY **data, AuthenticationAlgoKind_t algo, const unsigned char *str, uint32_t size, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - - assert(data); - assert(str); - - switch (algo) { - case AUTH_ALGO_KIND_RSA_2048: - result = dh_oct_to_public_key_modp(data, str, size, ex); - break; - case AUTH_ALGO_KIND_EC_PRIME256V1: - result = dh_oct_to_public_key_ecdh(data, str, size, ex); - break; - default: - assert(0); - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Invalid key algorithm specified"); - break; - } - - return result; + assert(data); + assert(str); + switch (algo) + { + case AUTH_ALGO_KIND_RSA_2048: + return dh_oct_to_public_key_modp(data, str, size, ex); + case AUTH_ALGO_KIND_EC_PRIME256V1: + return dh_oct_to_public_key_ecdh(data, str, size, ex); + default: + assert(0); + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Invalid key algorithm specified"); + return DDS_SECURITY_VALIDATION_FAILED; + } } -/* - * Allocates and return a NULL terminated string from given char array with the given size. - */ -char * -string_from_data( - const unsigned char *data, - uint32_t size) +char *string_from_data(const unsigned char *data, uint32_t size) { - char *str = NULL; - - if (size > 0 && data) { - str = ddsrt_malloc(size+1); - memcpy(str, data, size); - str[size] = '\0'; - } - - return str; + char *str = NULL; + if (size > 0 && data) + { + str = ddsrt_malloc(size + 1); + memcpy(str, data, size); + str[size] = '\0'; + } + return str; } -void -free_ca_list_contents( X509Seq *ca_list) +void free_ca_list_contents(X509Seq *ca_list) { - unsigned i; - if( ca_list->buffer != NULL && ca_list->length > 0){ - for (i = 0; i < ca_list->length; ++i) { - X509_free(ca_list->buffer[i]); - } - ddsrt_free ( ca_list->buffer ); - } - ca_list->buffer = NULL; - ca_list->length = 0; + unsigned i; + if (ca_list->buffer != NULL && ca_list->length > 0) + { + for (i = 0; i < ca_list->length; ++i) + X509_free(ca_list->buffer[i]); + ddsrt_free(ca_list->buffer); + } + ca_list->buffer = NULL; + ca_list->length = 0; } -DDS_Security_ValidationResult_t -get_trusted_ca_list ( const char* trusted_ca_dir, - X509Seq *ca_list, - DDS_Security_SecurityException *ex){ - - - DDS_Security_ValidationResult_t loading_result = DDS_RETCODE_OK; - - 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 = ddsrt_file_normalize(trusted_ca_dir); - - r = ddsrt_opendir(trusted_ca_dir_normalized, &d_descr); - ddsrt_free ( trusted_ca_dir_normalized ); - 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 = ddsrt_file_normalize(full_file_path); - - if(filename){ - X509 *identityCA; - loading_result = load_X509_certificate_from_file( filename, &identityCA, ex); - - ddsrt_free(filename); - - if( loading_result == DDS_SECURITY_VALIDATION_OK ){ - ca_buffer_array[ca_buffer_array_size] = identityCA; - ca_buffer_array_size++; - } else { - DDS_Security_Exception_reset(ex); - } - } - } - } - r = ddsrt_readdir(d_descr, &d_entry); - - ddsrt_free(full_file_path); - } - - 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 * ) ); - for (i = 0; i < ca_buffer_array_size; ++i) { - ca_list->buffer[i] = ca_buffer_array[i]; - - } - - } - ca_list->length = ca_buffer_array_size; - - return DDS_SECURITY_VALIDATION_OK; - - } - else{ - 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; - } - - return loading_result; -} - -DDS_Security_ValidationResult_t -create_asymmetrical_signature( - EVP_PKEY *pkey, - const unsigned char *data, - const size_t dataLen, - unsigned char **signature, - size_t *signatureLen, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t get_trusted_ca_list(const char *trusted_ca_dir, X509Seq *ca_list, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - EVP_MD_CTX *mdctx = NULL; - EVP_PKEY_CTX *kctx = NULL; + ddsrt_dir_handle_t d_descr; + struct ddsrt_dirent d_entry; + struct ddsrt_stat status; + X509 *ca_buf[MAX_TRUSTED_CA]; + unsigned ca_cnt = 0; + char *tca_dir_norm = ddsrt_file_normalize(trusted_ca_dir); + dds_return_t ret = ddsrt_opendir(tca_dir_norm, &d_descr); + ddsrt_free(tca_dir_norm); + if (ret != DDS_RETCODE_OK) + { + 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; + } - if (!(mdctx = EVP_MD_CTX_create())) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to create signing context: "); - goto err_create_ctx; + char *fpath, *fname; + X509 *ca; + bool failed = false; + while (!failed && ddsrt_readdir(d_descr, &d_entry) == DDS_RETCODE_OK) + { + ddsrt_asprintf(&fpath, "%s%s%s", trusted_ca_dir, ddsrt_file_sep(), d_entry.d_name); + if (ddsrt_stat(fpath, &status) == DDS_RETCODE_OK + && strcmp(d_entry.d_name, ".") != 0 && strcmp(d_entry.d_name, "..") != 0 + && (fname = ddsrt_file_normalize(fpath)) != NULL) + { + if (ca_cnt >= MAX_TRUSTED_CA) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_TRUSTED_CA_DIR_MAX_EXCEEDED_CODE, 0, DDS_SECURITY_ERR_TRUSTED_CA_DIR_MAX_EXCEEDED_MESSAGE, MAX_TRUSTED_CA); + failed = true; + } + else if (load_X509_certificate_from_file(fname, &ca, ex) == DDS_SECURITY_VALIDATION_OK) + ca_buf[ca_cnt++] = ca; + else + DDS_Security_Exception_reset(ex); + ddsrt_free(fname); } + ddsrt_free(fpath); + } + ddsrt_closedir(d_descr); - if (EVP_DigestSignInit(mdctx, &kctx, EVP_sha256(), NULL, pkey) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize signing context: "); - goto err_sign; + if (!failed) + { + free_ca_list_contents(ca_list); + if (ca_cnt > 0) + { + ca_list->buffer = ddsrt_malloc(ca_cnt * sizeof(X509 *)); + for (unsigned i = 0; i < ca_cnt; ++i) + ca_list->buffer[i] = ca_buf[i]; } + ca_list->length = ca_cnt; + } + return failed ? DDS_SECURITY_VALIDATION_FAILED : DDS_SECURITY_VALIDATION_OK; +} - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { - if (EVP_PKEY_CTX_set_rsa_padding(kctx, RSA_PKCS1_PSS_PADDING) < 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize signing context: "); - goto err_sign; - } - } +DDS_Security_ValidationResult_t create_asymmetrical_signature(EVP_PKEY *pkey, const unsigned char *data, const size_t dataLen, + unsigned char **signature, size_t *signatureLen, DDS_Security_SecurityException *ex) +{ + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *kctx = NULL; - if (EVP_DigestSignUpdate(mdctx, data, dataLen) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to update signing context: "); - goto err_sign; - } - - if (EVP_DigestSignFinal(mdctx, NULL, signatureLen) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to finalize signing context: "); - goto err_sign; - } - - *signature = ddsrt_malloc(sizeof(unsigned char) * (*signatureLen)); - assert(*signature != NULL); - if (EVP_DigestSignFinal(mdctx, *signature, signatureLen) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to finalize signing context: "); - ddsrt_free(*signature); + if (!(mdctx = EVP_MD_CTX_create())) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to create signing context: "); + goto err_create_ctx; + } + if (EVP_DigestSignInit(mdctx, &kctx, EVP_sha256(), NULL, pkey) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to initialize signing context: "); + goto err_sign; + } + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) + { + if (EVP_PKEY_CTX_set_rsa_padding(kctx, RSA_PKCS1_PSS_PADDING) < 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to initialize signing context: "); + goto err_sign; } + } + if (EVP_DigestSignUpdate(mdctx, data, dataLen) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to update signing context: "); + goto err_sign; + } + if (EVP_DigestSignFinal(mdctx, NULL, signatureLen) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to finalize signing context: "); + goto err_sign; + } + *signature = ddsrt_malloc(sizeof(unsigned char) * (*signatureLen)); + if (EVP_DigestSignFinal(mdctx, *signature, signatureLen) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to finalize signing context: "); + ddsrt_free(*signature); + goto err_sign; + } + EVP_MD_CTX_destroy(mdctx); + return DDS_SECURITY_VALIDATION_OK; err_sign: - EVP_MD_CTX_destroy(mdctx); + EVP_MD_CTX_destroy(mdctx); err_create_ctx: - return result; + return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_ValidationResult_t -validate_asymmetrical_signature( - EVP_PKEY *pkey, - const unsigned char *data, - const size_t dataLen, - const unsigned char *signature, - const size_t signatureLen, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t validate_asymmetrical_signature(EVP_PKEY *pkey, const unsigned char *data, const size_t dataLen, + const unsigned char *signature, const 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())) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to create verify context: "); - goto err_create_ctx; - } - - if (EVP_DigestVerifyInit(mdctx, &kctx, EVP_sha256(), NULL, pkey) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize verify context: "); - goto err_verify; - } - - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { - if (EVP_PKEY_CTX_set_rsa_padding(kctx, RSA_PKCS1_PSS_PADDING) < 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to initialize signing context: "); - goto err_verify; - } - } - - if (EVP_DigestVerifyUpdate(mdctx, data, dataLen) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to update verify context: "); - goto err_verify; - } - - if (EVP_DigestVerifyFinal(mdctx, signature, signatureLen) != 1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Failed to finalize verify context: "); - goto err_verify; + EVP_MD_CTX *mdctx = NULL; + EVP_PKEY_CTX *kctx = NULL; + if (!(mdctx = EVP_MD_CTX_create())) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to create verify context: "); + goto err_create_ctx; + } + if (EVP_DigestVerifyInit(mdctx, &kctx, EVP_sha256(), NULL, pkey) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to initialize verify context: "); + goto err_verify; + } + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) + { + if (EVP_PKEY_CTX_set_rsa_padding(kctx, RSA_PKCS1_PSS_PADDING) < 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to initialize signing context: "); + goto err_verify; } + } + if (EVP_DigestVerifyUpdate(mdctx, data, dataLen) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to update verify context: "); + goto err_verify; + } + if (EVP_DigestVerifyFinal(mdctx, signature, signatureLen) != 1) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Failed to finalize verify context: "); + goto err_verify; + } + EVP_MD_CTX_destroy(mdctx); + return DDS_SECURITY_VALIDATION_OK; err_verify: - EVP_MD_CTX_destroy(mdctx); + EVP_MD_CTX_destroy(mdctx); err_create_ctx: - return result; + return DDS_SECURITY_VALIDATION_FAILED; } diff --git a/src/security/builtin_plugins/authentication/src/auth_utils.h b/src/security/builtin_plugins/authentication/src/auth_utils.h index b08df38..bbde1ba 100644 --- a/src/security/builtin_plugins/authentication/src/auth_utils.h +++ b/src/security/builtin_plugins/authentication/src/auth_utils.h @@ -42,34 +42,21 @@ typedef struct { } X509Seq; typedef unsigned char HashValue_t[SHA256_DIGEST_LENGTH]; -/*typedef struct HashValue { - unsigned char value[SHA256_DIGEST_LENGTH]; -} HashValue_t; -*/ /* Return a string that contains an openssl error description * When a openssl function returns an error this function can be * used to retrieve a descriptive error string. * Note that the returned string should be freed. */ -char * -get_openssl_error_message( - void); +char * get_openssl_error_message(void); /* Return the subject name of contained in a X509 certificate * Note that the returned string should be freed. */ -char* -get_certificate_subject_name( - X509 *cert, - DDS_Security_SecurityException *ex); +char * get_certificate_subject_name(X509 *cert, DDS_Security_SecurityException *ex); -/* Return the expiry date of contained in a X509 certificate - * - */ -dds_time_t -get_certificate_expiry( - const X509 *cert); +/* Return the expiry date of contained in a X509 certificate */ +dds_time_t get_certificate_expiry(const X509 *cert); /* Return the subject name of a X509 certificate DER * encoded. The DER encoded subject name is returned in @@ -78,63 +65,19 @@ get_certificate_expiry( * * return length of allocated buffer or -1 on error */ -DDS_Security_ValidationResult_t -get_subject_name_DER_encoded( - const X509 *cert, - unsigned char **buffer, - size_t *size, - DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t get_subject_name_DER_encoded(const X509 *cert, unsigned char **buffer, size_t *size, DDS_Security_SecurityException *ex); +/* Load a X509 certificate for the provided data (PEM format) */ +DDS_Security_ValidationResult_t load_X509_certificate_from_data(const char *data, int len, X509 **x509Cert, DDS_Security_SecurityException *ex); -/* Load a X509 certificate for the provided data. - * - * data : certificate in PEM format - * x509Cert : the openssl X509 return value - */ -DDS_Security_ValidationResult_t -load_X509_certificate_from_data( - const char *data, - int len, - X509 **x509Cert, - DDS_Security_SecurityException *ex); +/* Load a X509 certificate for the provided data (certificate uri) */ +DDS_Security_ValidationResult_t load_X509_certificate(const char *data, X509 **x509Cert, DDS_Security_SecurityException *ex); +/* Load a X509 certificate for the provided file */ +DDS_Security_ValidationResult_t load_X509_certificate_from_file(const char *filename, X509 **x509Cert, DDS_Security_SecurityException *ex); -/* Load a X509 certificate for the provided data. - * - * data : URI of the certificate. URI format is defined in DDS Security spec 9.3.1 - - * x509Cert : the openssl X509 return value - */ -DDS_Security_ValidationResult_t -load_X509_certificate( - const char *data, - X509 **x509Cert, - DDS_Security_SecurityException *ex); - - -/* Load a X509 certificate for the provided file. - * - * filename : path of the file that contains PEM formatted certificate - * x509Cert : the openssl X509 return value - */ -DDS_Security_ValidationResult_t -load_X509_certificate_from_file( - const char *filename, - X509 **x509Cert, - DDS_Security_SecurityException *ex); - -/* Load a Private Key for the provided data. - * - * data : URI of the private key. URI format is defined in DDS Security spec 9.3.1 - * privateKey : the openssl EVP_PKEY return value - */ -DDS_Security_ValidationResult_t -load_X509_private_key( - const char *data, - const char *password, - EVP_PKEY **privateKey, - DDS_Security_SecurityException *ex); - +/* Load a Private Key for the provided data (private key uri) */ +DDS_Security_ValidationResult_t load_X509_private_key(const char *data, const char *password, EVP_PKEY **privateKey, DDS_Security_SecurityException *ex); /* Validate an identity certificate against the identityCA * The provided identity certificate is checked if it is @@ -144,95 +87,20 @@ load_X509_private_key( * The function does not yet check a CLR or ocsp * for expiry of identity certificate. */ -DDS_Security_ValidationResult_t -verify_certificate( - X509 *identityCert, - X509 *identityCa, - DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t verify_certificate(X509 *identityCert, X509 *identityCa, DDS_Security_SecurityException *ex); -DDS_Security_ValidationResult_t -check_certificate_expiry( - const X509 *cert, - DDS_Security_SecurityException *ex); - -AuthenticationAlgoKind_t -get_auhentication_algo_kind( - X509 *cert); - -AuthenticationChallenge * -generate_challenge( - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -get_certificate_contents( - X509 *cert, - unsigned char **data, - uint32_t *size, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -generate_dh_keys( - EVP_PKEY **dhkey, - AuthenticationAlgoKind_t authKind, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -dh_public_key_to_oct( - EVP_PKEY *pkey, - AuthenticationAlgoKind_t algo, - unsigned char **buffer, - uint32_t *length, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -dh_oct_to_public_key( - EVP_PKEY **data, - AuthenticationAlgoKind_t algo, - const unsigned char *str, - uint32_t size, - DDS_Security_SecurityException *ex); - - -AuthConfItemPrefix_t -get_conf_item_type( - const char *str, - char **data); - -/* - * Frees the contents of theCA list. - */ -void -free_ca_list_contents( - X509Seq *ca_list); - -DDS_Security_ValidationResult_t -get_trusted_ca_list ( - const char* trusted_ca_dir, - X509Seq *ca_list, - DDS_Security_SecurityException *ex); - -char * -string_from_data( - const unsigned char *data, - uint32_t size); - - -DDS_Security_ValidationResult_t -create_asymmetrical_signature( - EVP_PKEY *pkey, - const unsigned char *data, - const size_t dataLen, - unsigned char **signature, - size_t *signatureLen, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -validate_asymmetrical_signature( - EVP_PKEY *pkey, - const unsigned char *data, - const size_t dataLen, - const unsigned char *signature, - const size_t signatureLen, - DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t check_certificate_expiry(const X509 *cert, DDS_Security_SecurityException *ex); +AuthenticationAlgoKind_t get_authentication_algo_kind(X509 *cert); +AuthenticationChallenge *generate_challenge(DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t get_certificate_contents(X509 *cert, unsigned char **data, uint32_t *size, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t generate_dh_keys(EVP_PKEY **dhkey, AuthenticationAlgoKind_t authKind, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t dh_public_key_to_oct(EVP_PKEY *pkey, AuthenticationAlgoKind_t algo, unsigned char **buffer, uint32_t *length, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t dh_oct_to_public_key(EVP_PKEY **data, AuthenticationAlgoKind_t algo, const unsigned char *str, uint32_t size, DDS_Security_SecurityException *ex); +AuthConfItemPrefix_t get_conf_item_type(const char *str, char **data); +void free_ca_list_contents(X509Seq *ca_list); +DDS_Security_ValidationResult_t get_trusted_ca_list(const char* trusted_ca_dir, X509Seq *ca_list, DDS_Security_SecurityException *ex); +char * string_from_data(const unsigned char *data, uint32_t size); +DDS_Security_ValidationResult_t create_asymmetrical_signature(EVP_PKEY *pkey, const unsigned char *data, const size_t dataLen, unsigned char **signature, size_t *signatureLen, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t validate_asymmetrical_signature(EVP_PKEY *pkey, const unsigned char *data, const size_t dataLen, const unsigned char *signature, const size_t signatureLen, DDS_Security_SecurityException *ex); #endif /* AUTH_UTILS_H */ diff --git a/src/security/builtin_plugins/authentication/src/authentication.c b/src/security/builtin_plugins/authentication/src/authentication.c index 4d317d7..79f03bd 100644 --- a/src/security/builtin_plugins/authentication/src/authentication.c +++ b/src/security/builtin_plugins/authentication/src/authentication.c @@ -10,7 +10,9 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ - +#include +#include +#include #include #include #include @@ -19,12 +21,6 @@ #include #include #include -#include "authentication.h" -#include "dds/ddsrt/heap.h" -#include "dds/security/dds_security_api.h" -#include "dds/security/core/dds_security_timed_cb.h" -#include "dds/security/core/dds_security_utils.h" - #if OPENSLL_VERSION_NUMBER >= 0x10002000L #define AUTH_INCLUDE_EC #include @@ -40,431 +36,356 @@ #undef X509_NAME #endif -#include "dds/security/dds_security_api.h" -#include "dds/security/dds_security_api_types.h" +#include "dds/ddsrt/heap.h" #include "dds/ddsrt/atomics.h" -#include "stdbool.h" -#include #include "dds/ddsrt/string.h" #include "dds/ddsrt/sync.h" #include "dds/ddsrt/hopscotch.h" - +#include "dds/security/dds_security_api.h" +#include "dds/security/core/dds_security_timed_cb.h" +#include "dds/security/core/dds_security_utils.h" +#include "dds/security/dds_security_api.h" +#include "dds/security/dds_security_api_types.h" #include "dds/security/core/shared_secret.h" #include "dds/security/core/dds_security_utils.h" #include "dds/security/core/dds_security_serialize.h" #include "auth_utils.h" -#include +#include "authentication.h" #ifndef EVP_PKEY_id #define EVP_PKEY_id(k) ((k)->type) #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10100000L -#define REMOVE_THREAD_STATE() ERR_remove_thread_state(NULL); +#define REMOVE_THREAD_STATE() ERR_remove_thread_state(NULL); #elif OPENSSL_VERSION_NUMBER < 0x10000000L -#define REMOVE_THREAD_STATE() ERR_remove_state(0); +#define REMOVE_THREAD_STATE() ERR_remove_state(0); #else #define REMOVE_THREAD_STATE() #endif - #define HANDSHAKE_SIGNATURE_CONTENT_SIZE 6 +#define ADJUSTED_GUID_PREFIX_FLAG 0x80 -static const char * AUTH_PROTOCOL_CLASS = "DDS:Auth:PKI-DH"; -static const unsigned AUTH_PROTOCOL_VERSION_MAJOR = 1; -static const unsigned AUTH_PROTOCOL_VERSION_MINOR = 0; +static const char *AUTH_PROTOCOL_CLASS = "DDS:Auth:PKI-DH"; +static const unsigned AUTH_PROTOCOL_VERSION_MAJOR = 1; +static const unsigned AUTH_PROTOCOL_VERSION_MINOR = 0; -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_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 * PROPERTY_IDENTITY_CA = "dds.sec.auth.identity_ca"; -static const char * PROPERTY_PRIVATE_KEY = "dds.sec.auth.private_key"; -static const char * PROPERTY_PASSWORD = "dds.sec.auth.password"; -static const char * PROPERTY_IDENTITY_CERT = "dds.sec.auth.identity_certificate"; -static const char * PROPERTY_TRUSTED_CA_DIR = "dds.sec.auth.trusted_ca_dir"; +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_PASSWORD = "dds.sec.auth.password"; +static const char *PROPERTY_IDENTITY_CERT = "dds.sec.auth.identity_certificate"; +static const char *PROPERTY_TRUSTED_CA_DIR = "dds.sec.auth.trusted_ca_dir"; -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 *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_HANDSHAKE_REQUEST_TOKEN_ID = "DDS:Auth:PKI-DH:1.0+Req"; -static const char * AUTH_HANDSHAKE_REPLY_TOKEN_ID = "DDS:Auth:PKI-DH:1.0+Reply"; +static const char *AUTH_HANDSHAKE_REQUEST_TOKEN_ID = "DDS:Auth:PKI-DH:1.0+Req"; +static const char *AUTH_HANDSHAKE_REPLY_TOKEN_ID = "DDS:Auth:PKI-DH:1.0+Reply"; -static const char * AUTH_HANDSHAKE_FINAL_TOKEN_ID = "DDS:Auth:PKI-DH:1.0+Final"; +static const char *AUTH_HANDSHAKE_FINAL_TOKEN_ID = "DDS:Auth:PKI-DH:1.0+Final"; -static const char * AUTH_DSIG_ALGO_RSA_2048_SHA256_IDENT = "RSASSA-PSS-SHA256"; -static const char * AUTH_DSIG_ALGO_ECDSA_SHA256_IDENT = "ECDSA-SHA256"; -static const char * AUTH_KAGREE_ALGO_RSA_2048_SHA256_IDENT = "DH+MODP-2048-256"; -static const char * AUTH_KAGREE_ALGO_ECDH_PRIME256V1_IDENT = "ECDH+prime256v1-CEUM"; +static const char *AUTH_DSIG_ALGO_RSA_2048_SHA256_IDENT = "RSASSA-PSS-SHA256"; +static const char *AUTH_DSIG_ALGO_ECDSA_SHA256_IDENT = "ECDSA-SHA256"; +static const char *AUTH_KAGREE_ALGO_RSA_2048_SHA256_IDENT = "DH+MODP-2048-256"; +static const char *AUTH_KAGREE_ALGO_ECDH_PRIME256V1_IDENT = "ECDH+prime256v1-CEUM"; +static const char *ACCESS_PERMISSIONS_CREDENTIAL_TOKEN_ID = "DDS:Access:PermissionsCredential"; +static const char *ACCESS_PROPERTY_PERMISSION_DOCUMENT = "dds.perm.cert"; -static const char * ACCESS_PERMISSIONS_CREDENTIAL_TOKEN_ID = "DDS:Access:PermissionsCredential"; -static const char * ACCESS_PROPERTY_PERMISSION_DOCUMENT = "dds.perm.cert"; - - -/** - * Implementation structure for storing encapsulated members of the instance - * while giving only the interface definition to user - */ - -typedef enum { - SECURITY_OBJECT_KIND_UNKNOWN, - SECURITY_OBJECT_KIND_LOCAL_IDENTITY, - SECURITY_OBJECT_KIND_REMOTE_IDENTITY, - SECURITY_OBJECT_KIND_IDENTITY_RELATION, - SECURITY_OBJECT_KIND_HANDSHAKE +typedef enum +{ + SECURITY_OBJECT_KIND_UNKNOWN, + SECURITY_OBJECT_KIND_LOCAL_IDENTITY, + SECURITY_OBJECT_KIND_REMOTE_IDENTITY, + SECURITY_OBJECT_KIND_IDENTITY_RELATION, + SECURITY_OBJECT_KIND_HANDSHAKE } SecurityObjectKind_t; -typedef enum { +typedef enum +{ CREATEDREQUEST, CREATEDREPLY - } CreatedHandshakeStep_t; typedef struct SecurityObject SecurityObject; - typedef void (*SecurityObjectDestructor)(SecurityObject *obj); -struct SecurityObject { - int64_t handle; - SecurityObjectKind_t kind; - SecurityObjectDestructor destructor; +struct SecurityObject +{ + int64_t handle; + SecurityObjectKind_t kind; + SecurityObjectDestructor destructor; }; - #ifndef NDEBUG -#define CHECK_OBJECT_KIND(o,k) assert(security_object_valid((SecurityObject *)(o), k)) +#define CHECK_OBJECT_KIND(o, k) assert(security_object_valid((SecurityObject *)(o), k)) #else -#define CHECK_OBJECT_KIND(o,k) +#define CHECK_OBJECT_KIND(o, k) #endif -#define SECURITY_OBJECT(o) ((SecurityObject *)(o)) -#define SECURITY_OBJECT_HANDLE(o) (SECURITY_OBJECT(o)->handle) -#define IDENTITY_HANDLE(o) ((DDS_Security_IdentityHandle) SECURITY_OBJECT_HANDLE(o)) -#define HANDSHAKE_HANDLE(o) ((DDS_Security_HandshakeHandle) SECURITY_OBJECT_HANDLE(o)) +#define SECURITY_OBJECT(o) ((SecurityObject *)(o)) +#define SECURITY_OBJECT_HANDLE(o) (SECURITY_OBJECT(o)->handle) +#define IDENTITY_HANDLE(o) ((DDS_Security_IdentityHandle)SECURITY_OBJECT_HANDLE(o)) +#define HANDSHAKE_HANDLE(o) ((DDS_Security_HandshakeHandle)SECURITY_OBJECT_HANDLE(o)) -#define SECURITY_OBJECT_VALID(o,k) security_object_valid((SecurityObject *)(o), k) +#define SECURITY_OBJECT_VALID(o, k) security_object_valid((SecurityObject *)(o), k) - -typedef struct LocalIdentityInfo { - SecurityObject _parent; - DDS_Security_DomainId domainId; - DDS_Security_GUID_t candidateGUID; - DDS_Security_GUID_t adjustedGUID; - X509 *identityCert; - X509 *identityCA; - EVP_PKEY *privateKey; - DDS_Security_OctetSeq pdata; - AuthenticationAlgoKind_t dsignAlgoKind; - AuthenticationAlgoKind_t kagreeAlgoKind; - char *permissionsDocument; +typedef struct LocalIdentityInfo +{ + SecurityObject _parent; + DDS_Security_DomainId domainId; + DDS_Security_GUID_t candidateGUID; + DDS_Security_GUID_t adjustedGUID; + X509 *identityCert; + X509 *identityCA; + EVP_PKEY *privateKey; + DDS_Security_OctetSeq pdata; + AuthenticationAlgoKind_t dsignAlgoKind; + AuthenticationAlgoKind_t kagreeAlgoKind; + char *permissionsDocument; } LocalIdentityInfo; -typedef struct RemoteIdentityInfo { - SecurityObject _parent; - DDS_Security_GUID_t guid; - X509 *identityCert; - AuthenticationAlgoKind_t dsignAlgoKind; - AuthenticationAlgoKind_t kagreeAlgoKind; - DDS_Security_IdentityToken *remoteIdentityToken; - DDS_Security_OctetSeq pdata; - char *permissionsDocument; - struct ddsrt_hh *linkHash; /* contains the IdentityRelation objects */ +typedef struct RemoteIdentityInfo +{ + SecurityObject _parent; + DDS_Security_GUID_t guid; + X509 *identityCert; + AuthenticationAlgoKind_t dsignAlgoKind; + AuthenticationAlgoKind_t kagreeAlgoKind; + DDS_Security_IdentityToken *remoteIdentityToken; + DDS_Security_OctetSeq pdata; + char *permissionsDocument; + struct ddsrt_hh *linkHash; /* contains the IdentityRelation objects */ } RemoteIdentityInfo; - /* This structure contains the relation between a local and a remote identity * The handle for this object is the same as the handle of the associated * local identity object. The IdentityRelation object will be stored with the * remote identity. */ -typedef struct IdentityRelation { - SecurityObject _parent; - LocalIdentityInfo *localIdentity; - RemoteIdentityInfo *remoteIdentity; - AuthenticationChallenge *lchallenge; - AuthenticationChallenge *rchallenge; +typedef struct IdentityRelation +{ + SecurityObject _parent; + LocalIdentityInfo *localIdentity; + RemoteIdentityInfo *remoteIdentity; + AuthenticationChallenge *lchallenge; + AuthenticationChallenge *rchallenge; } IdentityRelation; -typedef struct HandshakeInfo { - SecurityObject _parent; - IdentityRelation *relation; - HashValue_t hash_c1; - HashValue_t hash_c2; - EVP_PKEY *ldh; - EVP_PKEY *rdh; - DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl; - CreatedHandshakeStep_t created_in; +typedef struct HandshakeInfo +{ + SecurityObject _parent; + IdentityRelation *relation; + HashValue_t hash_c1; + HashValue_t hash_c2; + EVP_PKEY *ldh; + EVP_PKEY *rdh; + DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl; + CreatedHandshakeStep_t created_in; } HandshakeInfo; -typedef struct dds_security_authentication_impl { - dds_security_authentication base; - ddsrt_mutex_t lock; - struct ddsrt_hh *objectHash; - struct ddsrt_hh *remoteGuidHash; - struct dds_security_timed_cb_data *timed_callbacks; - struct dds_security_timed_dispatcher_t *dispatcher; - X509Seq trustedCAList; +typedef struct dds_security_authentication_impl +{ + dds_security_authentication base; + ddsrt_mutex_t lock; + struct ddsrt_hh *objectHash; + struct ddsrt_hh *remoteGuidHash; + struct dds_security_timed_cb_data *timed_callbacks; + struct dds_security_timed_dispatcher_t *dispatcher; + X509Seq trustedCAList; } dds_security_authentication_impl; /* data type for timer dispatcher */ -typedef struct { - dds_security_authentication_impl *auth; - DDS_Security_IdentityHandle hdl; +typedef struct +{ + dds_security_authentication_impl *auth; + DDS_Security_IdentityHandle hdl; } validity_cb_info; - -static bool -security_object_valid( - SecurityObject *obj, - SecurityObjectKind_t kind) +static bool security_object_valid(SecurityObject *obj, SecurityObjectKind_t kind) { - if (!obj) return false; - if (obj->kind != kind) return false; - if (kind == SECURITY_OBJECT_KIND_IDENTITY_RELATION) { - IdentityRelation *relation = (IdentityRelation *)obj; - if (!relation->localIdentity || !relation->remoteIdentity || (ddsrt_address)obj->handle != (ddsrt_address)relation->localIdentity) { - return false; - } - } else if ((ddsrt_address)obj->handle != (ddsrt_address)obj) { - return false; - } - return true; + if (!obj || obj->kind != kind) + return false; + if (kind == SECURITY_OBJECT_KIND_IDENTITY_RELATION) + { + IdentityRelation *relation = (IdentityRelation *)obj; + if (!relation->localIdentity || !relation->remoteIdentity || (ddsrt_address)obj->handle != (ddsrt_address)relation->localIdentity) + return false; + } + else if ((ddsrt_address)obj->handle != (ddsrt_address)obj) + return false; + return true; } -static uint32_t -security_object_hash ( - const void *obj) +static uint32_t security_object_hash(const void *obj) { - const SecurityObject *object = obj; -#define UINT64_CONST(x, y, z) (((uint64_t) (x) * 1000000 + (y)) * 1000000 + (z)) - const uint64_t c = UINT64_CONST (16292676, 669999, 574021); -#undef UINT64_CONST - const uint32_t x = (uint32_t) object->handle; - return (unsigned) ((x * c) >> 32); + const SecurityObject *object = obj; + const uint64_t c = UINT64_C (16292676669999574021); + const uint32_t x = (uint32_t)object->handle; + return (uint32_t)((x * c) >> 32); } -static int -security_object_equal ( - const void *ha, - const void *hb) +static int security_object_equal(const void *ha, const void *hb) { - const SecurityObject *la = ha; - const SecurityObject *lb = hb; - - return la->handle == lb->handle; + const SecurityObject *la = ha; + const SecurityObject *lb = hb; + return la->handle == lb->handle; } -static SecurityObject * -security_object_find( - const struct ddsrt_hh *hh, - int64_t handle) +static SecurityObject *security_object_find(const struct ddsrt_hh *hh, int64_t handle) { - struct SecurityObject template; - - template.handle = handle; - - return (SecurityObject *) ddsrt_hh_lookup(hh, &template);; + struct SecurityObject template; + template.handle = handle; + return (SecurityObject *)ddsrt_hh_lookup(hh, &template); } -static void -security_object_init( - SecurityObject *obj, - SecurityObjectKind_t kind, - SecurityObjectDestructor destructor) +static void security_object_init(SecurityObject *obj, SecurityObjectKind_t kind, SecurityObjectDestructor destructor) { - assert(obj); - - obj->kind = kind; - obj->handle = (int64_t)(ddsrt_address)obj; - obj->destructor = destructor; + assert(obj); + obj->kind = kind; + obj->handle = (int64_t)(ddsrt_address)obj; + obj->destructor = destructor; } -static void -security_object_deinit( - SecurityObject *obj) - +static void security_object_deinit(SecurityObject *obj) { - assert(obj); - obj->handle = DDS_SECURITY_HANDLE_NIL; - obj->kind = SECURITY_OBJECT_KIND_UNKNOWN; - obj->destructor = NULL; + assert(obj); + obj->handle = DDS_SECURITY_HANDLE_NIL; + obj->kind = SECURITY_OBJECT_KIND_UNKNOWN; + obj->destructor = NULL; } -static void -security_object_free( - SecurityObject *obj) +static void security_object_free(SecurityObject *obj) { - assert(obj); - if (obj && obj->destructor) { - obj->destructor(obj); - } + assert(obj); + if (obj && obj->destructor) + obj->destructor(obj); } -static void -localIdentityInfoFree( - SecurityObject *obj); - - - -static LocalIdentityInfo * -localIdentityInfoNew( - DDS_Security_DomainId domainId, - X509 *identityCert, - X509 *identityCa, - EVP_PKEY *privateKey, - const DDS_Security_GUID_t *candidate_participant_guid, - const DDS_Security_GUID_t *adjusted_participant_guid) +static void local_identity_info_free(SecurityObject *obj) { - LocalIdentityInfo *identity = NULL; - - assert(identityCert); - assert(identityCa); - assert(privateKey); - assert(candidate_participant_guid); - assert(adjusted_participant_guid); - assert(sizeof(DDS_Security_IdentityHandle) == 8); - - identity = ddsrt_malloc(sizeof(*identity)); - memset(identity, 0, sizeof(*identity)); - - security_object_init((SecurityObject *)identity, SECURITY_OBJECT_KIND_LOCAL_IDENTITY, localIdentityInfoFree); - - - - - identity->domainId = domainId; - identity->identityCert = identityCert; - identity->identityCA = identityCa; - identity->privateKey = privateKey; - identity->permissionsDocument = NULL; - identity->dsignAlgoKind = get_auhentication_algo_kind(identityCert); - identity->kagreeAlgoKind = AUTH_ALGO_KIND_EC_PRIME256V1; - - memcpy(&identity->candidateGUID, candidate_participant_guid, sizeof(DDS_Security_GUID_t)); - memcpy(&identity->adjustedGUID, adjusted_participant_guid, sizeof(DDS_Security_GUID_t)); - - return identity; + LocalIdentityInfo *identity = (LocalIdentityInfo *)obj; + CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY); + if (identity) + { + if (identity->identityCert) + X509_free(identity->identityCert); + if (identity->identityCA) + X509_free(identity->identityCA); + if (identity->privateKey) + EVP_PKEY_free(identity->privateKey); + ddsrt_free(identity->pdata._buffer); + ddsrt_free(identity->permissionsDocument); + security_object_deinit((SecurityObject *)identity); + ddsrt_free(identity); + } } -static void -localIdentityInfoFree( - SecurityObject *obj) +static LocalIdentityInfo *local_identity_info_new(DDS_Security_DomainId domainId, X509 *identityCert, X509 *identityCa, EVP_PKEY *privateKey, const DDS_Security_GUID_t *candidate_participant_guid, const DDS_Security_GUID_t *adjusted_participant_guid) { - LocalIdentityInfo *identity = (LocalIdentityInfo *)obj; + LocalIdentityInfo *identity = NULL; + assert(identityCert); + assert(identityCa); + assert(privateKey); + assert(candidate_participant_guid); + assert(adjusted_participant_guid); + assert(sizeof(DDS_Security_IdentityHandle) == 8); - CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY); + identity = ddsrt_malloc(sizeof(*identity)); + memset(identity, 0, sizeof(*identity)); - if (identity) { - if (identity->identityCert) { - X509_free(identity->identityCert); - } - if (identity->identityCA) { - X509_free(identity->identityCA); - } - if (identity->privateKey) { - EVP_PKEY_free(identity->privateKey); - } - ddsrt_free(identity->pdata._buffer); - ddsrt_free(identity->permissionsDocument); - security_object_deinit((SecurityObject *)identity); - ddsrt_free(identity); - } + security_object_init((SecurityObject *)identity, SECURITY_OBJECT_KIND_LOCAL_IDENTITY, local_identity_info_free); + + identity->domainId = domainId; + identity->identityCert = identityCert; + identity->identityCA = identityCa; + identity->privateKey = privateKey; + identity->permissionsDocument = NULL; + identity->dsignAlgoKind = get_authentication_algo_kind(identityCert); + identity->kagreeAlgoKind = AUTH_ALGO_KIND_EC_PRIME256V1; + + memcpy(&identity->candidateGUID, candidate_participant_guid, sizeof(DDS_Security_GUID_t)); + memcpy(&identity->adjustedGUID, adjusted_participant_guid, sizeof(DDS_Security_GUID_t)); + + return identity; } -static uint32_t -remote_guid_hash ( - const void *obj) +static uint32_t remote_guid_hash(const void *obj) { - const RemoteIdentityInfo *identity = obj; - uint32_t tmp[4]; - - memcpy(tmp, &identity->guid, sizeof(tmp)); - - return (tmp[0]^tmp[1]^tmp[2]^tmp[3]); + const RemoteIdentityInfo *identity = obj; + uint32_t tmp[4]; + memcpy(tmp, &identity->guid, sizeof(tmp)); + return (tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3]); } -static int -remote_guid_equal ( - const void *ha, - const void *hb) +static int remote_guid_equal(const void *ha, const void *hb) { - const RemoteIdentityInfo *la = ha; - const RemoteIdentityInfo *lb = hb; - - return memcmp(&la->guid, &lb->guid, sizeof(la->guid)) == 0; + const RemoteIdentityInfo *la = ha; + const RemoteIdentityInfo *lb = hb; + return memcmp(&la->guid, &lb->guid, sizeof(la->guid)) == 0; } -static RemoteIdentityInfo * -find_remote_identity_by_guid( - const struct ddsrt_hh *hh, - const DDS_Security_GUID_t *guid) +static RemoteIdentityInfo *find_remote_identity_by_guid(const struct ddsrt_hh *hh, const DDS_Security_GUID_t *guid) { - struct RemoteIdentityInfo template; - - memcpy(&template.guid, guid, sizeof(*guid)); - - return (RemoteIdentityInfo *) ddsrt_hh_lookup(hh, &template); + struct RemoteIdentityInfo template; + memcpy(&template.guid, guid, sizeof(*guid)); + return (RemoteIdentityInfo *)ddsrt_hh_lookup(hh, &template); } -static void -remoteIdentityInfoFree( - SecurityObject *obj); - -static RemoteIdentityInfo * -remoteIdentityInfoNew( - const DDS_Security_GUID_t *guid, - const DDS_Security_IdentityToken *remote_identity_token) +static void remote_identity_info_free(SecurityObject *obj) { - RemoteIdentityInfo *identity = NULL; - - assert(guid); - assert(remote_identity_token); - - identity = ddsrt_malloc(sizeof(*identity)); - memset(identity, 0, sizeof(*identity)); - - security_object_init((SecurityObject *)identity, SECURITY_OBJECT_KIND_REMOTE_IDENTITY, remoteIdentityInfoFree); - - memcpy(&identity->guid, guid, sizeof(DDS_Security_GUID_t)); - identity->remoteIdentityToken = DDS_Security_DataHolder_alloc(); - DDS_Security_DataHolder_copy(identity->remoteIdentityToken, remote_identity_token); - identity->identityCert = NULL; - identity->dsignAlgoKind = AUTH_ALGO_KIND_UNKNOWN; - identity->kagreeAlgoKind = AUTH_ALGO_KIND_UNKNOWN; - identity->permissionsDocument = ddsrt_strdup(""); - identity->linkHash = ddsrt_hh_new(32, security_object_hash, security_object_equal); - - return identity; + RemoteIdentityInfo *identity = (RemoteIdentityInfo *)obj; + CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_REMOTE_IDENTITY); + if (identity) + { + if (identity->identityCert) + X509_free(identity->identityCert); + DDS_Security_DataHolder_free(identity->remoteIdentityToken); + ddsrt_hh_free(identity->linkHash); + ddsrt_free(identity->pdata._buffer); + ddsrt_free(identity->permissionsDocument); + security_object_deinit((SecurityObject *)identity); + ddsrt_free(identity); + } } -static void -remoteIdentityInfoFree( - SecurityObject *obj) +static RemoteIdentityInfo *remote_identity_info_new(const DDS_Security_GUID_t *guid, const DDS_Security_IdentityToken *remote_identity_token) { - RemoteIdentityInfo *identity = (RemoteIdentityInfo *)obj; + assert(guid); + assert(remote_identity_token); - CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_REMOTE_IDENTITY); - - if (identity) { - if (identity->identityCert) { - X509_free(identity->identityCert); - } - DDS_Security_DataHolder_free(identity->remoteIdentityToken); - - ddsrt_hh_free(identity->linkHash); - - ddsrt_free(identity->pdata._buffer); - ddsrt_free(identity->permissionsDocument); - security_object_deinit((SecurityObject *)identity); - ddsrt_free(identity); - } + RemoteIdentityInfo *identity = ddsrt_malloc(sizeof(*identity)); + memset(identity, 0, sizeof(*identity)); + security_object_init((SecurityObject *)identity, SECURITY_OBJECT_KIND_REMOTE_IDENTITY, remote_identity_info_free); + memcpy(&identity->guid, guid, sizeof(DDS_Security_GUID_t)); + identity->remoteIdentityToken = DDS_Security_DataHolder_alloc(); + DDS_Security_DataHolder_copy(identity->remoteIdentityToken, remote_identity_token); + identity->identityCert = NULL; + identity->dsignAlgoKind = AUTH_ALGO_KIND_UNKNOWN; + identity->kagreeAlgoKind = AUTH_ALGO_KIND_UNKNOWN; + identity->permissionsDocument = ddsrt_strdup(""); + identity->linkHash = ddsrt_hh_new(32, security_object_hash, security_object_equal); + return identity; } -static void -identityRelationFree( - SecurityObject *obj); +static void identity_relation_free(SecurityObject *obj) +{ + IdentityRelation *relation = (IdentityRelation *)obj; + CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_IDENTITY_RELATION); + if (relation) + { + ddsrt_free(relation->lchallenge); + ddsrt_free(relation->rchallenge); + security_object_deinit((SecurityObject *)relation); + ddsrt_free(relation); + } +} /* The IdentityRelation provides the association between a local and a remote * identity. This object manages the challenges which are created for @@ -474,1462 +395,1056 @@ identityRelationFree( * The rchallenge is the challenge received from the remote identity it may be set when * an auth_request_message_token is received from the remote identity, */ -static IdentityRelation * -identityRelationNew( - LocalIdentityInfo *localIdentity, - RemoteIdentityInfo *remoteIdentity, - AuthenticationChallenge *lchallenge, - AuthenticationChallenge *rchallenge) +static IdentityRelation *identity_relation_new(LocalIdentityInfo *localIdentity, RemoteIdentityInfo *remoteIdentity, AuthenticationChallenge *lchallenge, AuthenticationChallenge *rchallenge) { - IdentityRelation *relation; - - assert(localIdentity); - assert(remoteIdentity); - - relation = ddsrt_malloc(sizeof(*relation)); - memset(relation, 0, sizeof(*relation)); - - security_object_init((SecurityObject *)relation, SECURITY_OBJECT_KIND_IDENTITY_RELATION, identityRelationFree); - relation->_parent.handle = SECURITY_OBJECT_HANDLE(localIdentity); - - relation->localIdentity = localIdentity; - relation->remoteIdentity = remoteIdentity; - relation->lchallenge = lchallenge; - relation->rchallenge = rchallenge; - - return relation; + IdentityRelation *relation; + assert(localIdentity); + assert(remoteIdentity); + relation = ddsrt_malloc(sizeof(*relation)); + memset(relation, 0, sizeof(*relation)); + security_object_init((SecurityObject *)relation, SECURITY_OBJECT_KIND_IDENTITY_RELATION, identity_relation_free); + relation->_parent.handle = SECURITY_OBJECT_HANDLE(localIdentity); + relation->localIdentity = localIdentity; + relation->remoteIdentity = remoteIdentity; + relation->lchallenge = lchallenge; + relation->rchallenge = rchallenge; + return relation; } -static void -identityRelationFree( - SecurityObject *obj) +static void handshake_info_free(SecurityObject *obj) { - IdentityRelation *relation = (IdentityRelation *)obj; - - CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_IDENTITY_RELATION); - - if (relation) { - ddsrt_free(relation->lchallenge); - ddsrt_free(relation->rchallenge); - security_object_deinit((SecurityObject *)relation); - ddsrt_free(relation); + CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_HANDSHAKE); + HandshakeInfo *handshake = (HandshakeInfo *)obj; + if (handshake) + { + if (handshake->ldh) + EVP_PKEY_free(handshake->ldh); + if (handshake->rdh) + EVP_PKEY_free(handshake->rdh); + if (handshake->shared_secret_handle_impl) + { + ddsrt_free(handshake->shared_secret_handle_impl->shared_secret); + ddsrt_free(handshake->shared_secret_handle_impl); } + security_object_deinit((SecurityObject *)handshake); + ddsrt_free(handshake); + } } -static void -handshakeInfoFree( - SecurityObject *obj); - -static HandshakeInfo * -handshakeInfoNew( - LocalIdentityInfo *localIdentity, - RemoteIdentityInfo *remoteIdentity, - IdentityRelation *relation) +static HandshakeInfo *handshake_info_new(LocalIdentityInfo *localIdentity, RemoteIdentityInfo *remoteIdentity, IdentityRelation *relation) { - HandshakeInfo *handshake; - - assert(localIdentity); - assert(remoteIdentity); - - DDSRT_UNUSED_ARG(localIdentity); - DDSRT_UNUSED_ARG(remoteIdentity); - handshake = ddsrt_malloc(sizeof(*handshake)); - memset(handshake, 0, sizeof(*handshake)); - - security_object_init((SecurityObject *)handshake, SECURITY_OBJECT_KIND_HANDSHAKE, handshakeInfoFree); - - handshake->relation = relation; - handshake->shared_secret_handle_impl = NULL; - - return handshake; + assert(localIdentity); + assert(remoteIdentity); + DDSRT_UNUSED_ARG(localIdentity); + DDSRT_UNUSED_ARG(remoteIdentity); + HandshakeInfo *handshake = ddsrt_malloc(sizeof(*handshake)); + memset(handshake, 0, sizeof(*handshake)); + security_object_init((SecurityObject *)handshake, SECURITY_OBJECT_KIND_HANDSHAKE, handshake_info_free); + handshake->relation = relation; + handshake->shared_secret_handle_impl = NULL; + return handshake; } -static void -handshakeInfoFree( - SecurityObject *obj) +static IdentityRelation *find_identity_relation(const RemoteIdentityInfo *remote, int64_t lid) { - HandshakeInfo *handshake = (HandshakeInfo *)obj; + return (IdentityRelation *)security_object_find(remote->linkHash, lid); +} - CHECK_OBJECT_KIND(obj, SECURITY_OBJECT_KIND_HANDSHAKE); +static void remove_identity_relation(RemoteIdentityInfo *remote, IdentityRelation *relation) +{ + (void)ddsrt_hh_remove(remote->linkHash, relation); + security_object_free((SecurityObject *)relation); +} - if (handshake) { - if (handshake->ldh) { - EVP_PKEY_free(handshake->ldh); - } - if (handshake->rdh) { - EVP_PKEY_free(handshake->rdh); - } - if(handshake->shared_secret_handle_impl) { - ddsrt_free( handshake->shared_secret_handle_impl->shared_secret); - ddsrt_free( handshake->shared_secret_handle_impl ); - } - security_object_deinit((SecurityObject *)handshake); - ddsrt_free(handshake); +static HandshakeInfo *find_handshake(const dds_security_authentication_impl *auth, int64_t localId, int64_t remoteId) +{ + struct ddsrt_hh_iter it; + SecurityObject *obj; + for (obj = ddsrt_hh_iter_first(auth->objectHash, &it); obj; obj = ddsrt_hh_iter_next(&it)) + { + if (obj->kind == SECURITY_OBJECT_KIND_HANDSHAKE) + { + IdentityRelation *relation = ((HandshakeInfo *)obj)->relation; + assert(relation); + if (SECURITY_OBJECT_HANDLE(relation->localIdentity) == localId && SECURITY_OBJECT_HANDLE(relation->remoteIdentity) == remoteId) + return (HandshakeInfo *)obj; } + } + return NULL; } -static IdentityRelation * -find_identity_relation( - const RemoteIdentityInfo *remote, - int64_t lid) +static char * get_authentication_class_id(void) { - return (IdentityRelation *)security_object_find(remote->linkHash, lid); + size_t sz = strlen(AUTH_PROTOCOL_CLASS) + 5; + char *classId = ddsrt_malloc(sz); + snprintf(classId, sz, "%s:%1u.%1u", AUTH_PROTOCOL_CLASS, AUTH_PROTOCOL_VERSION_MAJOR, AUTH_PROTOCOL_VERSION_MINOR); + return classId; } -static void -remove_identity_relation( - RemoteIdentityInfo *remote, - IdentityRelation *relation) +static const char *get_authentication_algo(AuthenticationAlgoKind_t kind) { - (void)ddsrt_hh_remove(remote->linkHash, relation); - security_object_free((SecurityObject *) relation); + switch (kind) + { + case AUTH_ALGO_KIND_RSA_2048: + return "RSA-2048"; + case AUTH_ALGO_KIND_EC_PRIME256V1: + return "EC-prime256v1"; + default: + assert(0); + return ""; + } } -static HandshakeInfo * -find_handshake( - const dds_security_authentication_impl *auth, - int64_t localId, - int64_t remoteId) +static const char *get_dsign_algo(AuthenticationAlgoKind_t kind) { - struct ddsrt_hh_iter it; - SecurityObject *obj; - IdentityRelation *relation; - HandshakeInfo *found = NULL; - - for (obj = ddsrt_hh_iter_first(auth->objectHash, &it); obj && !found; obj = ddsrt_hh_iter_next(&it)) { - if (obj->kind == SECURITY_OBJECT_KIND_HANDSHAKE) { - relation = ((HandshakeInfo *)obj)->relation; - assert(relation); - if ((SECURITY_OBJECT_HANDLE(relation->localIdentity) == localId) && - (SECURITY_OBJECT_HANDLE(relation->remoteIdentity) == remoteId)) { - found = (HandshakeInfo *)obj; - } - } - } - - return found; + switch (kind) + { + case AUTH_ALGO_KIND_RSA_2048: + return AUTH_DSIG_ALGO_RSA_2048_SHA256_IDENT; + case AUTH_ALGO_KIND_EC_PRIME256V1: + return AUTH_DSIG_ALGO_ECDSA_SHA256_IDENT; + default: + assert(0); + return ""; + } } -static char * -get_authentication_class_id( - void) +static const char *get_kagree_algo(AuthenticationAlgoKind_t kind) { - char *classId; - size_t sz; - - sz = strlen(AUTH_PROTOCOL_CLASS) + 5; - - classId = ddsrt_malloc(sz); - snprintf(classId, sz, "%s:%1u.%1u", AUTH_PROTOCOL_CLASS, AUTH_PROTOCOL_VERSION_MAJOR, AUTH_PROTOCOL_VERSION_MINOR); - - return classId; + switch (kind) + { + case AUTH_ALGO_KIND_RSA_2048: + return AUTH_KAGREE_ALGO_RSA_2048_SHA256_IDENT; + case AUTH_ALGO_KIND_EC_PRIME256V1: + return AUTH_KAGREE_ALGO_ECDH_PRIME256V1_IDENT; + default: + assert(0); + return ""; + } } -static const char * -get_authentication_algo( - AuthenticationAlgoKind_t kind) +static AuthenticationAlgoKind_t get_dsign_algo_from_string(const char *name) { - const char *result; - switch (kind) { - case AUTH_ALGO_KIND_RSA_2048: - result = "RSA-2048"; - break; - case AUTH_ALGO_KIND_EC_PRIME256V1: - result = "EC-prime256v1"; - break; - default: - assert(0); - result = ""; - break; - } - - return result; + if (name) + { + if (strcmp(AUTH_DSIG_ALGO_RSA_2048_SHA256_IDENT, name) == 0) + return AUTH_ALGO_KIND_RSA_2048; + if (strcmp(AUTH_DSIG_ALGO_ECDSA_SHA256_IDENT, name) == 0) + return AUTH_ALGO_KIND_EC_PRIME256V1; + } + return AUTH_ALGO_KIND_UNKNOWN; } -static const char * -get_dsign_algo( - AuthenticationAlgoKind_t kind) +static AuthenticationAlgoKind_t get_kagree_algo_from_string(const char *name) { - const char *result; - switch (kind) { - case AUTH_ALGO_KIND_RSA_2048: - result = AUTH_DSIG_ALGO_RSA_2048_SHA256_IDENT; - break; - case AUTH_ALGO_KIND_EC_PRIME256V1: - result = AUTH_DSIG_ALGO_ECDSA_SHA256_IDENT; - break; - default: - assert(0); - result = ""; - break; - } - - return result; + if (name) + { + if (strcmp(AUTH_KAGREE_ALGO_RSA_2048_SHA256_IDENT, name) == 0) + return AUTH_ALGO_KIND_RSA_2048; + if (strcmp(AUTH_KAGREE_ALGO_ECDH_PRIME256V1_IDENT, name) == 0) + return AUTH_ALGO_KIND_EC_PRIME256V1; + } + return AUTH_ALGO_KIND_UNKNOWN; } -static const char * -get_kagree_algo( - AuthenticationAlgoKind_t kind) +static void free_binary_properties(DDS_Security_BinaryProperty_t *seq, uint32_t length) { - const char *result; - switch (kind) { - case AUTH_ALGO_KIND_RSA_2048: - result = AUTH_KAGREE_ALGO_RSA_2048_SHA256_IDENT; - break; - case AUTH_ALGO_KIND_EC_PRIME256V1: - result = AUTH_KAGREE_ALGO_ECDH_PRIME256V1_IDENT; - break; - default: - assert(0); - result = ""; - break; - } - - return result; + assert(seq); + for (uint32_t i = 0; i < length; i++) + { + ddsrt_free(seq[i].name); + ddsrt_free(seq[i].value._buffer); + } + ddsrt_free(seq); } -static AuthenticationAlgoKind_t -get_dsign_algo_from_string( - const char *name) +static void get_hash_binary_property_seq(const DDS_Security_BinaryPropertySeq *seq, unsigned char hash[SHA256_DIGEST_LENGTH]) { - AuthenticationAlgoKind_t algoKind = AUTH_ALGO_KIND_UNKNOWN; - - if (name) { - if (strcmp(AUTH_DSIG_ALGO_RSA_2048_SHA256_IDENT, name) == 0) { - algoKind = AUTH_ALGO_KIND_RSA_2048; - } else if (strcmp(AUTH_DSIG_ALGO_ECDSA_SHA256_IDENT, name) == 0) { - algoKind = AUTH_ALGO_KIND_EC_PRIME256V1; - } - } - - return algoKind; + unsigned char *buffer; + size_t size; + DDS_Security_Serializer serializer = DDS_Security_Serializer_new(4096, 4096); + DDS_Security_Serialize_BinaryPropertySeq(serializer, seq); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + SHA256(buffer, size, hash); + ddsrt_free(buffer); + DDS_Security_Serializer_free(serializer); } -static AuthenticationAlgoKind_t -get_kagree_algo_from_string( - const char *name) +static DDS_Security_ValidationResult_t create_signature(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) { - AuthenticationAlgoKind_t algoKind = AUTH_ALGO_KIND_UNKNOWN; + DDS_Security_ValidationResult_t result; + unsigned char *buffer; + size_t size; + DDS_Security_Serializer serializer = DDS_Security_Serializer_new(4096, 4096); - if (name) { - if (strcmp(AUTH_KAGREE_ALGO_RSA_2048_SHA256_IDENT, name) == 0) { - algoKind = AUTH_ALGO_KIND_RSA_2048; - } else if (strcmp(AUTH_KAGREE_ALGO_ECDH_PRIME256V1_IDENT, name) == 0) { - algoKind = AUTH_ALGO_KIND_EC_PRIME256V1; - } - } + DDS_Security_Serialize_BinaryPropertyArray(serializer, binary_properties, binary_properties_length); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); - return algoKind; + result = create_asymmetrical_signature(pkey, buffer, size, signature, signatureLen, ex); + ddsrt_free(buffer); + DDS_Security_Serializer_free(serializer); + + return result; } -static void -free_binary_properties( - DDS_Security_BinaryProperty_t *seq, - uint32_t length) +static DDS_Security_ValidationResult_t validate_signature(EVP_PKEY *pkey, const DDS_Security_BinaryProperty_t **properties, + const uint32_t properties_length, unsigned char *signature, size_t signatureLen, DDS_Security_SecurityException *ex) { - uint32_t i; - assert (seq); - for (i = 0; i < length; i++) { - ddsrt_free(seq[i].name); - ddsrt_free(seq[i].value._buffer); - } - ddsrt_free(seq); + DDS_Security_ValidationResult_t result; + unsigned char *buffer; + size_t size; + DDS_Security_Serializer serializer = DDS_Security_Serializer_new(4096, 4096); + + DDS_Security_Serialize_BinaryPropertyArray(serializer, properties, properties_length); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + + result = validate_asymmetrical_signature(pkey, buffer, size, signature, signatureLen, ex); + ddsrt_free(buffer); + DDS_Security_Serializer_free(serializer); + + return result; } -static void -get_hash_binary_property_seq( - const DDS_Security_BinaryPropertySeq *seq, - unsigned char hash[SHA256_DIGEST_LENGTH]) +static DDS_Security_ValidationResult_t compute_hash_value(HashValue_t value, const DDS_Security_BinaryProperty_t **properties, + const uint32_t properties_length, DDS_Security_SecurityException *ex) { - DDS_Security_Serializer serializer; - unsigned char *buffer; - size_t size; - - serializer = DDS_Security_Serializer_new(4096, 4096); - - DDS_Security_Serialize_BinaryPropertySeq(serializer, seq); - DDS_Security_Serializer_buffer(serializer, &buffer, &size); - SHA256(buffer, size, hash); - ddsrt_free(buffer); - DDS_Security_Serializer_free(serializer); + DDSRT_UNUSED_ARG(ex); + unsigned char *buffer; + size_t size; + DDS_Security_Serializer serializer = DDS_Security_Serializer_new(4096, 4096); + DDS_Security_Serialize_BinaryPropertyArray(serializer, properties, properties_length); + DDS_Security_Serializer_buffer(serializer, &buffer, &size); + SHA256(buffer, size, value); + ddsrt_free(buffer); + DDS_Security_Serializer_free(serializer); + return DDS_SECURITY_VALIDATION_OK; } -static DDS_Security_ValidationResult_t -create_signature( - 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) +static DDS_Security_BinaryProperty_t *hash_value_to_binary_property(const char *name, HashValue_t hash) { - 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(pkey, buffer, size, signature, signatureLen, ex); - ddsrt_free(buffer); - DDS_Security_Serializer_free(serializer); - - return result; + DDS_Security_BinaryProperty_t *bp = DDS_Security_BinaryProperty_alloc(); + DDS_Security_BinaryProperty_set_by_value(bp, name, hash, sizeof(HashValue_t)); + return bp; } -static DDS_Security_ValidationResult_t -validate_signature( - EVP_PKEY *pkey, - const DDS_Security_BinaryProperty_t **properties, - const uint32_t properties_length, - unsigned char *signature, - size_t signatureLen, - DDS_Security_SecurityException *ex) +static void validity_callback(struct dds_security_timed_dispatcher_t *d, dds_security_timed_cb_kind kind, void *listener, void *arg) { - 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, properties, properties_length); - DDS_Security_Serializer_buffer(serializer, &buffer, &size); - - result = validate_asymmetrical_signature(pkey, buffer, size, signature, signatureLen, ex); - ddsrt_free(buffer); - DDS_Security_Serializer_free(serializer); - - return result; + DDSRT_UNUSED_ARG(d); + assert(d); + assert(arg); + validity_cb_info *info = arg; + 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) + auth_listener->on_revoke_identity(auth_listener, (dds_security_authentication *)info->auth, info->hdl); + } + ddsrt_free(arg); } -static DDS_Security_ValidationResult_t -compute_hash_value( - HashValue_t value, - const DDS_Security_BinaryProperty_t **properties, - const uint32_t properties_length, - DDS_Security_SecurityException *ex) +static void add_validity_end_trigger(dds_security_authentication_impl *auth, const DDS_Security_IdentityHandle identity_handle, dds_time_t end) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - DDS_Security_Serializer serializer; - unsigned char *buffer; - size_t size; - - DDSRT_UNUSED_ARG(ex); - - serializer = DDS_Security_Serializer_new(4096, 4096); - - DDS_Security_Serialize_BinaryPropertyArray(serializer, properties, properties_length); - DDS_Security_Serializer_buffer(serializer, &buffer, &size); - SHA256(buffer, size, value); - ddsrt_free(buffer); - DDS_Security_Serializer_free(serializer); - - return result; + validity_cb_info *arg = ddsrt_malloc(sizeof(validity_cb_info)); + arg->auth = auth; + arg->hdl = identity_handle; + dds_security_timed_dispatcher_add(auth->timed_callbacks, auth->dispatcher, validity_callback, end, (void *)arg); } -static DDS_Security_BinaryProperty_t * -hash_value_to_binary_property( - const char *name, - HashValue_t hash) +static DDS_Security_ValidationResult_t get_adjusted_participant_guid(X509 *cert, const DDS_Security_GUID_t *candidate, DDS_Security_GUID_t *adjusted, DDS_Security_SecurityException *ex) { - DDS_Security_BinaryProperty_t *bp = DDS_Security_BinaryProperty_alloc(); + unsigned char high[SHA256_DIGEST_LENGTH], low[SHA256_DIGEST_LENGTH]; + unsigned char *subject = NULL; + size_t size = 0; - DDS_Security_BinaryProperty_set_by_value(bp, name, hash, sizeof(HashValue_t)); + assert(cert); + assert(candidate); + assert(adjusted); - return bp; -} + if (get_subject_name_DER_encoded(cert, &subject, &size, ex) != DDS_SECURITY_VALIDATION_OK) + return DDS_SECURITY_VALIDATION_FAILED; -static void -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 == 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) { - auth_listener->on_revoke_identity(auth_listener, - (dds_security_authentication*)info->auth, - info->hdl); - - } - } - ddsrt_free(arg); -} - - -static void -add_validity_end_trigger(dds_security_authentication_impl *auth, - const DDS_Security_IdentityHandle identity_handle, - dds_time_t end) -{ - validity_cb_info *arg = ddsrt_malloc(sizeof(validity_cb_info)); - arg->auth = auth; - arg->hdl = identity_handle; - dds_security_timed_dispatcher_add(auth->timed_callbacks, auth->dispatcher, - validity_callback, - end, - (void*)arg); -} - - - -#define ADJUSTED_GUID_PREFIX_FLAG 0x80 - -static DDS_Security_ValidationResult_t -get_adjusted_participant_guid( - X509 *cert, - const DDS_Security_GUID_t *candidate, - DDS_Security_GUID_t *adjusted, - DDS_Security_SecurityException *ex) -{ - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_FAILED; - unsigned char high[SHA256_DIGEST_LENGTH], low[SHA256_DIGEST_LENGTH]; - unsigned char *subject = NULL; - size_t size=0; - - assert(cert); - assert(candidate); - assert(adjusted); - - result = get_subject_name_DER_encoded(cert, &subject, &size, ex); - if ( result == DDS_SECURITY_VALIDATION_OK ) { - DDS_Security_octet hb = ADJUSTED_GUID_PREFIX_FLAG; - int i; - - SHA256(subject, size, 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); - } - - return result; + DDS_Security_octet hb = ADJUSTED_GUID_PREFIX_FLAG; + SHA256(subject, size, high); + SHA256(&candidate->prefix[0], sizeof(DDS_Security_GuidPrefix_t), low); + adjusted->entityId = candidate->entityId; + for (int i = 0; i < 6; i++) + { + adjusted->prefix[i] = hb | high[i] >> 1; + hb = (DDS_Security_octet)(high[i] << 7); + } + for (int i = 0; i < 6; i++) + adjusted->prefix[i + 6] = low[i]; + ddsrt_free(subject); + return DDS_SECURITY_VALIDATION_OK; } #undef ADJUSTED_GUID_PREFIX_FLAG -DDS_Security_ValidationResult_t -validate_local_identity( - dds_security_authentication *instance, - DDS_Security_IdentityHandle *local_identity_handle, - DDS_Security_GUID_t *adjusted_participant_guid, - const DDS_Security_DomainId domain_id, - const DDS_Security_Qos *participant_qos, - const DDS_Security_GUID_t *candidate_participant_guid, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t validate_local_identity(dds_security_authentication *instance, DDS_Security_IdentityHandle *local_identity_handle, + DDS_Security_GUID_t *adjusted_participant_guid, const DDS_Security_DomainId domain_id, const DDS_Security_Qos *participant_qos, + const DDS_Security_GUID_t *candidate_participant_guid, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - dds_security_authentication_impl *implementation = (dds_security_authentication_impl *) instance; - LocalIdentityInfo *identity; - char *identityCertPEM; - char *identityCaPEM; - char *privateKeyPEM; - char *password; - X509 *identityCert; - X509 *identityCA; - EVP_PKEY *privateKey; - char *trusted_ca_dir; - unsigned i; - dds_time_t certExpiry = DDS_TIME_INVALID; + dds_security_authentication_impl *implementation = (dds_security_authentication_impl *)instance; + LocalIdentityInfo *identity; + char *identityCertPEM, *identityCaPEM, *privateKeyPEM, *password, *trusted_ca_dir; + X509 *identityCert, *identityCA; + EVP_PKEY *privateKey; + dds_time_t certExpiry = DDS_TIME_INVALID; - /* validate provided arguments */ - if (!instance || !local_identity_handle || !adjusted_participant_guid || !participant_qos || !candidate_participant_guid) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "validate_local_identity: Invalid parameter provided"); - goto err_bad_param; - } + if (!instance || !local_identity_handle || !adjusted_participant_guid || !participant_qos || !candidate_participant_guid) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_local_identity: Invalid parameter provided"); + goto err_bad_param; + } - identityCertPEM = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_IDENTITY_CERT); - if (!identityCertPEM) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "validate_local_identity: missing property '%s'", PROPERTY_IDENTITY_CERT); - goto err_no_identity_cert; - } + if (!(identityCertPEM = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_IDENTITY_CERT))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_local_identity: missing property '%s'", PROPERTY_IDENTITY_CERT); + goto err_no_identity_cert; + } - identityCaPEM = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_IDENTITY_CA); - if (!identityCaPEM) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "validate_local_identity: missing property '%s'", PROPERTY_IDENTITY_CA); - goto err_no_identity_ca; - } + if (!(identityCaPEM = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_IDENTITY_CA))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_local_identity: missing property '%s'", PROPERTY_IDENTITY_CA); + goto err_no_identity_ca; + } - privateKeyPEM = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_PRIVATE_KEY); - if (!privateKeyPEM) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "validate_local_identity: missing property '%s'", PROPERTY_PRIVATE_KEY); - goto err_no_private_key; - } + if (!(privateKeyPEM = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_PRIVATE_KEY))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_local_identity: missing property '%s'", PROPERTY_PRIVATE_KEY); + goto err_no_private_key; + } - password = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_PASSWORD); + password = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_PASSWORD); - trusted_ca_dir = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_TRUSTED_CA_DIR); - if (trusted_ca_dir && *trusted_ca_dir != '\0') + trusted_ca_dir = DDS_Security_Property_get_value(&participant_qos->property.value, PROPERTY_TRUSTED_CA_DIR); + if (trusted_ca_dir && strlen(trusted_ca_dir) > 0) + { + if (get_trusted_ca_list(trusted_ca_dir, &(implementation->trustedCAList), ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_trusted_ca_dir; + } + + if (load_X509_certificate(identityCaPEM, &identityCA, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_identity_ca; + + /* check for CA if listed in trusted CA files */ + if (implementation->trustedCAList.length > 0) + { + const EVP_MD *digest = EVP_get_digestbyname("sha1"); + uint32_t size; + unsigned char hash_buffer[20], hash_buffer_trusted[20]; + DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_FAILED; + + X509_digest(identityCA, digest, hash_buffer, &size); + for (unsigned i = 0; i < implementation->trustedCAList.length; ++i) { - if ((result = get_trusted_ca_list (trusted_ca_dir, &(implementation->trustedCAList), ex)) != DDS_SECURITY_VALIDATION_OK) - goto err_inv_trusted_ca_dir; + X509_digest(implementation->trustedCAList.buffer[i], digest, hash_buffer_trusted, &size); + if (memcmp(hash_buffer_trusted, hash_buffer, 20) == 0) + { + result = DDS_SECURITY_VALIDATION_OK; + break; + } } - - result = load_X509_certificate(identityCaPEM, &identityCA, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_identity_ca; + if (result != DDS_SECURITY_VALIDATION_OK) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CA_NOT_TRUSTED_CODE, DDS_SECURITY_VALIDATION_FAILED, DDS_SECURITY_ERR_CA_NOT_TRUSTED_MESSAGE); + goto err_identity_ca_not_trusted; } + } + if (load_X509_certificate(identityCertPEM, &identityCert, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_identity_cert; + if (load_X509_private_key(privateKeyPEM, password, &privateKey, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_private_key; - /*check for CA if listed in trusted CA files*/ - if( implementation->trustedCAList.length != 0 ){ - const EVP_MD *digest = EVP_get_digestbyname("sha1"); - uint32_t size; - unsigned char hash_buffer[20]; - unsigned char hash_buffer_trusted[20]; - result = DDS_SECURITY_VALIDATION_FAILED; - X509_digest(identityCA, digest, hash_buffer, &size); - for (i = 0; i < implementation->trustedCAList.length; ++i) { - X509_digest(implementation->trustedCAList.buffer[i], digest, hash_buffer_trusted, &size); - if( memcmp( hash_buffer_trusted, hash_buffer,20 ) == 0){ - result = DDS_SECURITY_VALIDATION_OK; - break; - } - } + if (verify_certificate(identityCert, identityCA, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_verification_failed; - if (result != DDS_SECURITY_VALIDATION_OK) { /*not trusted*/ - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CA_NOT_TRUSTED_CODE, (int)result, DDS_SECURITY_ERR_CA_NOT_TRUSTED_MESSAGE); - goto err_identity_ca_not_trusted; - } - } - result = load_X509_certificate(identityCertPEM, &identityCert, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_identity_cert; - } + if (get_adjusted_participant_guid(identityCert, candidate_participant_guid, adjusted_participant_guid, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_adj_guid_failed; - result = load_X509_private_key(privateKeyPEM, password, &privateKey, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_private_key; - } + ddsrt_free(password); + ddsrt_free(privateKeyPEM); + ddsrt_free(identityCaPEM); + ddsrt_free(identityCertPEM); + ddsrt_free(trusted_ca_dir); - result = verify_certificate(identityCert, identityCA, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_verification_failed; - } + identity = local_identity_info_new(domain_id, identityCert, identityCA, privateKey, candidate_participant_guid, adjusted_participant_guid); + *local_identity_handle = IDENTITY_HANDLE(identity); - result = get_adjusted_participant_guid(identityCert, candidate_participant_guid, adjusted_participant_guid, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_adj_guid_failed; - } + if ((certExpiry = get_certificate_expiry(identityCert)) == DDS_TIME_INVALID) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Expiry date of the certificate is invalid"); + goto err_verification_failed; + } + else if (certExpiry != DDS_NEVER) + add_validity_end_trigger(implementation, *local_identity_handle, certExpiry); - ddsrt_free(password); - ddsrt_free(privateKeyPEM); - ddsrt_free(identityCaPEM); - ddsrt_free(identityCertPEM); - ddsrt_free(trusted_ca_dir); - - identity = localIdentityInfoNew(domain_id, identityCert, identityCA, privateKey, candidate_participant_guid, adjusted_participant_guid); - - *local_identity_handle = IDENTITY_HANDLE(identity); - - /* setup expiry listener */ - certExpiry = get_certificate_expiry( identityCert ); - - if( certExpiry == DDS_TIME_INVALID ){ - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Expiry date of the certificate is invalid"); - goto err_verification_failed; - } else if ( certExpiry != DDS_NEVER ){ - add_validity_end_trigger( implementation, - *local_identity_handle, - certExpiry); - } - - - ddsrt_mutex_lock(&implementation->lock); - (void)ddsrt_hh_add(implementation->objectHash, identity); - - ddsrt_mutex_unlock(&implementation->lock); - - return result; + ddsrt_mutex_lock(&implementation->lock); + (void)ddsrt_hh_add(implementation->objectHash, identity); + ddsrt_mutex_unlock(&implementation->lock); + return DDS_SECURITY_VALIDATION_OK; err_adj_guid_failed: err_verification_failed: - EVP_PKEY_free(privateKey); + EVP_PKEY_free(privateKey); err_inv_private_key: - X509_free(identityCert); + X509_free(identityCert); err_inv_identity_cert: err_identity_ca_not_trusted: - X509_free(identityCA); + X509_free(identityCA); err_inv_identity_ca: err_inv_trusted_ca_dir: - ddsrt_free(password); - ddsrt_free(privateKeyPEM); - ddsrt_free(trusted_ca_dir); + ddsrt_free(password); + ddsrt_free(privateKeyPEM); + ddsrt_free(trusted_ca_dir); err_no_private_key: - ddsrt_free(identityCaPEM); + ddsrt_free(identityCaPEM); err_no_identity_ca: - ddsrt_free(identityCertPEM); + ddsrt_free(identityCertPEM); err_no_identity_cert: err_bad_param: - return DDS_SECURITY_VALIDATION_FAILED; + return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_boolean -get_identity_token(dds_security_authentication *instance, - DDS_Security_IdentityToken *identity_token, - const DDS_Security_IdentityHandle handle, - DDS_Security_SecurityException *ex) +DDS_Security_boolean get_identity_token(dds_security_authentication *instance, DDS_Security_IdentityToken *identity_token, const DDS_Security_IdentityHandle handle, DDS_Security_SecurityException *ex) { - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - SecurityObject *obj; - LocalIdentityInfo *identity; - char *snCert, *snCA; + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + SecurityObject *obj; + LocalIdentityInfo *identity; + char *snCert, *snCA; - memset(identity_token, 0, sizeof(*identity_token)); + if (!instance || !identity_token) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); + goto err_bad_param; + } + memset(identity_token, 0, sizeof(*identity_token)); - /* validate provided arguments */ - if (!instance || !identity_token) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); - goto err_bad_param; - } + ddsrt_mutex_lock(&impl->lock); - ddsrt_mutex_lock(&impl->lock); + obj = security_object_find(impl->objectHash, handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid handle provided"); + goto err_inv_handle; + } + identity = (LocalIdentityInfo *)obj; + if (!(snCert = get_certificate_subject_name(identity->identityCert, ex))) + goto err_sn_cert; + if (!(snCA = get_certificate_subject_name(identity->identityCA, ex))) + goto err_sn_ca; - obj = security_object_find(impl->objectHash, handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid handle provided"); - goto err_inv_handle; - } - identity = (LocalIdentityInfo *)obj; + identity_token->class_id = get_authentication_class_id(); + identity_token->properties._length = 4; + identity_token->properties._buffer = DDS_Security_PropertySeq_allocbuf(4); + identity_token->properties._buffer[0].name = ddsrt_strdup(PROPERTY_CERT_SUBJECT_NAME); + identity_token->properties._buffer[0].value = snCert; + identity_token->properties._buffer[1].name = ddsrt_strdup(PROPERTY_CERT_ALGORITHM); + identity_token->properties._buffer[1].value = ddsrt_strdup(get_authentication_algo(get_authentication_algo_kind(identity->identityCert))); + identity_token->properties._buffer[2].name = ddsrt_strdup(PROPERTY_CA_SUBJECT_NAME); + identity_token->properties._buffer[2].value = snCA; + identity_token->properties._buffer[3].name = ddsrt_strdup(PROPERTY_CA_ALGORITHM); + identity_token->properties._buffer[3].value = ddsrt_strdup(get_authentication_algo(get_authentication_algo_kind(identity->identityCA))); - snCert = get_certificate_subject_name(identity->identityCert, ex); + ddsrt_mutex_unlock(&impl->lock); - if (!snCert) { - goto err_sn_cert; - } - - snCA = get_certificate_subject_name(identity->identityCA, ex); - if (!snCA) { - goto err_sn_ca; - } - - identity_token->class_id = get_authentication_class_id(); - identity_token->properties._length = 4; - identity_token->properties._buffer = DDS_Security_PropertySeq_allocbuf(4); - - identity_token->properties._buffer[0].name = ddsrt_strdup(PROPERTY_CERT_SUBJECT_NAME); - identity_token->properties._buffer[0].value = snCert; - - identity_token->properties._buffer[1].name = ddsrt_strdup(PROPERTY_CERT_ALGORITHM); - identity_token->properties._buffer[1].value = ddsrt_strdup(get_authentication_algo(get_auhentication_algo_kind(identity->identityCert))); - - identity_token->properties._buffer[2].name = ddsrt_strdup(PROPERTY_CA_SUBJECT_NAME); - identity_token->properties._buffer[2].value = snCA; - - identity_token->properties._buffer[3].name = ddsrt_strdup(PROPERTY_CA_ALGORITHM); - identity_token->properties._buffer[3].value = ddsrt_strdup(get_authentication_algo(get_auhentication_algo_kind(identity->identityCA))); - - ddsrt_mutex_unlock(&impl->lock); - - return true; + return true; err_sn_ca: - ddsrt_free(snCert); + ddsrt_free(snCert); err_sn_cert: err_inv_handle: - ddsrt_mutex_unlock(&impl->lock); + ddsrt_mutex_unlock(&impl->lock); err_bad_param: + return false; +} + +DDS_Security_boolean get_identity_status_token(dds_security_authentication *instance, DDS_Security_IdentityStatusToken *identity_status_token, const DDS_Security_IdentityHandle handle, DDS_Security_SecurityException *ex) +{ + DDSRT_UNUSED_ARG(identity_status_token); + DDSRT_UNUSED_ARG(handle); + DDSRT_UNUSED_ARG(ex); + DDSRT_UNUSED_ARG(instance); + return true; +} + +DDS_Security_boolean set_permissions_credential_and_token(dds_security_authentication *instance, const DDS_Security_IdentityHandle handle, + const DDS_Security_PermissionsCredentialToken *permissions_credential, const DDS_Security_PermissionsToken *permissions_token, DDS_Security_SecurityException *ex) +{ + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + LocalIdentityInfo *identity; + + if (!instance || handle == DDS_SECURITY_HANDLE_NIL || !permissions_credential || !permissions_token) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); return false; -} + } -DDS_Security_boolean get_identity_status_token( - dds_security_authentication *instance, - DDS_Security_IdentityStatusToken *identity_status_token, - const DDS_Security_IdentityHandle handle, - DDS_Security_SecurityException *ex) -{ - DDSRT_UNUSED_ARG(identity_status_token); - DDSRT_UNUSED_ARG(handle); - DDSRT_UNUSED_ARG(ex); - DDSRT_UNUSED_ARG(instance); + if (!permissions_credential->class_id || strcmp(permissions_credential->class_id, ACCESS_PERMISSIONS_CREDENTIAL_TOKEN_ID) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); + return false; + } - return true; -} - -DDS_Security_boolean -set_permissions_credential_and_token( - dds_security_authentication *instance, - const DDS_Security_IdentityHandle handle, - const DDS_Security_PermissionsCredentialToken *permissions_credential, - const DDS_Security_PermissionsToken *permissions_token, - DDS_Security_SecurityException *ex) -{ - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - LocalIdentityInfo *identity; - - /* validate provided arguments */ - if ((!instance) || - (handle == DDS_SECURITY_HANDLE_NIL) || - (!permissions_credential) || - (!permissions_token) ){ - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); - return false; - } - - if (!permissions_credential->class_id || - (strcmp(permissions_credential->class_id, ACCESS_PERMISSIONS_CREDENTIAL_TOKEN_ID) != 0)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); - return false; - } - - if ((permissions_credential->properties._length == 0) || - (permissions_credential->properties._buffer[0].name == NULL) || - (strcmp(permissions_credential->properties._buffer[0].name, ACCESS_PROPERTY_PERMISSION_DOCUMENT) != 0)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); - return false; - } - - ddsrt_mutex_lock(&impl->lock); - - identity = (LocalIdentityInfo *)security_object_find(impl->objectHash, handle); - if (!identity || !SECURITY_OBJECT_VALID(identity, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) { - ddsrt_mutex_unlock(&impl->lock); - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid handle provided"); - return false; - } - - if (permissions_credential->properties._buffer[0].value) { - identity->permissionsDocument = ddsrt_strdup(permissions_credential->properties._buffer[0].value); - } else { - identity->permissionsDocument = ddsrt_strdup(""); - } + if (permissions_credential->properties._length == 0 || permissions_credential->properties._buffer[0].name == NULL + || strcmp(permissions_credential->properties._buffer[0].name, ACCESS_PROPERTY_PERMISSION_DOCUMENT) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid parameter provided"); + return false; + } + ddsrt_mutex_lock(&impl->lock); + identity = (LocalIdentityInfo *)security_object_find(impl->objectHash, handle); + if (!identity || !SECURITY_OBJECT_VALID(identity, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) + { ddsrt_mutex_unlock(&impl->lock); + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "get_identity_token: Invalid handle provided"); + return false; + } + identity->permissionsDocument = ddsrt_strdup(permissions_credential->properties._buffer[0].value ? permissions_credential->properties._buffer[0].value : ""); + ddsrt_mutex_unlock(&impl->lock); - return true; + return true; } - -static DDS_Security_ValidationResult_t -validate_remote_identity_token( - const LocalIdentityInfo *localIdent, - const DDS_Security_IdentityToken *token, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t validate_remote_identity_token(const LocalIdentityInfo *localIdent, const DDS_Security_IdentityToken *token, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - - DDSRT_UNUSED_ARG(localIdent); - - if (token->class_id) { - size_t sz = strlen(AUTH_PROTOCOL_CLASS); - - if (strncmp(AUTH_PROTOCOL_CLASS, token->class_id, sz) == 0) { - char *ptr = &token->class_id[sz]; - char postfix[2]; - unsigned major, minor; - - DDSRT_WARNING_MSVC_OFF(4996); - if (sscanf(ptr, ":%u.%u%1s", &major, &minor, postfix) == 2) { - DDSRT_WARNING_MSVC_ON(4996); - if (major == AUTH_PROTOCOL_VERSION_MAJOR) { - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "remote identity token: version %u.%u not supported", major, minor); - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "remote identity token: class_id has wrong format"); - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "remote identity token: class_id='%s' not supported", token->class_id); - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "remote identity token: class_id is empty"); - } - - return result; -} - -static DDS_Security_ValidationResult_t -validate_auth_request_token( - const DDS_Security_IdentityToken *token, - AuthenticationChallenge **challenge, - DDS_Security_SecurityException *ex) -{ - uint32_t index; - int found = 0; - - assert(token); - - if (!token->class_id) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "AuthRequestMessageToken invalid: missing class_id"); - goto err_inv_token; - } - - if (strncmp(token->class_id, AUTH_REQUEST_TOKEN_CLASS_ID, strlen(AUTH_REQUEST_TOKEN_CLASS_ID)) != 0) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "AuthRequestMessageToken invalid: class_id '%s' is invalid", token->class_id); - goto err_inv_token; - } - - if (!token->binary_properties._buffer) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "AuthRequestMessageToken invalid: properties are missing"); - goto err_inv_token; - } - - for (index = 0; index < token->binary_properties._length; index++) { - size_t len = strlen(AUTH_REQUEST_TOKEN_FUTURE_PROP_NAME); - if (token->binary_properties._buffer[index].name && - (strncmp(token->binary_properties._buffer[index].name, AUTH_REQUEST_TOKEN_FUTURE_PROP_NAME, len) == 0)) { - found = 1; - break; - } - } - - if (!found) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "AuthRequestMessageToken invalid: future_challenge not found"); - goto err_inv_token; - } - - if (token->binary_properties._buffer[index].value._length != sizeof(AuthenticationChallenge)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "AuthRequestMessageToken invalid: future_challenge invalid size"); - goto err_inv_token; - } - - if (!token->binary_properties._buffer[index].value._buffer) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "AuthRequestMessageToken invalid: future_challenge invalid size"); - goto err_inv_token; - } - - if (challenge) { - *challenge = ddsrt_malloc(sizeof(AuthenticationChallenge)); - memcpy(*challenge, &token->binary_properties._buffer[index].value._buffer[0], sizeof(AuthenticationChallenge)); - } - - return DDS_SECURITY_VALIDATION_OK; - -err_inv_token: + DDSRT_UNUSED_ARG(localIdent); + if (!token->class_id) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "remote identity token: class_id is empty"); return DDS_SECURITY_VALIDATION_FAILED; + } + + size_t sz = strlen(AUTH_PROTOCOL_CLASS); + if (strncmp(AUTH_PROTOCOL_CLASS, token->class_id, sz) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "remote identity token: class_id='%s' not supported", token->class_id); + return DDS_SECURITY_VALIDATION_FAILED; + } + + char *ptr = &token->class_id[sz]; + unsigned major, minor; + char postfix[2]; + DDSRT_WARNING_MSVC_OFF(4996); + if (sscanf(ptr, ":%u.%u%1s", &major, &minor, postfix) != 2) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "remote identity token: class_id has wrong format"); + return DDS_SECURITY_VALIDATION_FAILED; + } + DDSRT_WARNING_MSVC_ON(4996); + + if (major != AUTH_PROTOCOL_VERSION_MAJOR) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "remote identity token: version %u.%u not supported", major, minor); + return DDS_SECURITY_VALIDATION_FAILED; + } + + return DDS_SECURITY_VALIDATION_OK; } -static void -fill_auth_request_token( - DDS_Security_AuthRequestMessageToken *token, - AuthenticationChallenge *challenge) +static DDS_Security_ValidationResult_t validate_auth_request_token(const DDS_Security_IdentityToken *token, AuthenticationChallenge **challenge, DDS_Security_SecurityException *ex) { - uint32_t len = sizeof(challenge->value); + uint32_t index; + int found = 0; + assert(token); + if (!token->class_id) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "AuthRequestMessageToken invalid: missing class_id"); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (strncmp(token->class_id, AUTH_REQUEST_TOKEN_CLASS_ID, strlen(AUTH_REQUEST_TOKEN_CLASS_ID)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "AuthRequestMessageToken invalid: class_id '%s' is invalid", token->class_id); + return DDS_SECURITY_VALIDATION_FAILED; + } + if (!token->binary_properties._buffer) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "AuthRequestMessageToken invalid: properties are missing"); + return DDS_SECURITY_VALIDATION_FAILED; + } - DDS_Security_DataHolder_deinit(token); + for (index = 0; index < token->binary_properties._length; index++) + { + size_t len = strlen(AUTH_REQUEST_TOKEN_FUTURE_PROP_NAME); + if (token->binary_properties._buffer[index].name && strncmp(token->binary_properties._buffer[index].name, AUTH_REQUEST_TOKEN_FUTURE_PROP_NAME, len) == 0) + { + found = 1; + break; + } + } + if (!found) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "AuthRequestMessageToken invalid: future_challenge not found"); + return DDS_SECURITY_VALIDATION_FAILED; + } - token->class_id = ddsrt_strdup(AUTH_REQUEST_TOKEN_CLASS_ID); - 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); + if (token->binary_properties._buffer[index].value._length != sizeof(AuthenticationChallenge) + || !token->binary_properties._buffer[index].value._buffer) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "AuthRequestMessageToken invalid: future_challenge invalid size"); + return DDS_SECURITY_VALIDATION_FAILED; + } - token->binary_properties._buffer->value._length = len; - token->binary_properties._buffer->value._buffer = ddsrt_malloc(len); - memcpy(token->binary_properties._buffer->value._buffer, challenge->value, len); - token->binary_properties._buffer->propagate = true; + if (challenge) + { + *challenge = ddsrt_malloc(sizeof(AuthenticationChallenge)); + memcpy(*challenge, &token->binary_properties._buffer[index].value._buffer[0], sizeof(AuthenticationChallenge)); + } + return DDS_SECURITY_VALIDATION_OK; } -DDS_Security_ValidationResult_t -validate_remote_identity( - dds_security_authentication *instance, - DDS_Security_IdentityHandle *remote_identity_handle, - DDS_Security_AuthRequestMessageToken *local_auth_request_token, - const DDS_Security_AuthRequestMessageToken *remote_auth_request_token, - const DDS_Security_IdentityHandle local_identity_handle, - const DDS_Security_IdentityToken *remote_identity_token, - const DDS_Security_GUID_t *remote_participant_guid, - DDS_Security_SecurityException *ex) +static void fill_auth_request_token(DDS_Security_AuthRequestMessageToken *token, AuthenticationChallenge *challenge) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - SecurityObject *obj; - LocalIdentityInfo *localIdent; - RemoteIdentityInfo *remoteIdent; - IdentityRelation *relation; - AuthenticationChallenge *lchallenge = NULL, *rchallenge = NULL; - int r; + uint32_t len = sizeof(challenge->value); + DDS_Security_DataHolder_deinit(token); + token->class_id = ddsrt_strdup(AUTH_REQUEST_TOKEN_CLASS_ID); + 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._length = len; + token->binary_properties._buffer->value._buffer = ddsrt_malloc(len); + memcpy(token->binary_properties._buffer->value._buffer, challenge->value, len); + token->binary_properties._buffer->propagate = true; +} - /* validate provided arguments */ - if (!instance || !remote_identity_handle || !local_auth_request_token || !remote_identity_token || !remote_participant_guid) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_remote_identity: Invalid parameter provided"); - goto err_bad_param; +DDS_Security_ValidationResult_t validate_remote_identity(dds_security_authentication *instance, DDS_Security_IdentityHandle *remote_identity_handle, + DDS_Security_AuthRequestMessageToken *local_auth_request_token, const DDS_Security_AuthRequestMessageToken *remote_auth_request_token, const DDS_Security_IdentityHandle local_identity_handle, + const DDS_Security_IdentityToken *remote_identity_token, const DDS_Security_GUID_t *remote_participant_guid, DDS_Security_SecurityException *ex) +{ + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + SecurityObject *obj; + LocalIdentityInfo *localIdent; + RemoteIdentityInfo *remoteIdent; + IdentityRelation *relation; + AuthenticationChallenge *lchallenge = NULL, *rchallenge = NULL; + + if (!instance || !remote_identity_handle || !local_auth_request_token || !remote_identity_token || !remote_participant_guid) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_remote_identity: Invalid parameter provided"); + goto err_bad_param; + } + + ddsrt_mutex_lock(&impl->lock); + obj = security_object_find(impl->objectHash, local_identity_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_remote_identity: Invalid handle provided"); + goto err_inv_handle; + } + localIdent = (LocalIdentityInfo *)obj; + + if (validate_remote_identity_token(localIdent, remote_identity_token, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_remote_identity_token; + + /* When the remote_auth_request_token is not null, check if it's contents is valid and set the futureChallenge from the data contained in the remote_auth_request_token. */ + if (remote_auth_request_token) + { + if (validate_auth_request_token(remote_auth_request_token, &rchallenge, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_auth_req_token; + } + + if ((lchallenge = generate_challenge(ex)) == NULL) + goto err_alloc_challenge; + + /* The validate_remote_identity will also create a handshake structure which contains the relation between + a local an remote identity. This handshake structure is inserted in the remote identity structure. */ + + /* Check if the remote identity has already been validated by a previous validation request. */ + if (!(remoteIdent = find_remote_identity_by_guid(impl->remoteGuidHash, remote_participant_guid))) + { + remoteIdent = remote_identity_info_new(remote_participant_guid, remote_identity_token); + (void)ddsrt_hh_add(impl->objectHash, remoteIdent); + (void)ddsrt_hh_add(impl->remoteGuidHash, remoteIdent); + relation = identity_relation_new(localIdent, remoteIdent, lchallenge, rchallenge); + (void)ddsrt_hh_add(remoteIdent->linkHash, relation); + } + else + { + /* When the remote identity has already been validated before, check if the remote identity token matches with the existing one */ + if (!DDS_Security_DataHolder_equal(remoteIdent->remoteIdentityToken, remote_identity_token)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_remote_identity: remote_identity_token does not match with previously received one"); + goto err_inv_duplicate; } - ddsrt_mutex_lock(&impl->lock); - - obj = security_object_find(impl->objectHash, local_identity_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "validate_remote_identity: Invalid handle provided"); - goto err_inv_handle; + if (!(relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)))) + { + relation = identity_relation_new(localIdent, remoteIdent, lchallenge, rchallenge); + int r = ddsrt_hh_add(remoteIdent->linkHash, relation); + assert(r); + (void)r; } - localIdent = (LocalIdentityInfo *) obj; - - /* Check if the provided remote_identity_token is compatible */ - result = validate_remote_identity_token(localIdent, remote_identity_token, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_remote_identity_token; + else + { + if (remote_auth_request_token) + { + assert(rchallenge); + ddsrt_free(relation->rchallenge); + relation->rchallenge = rchallenge; + } + ddsrt_free(lchallenge); } + } - /* When the remote_auth_request_token is not null, check if it's contents is valid and - * set the futureChallenge from the data contained in the remote_auth_request_token. - */ - if (remote_auth_request_token) { - result = validate_auth_request_token(remote_auth_request_token, &rchallenge, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_auth_req_token; - } - } + ddsrt_mutex_unlock(&impl->lock); - if ((lchallenge = generate_challenge(ex)) == NULL) { - goto err_alloc_challenge; - } + if (!remote_auth_request_token) + { + /* Create local_auth_request_token with contents set to the challenge */ + fill_auth_request_token(local_auth_request_token, relation->lchallenge); + } + else + { + /* Set local_auth_request token to TokenNil */ + DDS_Security_set_token_nil(local_auth_request_token); + } - /* The validate_remote_identity will also create a handshake structure which contains the - * relation between an local an remote identity. This handshake structure is inserted in - * the remote identity structure. - */ - - /* Check if the remote identity has already been validated by a previous validation request. */ - remoteIdent = find_remote_identity_by_guid(impl->remoteGuidHash, remote_participant_guid); - if (!remoteIdent) { - remoteIdent = remoteIdentityInfoNew(remote_participant_guid, remote_identity_token); - (void)ddsrt_hh_add(impl->objectHash, remoteIdent); - (void)ddsrt_hh_add(impl->remoteGuidHash, remoteIdent); - relation = identityRelationNew(localIdent, remoteIdent, lchallenge, rchallenge); - (void)ddsrt_hh_add(remoteIdent->linkHash, relation); - } else { - /* When the remote identity has already been validated before, - check if the remote identity token matches with the existing one - */ - if (!DDS_Security_DataHolder_equal(remoteIdent->remoteIdentityToken, remote_identity_token)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "validate_remote_identity: remote_identity_token does not match with previously received one"); - goto err_inv_duplicate; - } - - relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)); - if (!relation) { - relation = identityRelationNew(localIdent, remoteIdent, lchallenge, rchallenge); - r = ddsrt_hh_add(remoteIdent->linkHash, relation); - assert(r); - (void)r; - } else { - if (remote_auth_request_token) { - assert(rchallenge); - ddsrt_free(relation->rchallenge); - relation->rchallenge = rchallenge; - } - ddsrt_free(lchallenge); - } - } - - ddsrt_mutex_unlock(&impl->lock); - - if (!remote_auth_request_token) { - /* Create local_auth_request_token with contents set to the challenge */ - fill_auth_request_token(local_auth_request_token, relation->lchallenge); - } else { - /* Set local_auth_request token to TokenNil */ - DDS_Security_set_token_nil(local_auth_request_token); - } - - *remote_identity_handle = IDENTITY_HANDLE(remoteIdent);; - - if (memcmp(&localIdent->adjustedGUID, &remoteIdent->guid, sizeof(DDS_Security_GUID_t)) < 0) { - result = DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST; - } else { - result = DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE; - } - - return result; + *remote_identity_handle = IDENTITY_HANDLE(remoteIdent); + return memcmp(&localIdent->adjustedGUID, &remoteIdent->guid, sizeof(DDS_Security_GUID_t)) < 0 ? + DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_REQUEST : DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE; err_inv_duplicate: - ddsrt_free(lchallenge); + ddsrt_free(lchallenge); err_alloc_challenge: - ddsrt_free(rchallenge); + ddsrt_free(rchallenge); err_inv_auth_req_token: err_remote_identity_token: err_inv_handle: - ddsrt_mutex_unlock(&impl->lock); + ddsrt_mutex_unlock(&impl->lock); err_bad_param: - return DDS_SECURITY_VALIDATION_FAILED; + return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_ValidationResult_t -begin_handshake_request( - dds_security_authentication *instance, - DDS_Security_HandshakeHandle *handshake_handle, - DDS_Security_HandshakeMessageToken *handshake_message, - const DDS_Security_IdentityHandle initiator_identity_handle, - const DDS_Security_IdentityHandle replier_identity_handle, - const DDS_Security_OctetSeq *serialized_local_participant_data, - DDS_Security_SecurityException *ex) +DDS_Security_ValidationResult_t begin_handshake_request(dds_security_authentication *instance, DDS_Security_HandshakeHandle *handshake_handle, + DDS_Security_HandshakeMessageToken *handshake_message, const DDS_Security_IdentityHandle initiator_identity_handle, const DDS_Security_IdentityHandle replier_identity_handle, + const DDS_Security_OctetSeq *serialized_local_participant_data, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - HandshakeInfo *handshake = NULL; - IdentityRelation *relation = NULL; - SecurityObject *obj; - LocalIdentityInfo *localIdent; - RemoteIdentityInfo *remoteIdent; - EVP_PKEY *dhkey; - 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 *dh1; - DDS_Security_BinaryProperty_t *challenge; - unsigned char *certData; - unsigned char *dhPubKeyData = NULL; - uint32_t certDataSize, dhPubKeyDataSize; - int created = 0; + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + HandshakeInfo *handshake = NULL; + IdentityRelation *relation = NULL; + SecurityObject *obj; + LocalIdentityInfo *localIdent; + RemoteIdentityInfo *remoteIdent; + EVP_PKEY *dhkey; + DDS_Security_BinaryProperty_t *tokens, *c_id, *c_perm, *c_pdata, *c_dsign_algo, *c_kagree_algo, *hash_c1, *dh1, *challenge; + unsigned char *certData, *dhPubKeyData = NULL; + uint32_t certDataSize, dhPubKeyDataSize; + int created = 0; - /* validate provided arguments */ - if (!instance || !handshake_handle || !handshake_message || !serialized_local_participant_data) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "begin_handshake_request: Invalid parameter provided"); - goto err_bad_param; - } + if (!instance || !handshake_handle || !handshake_message || !serialized_local_participant_data) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_request: Invalid parameter provided"); + goto err_bad_param; + } - ddsrt_mutex_lock(&impl->lock); + ddsrt_mutex_lock(&impl->lock); - obj = security_object_find(impl->objectHash, initiator_identity_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "begin_handshake_request: Invalid initiator_identity_handle provided"); - goto err_inv_handle; - } - localIdent = (LocalIdentityInfo *) obj; + obj = security_object_find(impl->objectHash, initiator_identity_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_request: Invalid initiator_identity_handle provided"); + goto err_inv_handle; + } + localIdent = (LocalIdentityInfo *)obj; - obj = security_object_find(impl->objectHash, replier_identity_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_REMOTE_IDENTITY)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "begin_handshake_request: Invalid replier_identity_handle provided"); - goto err_inv_handle; - } - remoteIdent = (RemoteIdentityInfo *)obj; + obj = security_object_find(impl->objectHash, replier_identity_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_REMOTE_IDENTITY)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_request: Invalid replier_identity_handle provided"); + goto err_inv_handle; + } + remoteIdent = (RemoteIdentityInfo *)obj; - result = get_certificate_contents(localIdent->identityCert, &certData, &certDataSize, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_alloc_cid; - } - - handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(localIdent), SECURITY_OBJECT_HANDLE(remoteIdent)); - if (!handshake) { - relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)); - assert(relation); - handshake = handshakeInfoNew(localIdent, remoteIdent, relation); - handshake->created_in = CREATEDREQUEST; - (void)ddsrt_hh_add(impl->objectHash, handshake); - created = 1; - } else { - relation = handshake->relation; - assert(relation); - } - - if (!handshake->ldh) { - result = generate_dh_keys(&dhkey, localIdent->kagreeAlgoKind, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_gen_dh_keys; - } - - handshake->ldh = dhkey; - } - - result = dh_public_key_to_oct(handshake->ldh, localIdent->kagreeAlgoKind, &dhPubKeyData, &dhPubKeyDataSize, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_get_public_key; - } - - if (localIdent->pdata._length == 0) { - DDS_Security_OctetSeq_copy(&localIdent->pdata, serialized_local_participant_data); - } - - 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]; - challenge = &tokens[7]; - - /* Store the Identity Certificate associated with the local identify in c.id property */ - DDS_Security_BinaryProperty_set_by_ref(c_id, "c.id", certData, certDataSize); - - /* Store the permission document in the c.perm property */ - if (localIdent->permissionsDocument) { - DDS_Security_BinaryProperty_set_by_string(c_perm, "c.perm", localIdent->permissionsDocument); - } else { - DDS_Security_BinaryProperty_set_by_string(c_perm, "c.perm", ""); - } - - /* Store the provided local_participant_data in the c.pdata property */ - DDS_Security_BinaryProperty_set_by_value(c_pdata, "c.pdata", serialized_local_participant_data->_buffer, serialized_local_participant_data->_length); - - /* Set the used signing algorithm descriptor in c.dsign_algo */ - DDS_Security_BinaryProperty_set_by_string(c_dsign_algo, "c.dsign_algo", get_dsign_algo(localIdent->dsignAlgoKind)); - - /* Set the used key algorithm descriptor in c.kagree_algo */ - DDS_Security_BinaryProperty_set_by_string(c_kagree_algo, "c.kagree_algo", get_kagree_algo(localIdent->kagreeAlgoKind)); - - /* Calculate the hash_c1 */ - { - DDS_Security_BinaryPropertySeq bseq; - - bseq._length = 5; - bseq._buffer = tokens; - - get_hash_binary_property_seq(&bseq, handshake->hash_c1); - DDS_Security_BinaryProperty_set_by_value(hash_c1, "hash_c1", handshake->hash_c1, sizeof(HashValue_t)); - } - - /* Set the DH public key associated with the local participant in dh1 property */ - assert(dhPubKeyData); - assert(dhPubKeyDataSize < 1200); - DDS_Security_BinaryProperty_set_by_ref(dh1, "dh1", dhPubKeyData, dhPubKeyDataSize); - - /* Set the challenge in challenge1 property */ - DDS_Security_BinaryProperty_set_by_value(challenge, "challenge1", relation->lchallenge->value, sizeof(AuthenticationChallenge)); + if (get_certificate_contents(localIdent->identityCert, &certData, &certDataSize, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_alloc_cid; + if (!(handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(localIdent), SECURITY_OBJECT_HANDLE(remoteIdent)))) + { + relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)); + assert(relation); + handshake = handshake_info_new(localIdent, remoteIdent, relation); + handshake->created_in = CREATEDREQUEST; (void)ddsrt_hh_add(impl->objectHash, handshake); + created = 1; + } + else + { + relation = handshake->relation; + assert(relation); + } - ddsrt_mutex_unlock(&impl->lock); + if (!handshake->ldh) + { + if (generate_dh_keys(&dhkey, localIdent->kagreeAlgoKind, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_gen_dh_keys; + handshake->ldh = dhkey; + } - handshake_message->class_id = ddsrt_strdup(AUTH_HANDSHAKE_REQUEST_TOKEN_ID); - handshake_message->properties._length = 0; - handshake_message->properties._buffer = NULL; - handshake_message->binary_properties._length = 8; - handshake_message->binary_properties._buffer = tokens; - *handshake_handle = HANDSHAKE_HANDLE(handshake); + if (dh_public_key_to_oct(handshake->ldh, localIdent->kagreeAlgoKind, &dhPubKeyData, &dhPubKeyDataSize, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_get_public_key; - return DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE; + if (localIdent->pdata._length == 0) + DDS_Security_OctetSeq_copy(&localIdent->pdata, serialized_local_participant_data); + + 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]; + challenge = &tokens[7]; + + DDS_Security_BinaryProperty_set_by_ref(c_id, "c.id", certData, certDataSize); + DDS_Security_BinaryProperty_set_by_string(c_perm, "c.perm", localIdent->permissionsDocument ? localIdent->permissionsDocument : ""); + DDS_Security_BinaryProperty_set_by_value(c_pdata, "c.pdata", serialized_local_participant_data->_buffer, serialized_local_participant_data->_length); + DDS_Security_BinaryProperty_set_by_string(c_dsign_algo, "c.dsign_algo", get_dsign_algo(localIdent->dsignAlgoKind)); + DDS_Security_BinaryProperty_set_by_string(c_kagree_algo, "c.kagree_algo", get_kagree_algo(localIdent->kagreeAlgoKind)); + + { + DDS_Security_BinaryPropertySeq bseq = { ._length = 5, ._buffer = tokens }; + get_hash_binary_property_seq(&bseq, handshake->hash_c1); + DDS_Security_BinaryProperty_set_by_value(hash_c1, "hash_c1", handshake->hash_c1, sizeof(HashValue_t)); + } + + /* Set the DH public key associated with the local participant in dh1 property */ + assert(dhPubKeyData); + assert(dhPubKeyDataSize < 1200); + DDS_Security_BinaryProperty_set_by_ref(dh1, "dh1", dhPubKeyData, dhPubKeyDataSize); + + /* Set the challenge in challenge1 property */ + DDS_Security_BinaryProperty_set_by_value(challenge, "challenge1", relation->lchallenge->value, sizeof(AuthenticationChallenge)); + + (void)ddsrt_hh_add(impl->objectHash, handshake); + + ddsrt_mutex_unlock(&impl->lock); + + handshake_message->class_id = ddsrt_strdup(AUTH_HANDSHAKE_REQUEST_TOKEN_ID); + handshake_message->properties._length = 0; + handshake_message->properties._buffer = NULL; + handshake_message->binary_properties._length = 8; + handshake_message->binary_properties._buffer = tokens; + *handshake_handle = HANDSHAKE_HANDLE(handshake); + + return DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE; err_get_public_key: err_gen_dh_keys: - if (created) { - (void)ddsrt_hh_remove(impl->objectHash, handshake); - security_object_free((SecurityObject *)handshake); - } + if (created) + { + (void)ddsrt_hh_remove(impl->objectHash, handshake); + security_object_free((SecurityObject *)handshake); + } err_alloc_cid: - ddsrt_free(certData); + ddsrt_free(certData); err_inv_handle: - ddsrt_mutex_unlock(&impl->lock); + ddsrt_mutex_unlock(&impl->lock); err_bad_param: - return DDS_SECURITY_VALIDATION_FAILED; + return DDS_SECURITY_VALIDATION_FAILED; } -static DDS_Security_ValidationResult_t -validate_pdata( - const DDS_Security_OctetSeq *seq, - X509 *cert, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t validate_pdata(const DDS_Security_OctetSeq *seq, X509 *cert, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - DDS_Security_Deserializer deserializer; - DDS_Security_ParticipantBuiltinTopicData *pdata; - DDS_Security_GUID_t cguid, aguid; + DDS_Security_ParticipantBuiltinTopicData *pdata; + DDS_Security_GUID_t cguid, aguid; + DDS_Security_Deserializer deserializer = DDS_Security_Deserializer_new(seq->_buffer, seq->_length); + if (!deserializer) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: c.pdata invalid encoding"); + goto failed_deser; + } - deserializer = DDS_Security_Deserializer_new(seq->_buffer, seq->_length); - if (!deserializer) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: c.pdata invalid encoding"); - goto err_invalid_data; - } + pdata = DDS_Security_ParticipantBuiltinTopicData_alloc(); + if (!DDS_Security_Deserialize_ParticipantBuiltinTopicData(deserializer, pdata, ex)) + goto failed; - pdata = DDS_Security_ParticipantBuiltinTopicData_alloc(); + memset(&cguid, 0, sizeof(DDS_Security_GUID_t)); + if (get_adjusted_participant_guid(cert, &cguid, &aguid, ex) != DDS_SECURITY_VALIDATION_OK) + goto failed; - if (!DDS_Security_Deserialize_ParticipantBuiltinTopicData(deserializer, pdata, ex)) { - result = DDS_SECURITY_VALIDATION_FAILED; - goto err_incorrect_data; - } + DDS_Security_BuiltinTopicKey_t key; + DDS_Security_BuiltinTopicKeyBE(key, pdata->key); + if (memcmp(key, aguid.prefix, 6) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: c.pdata contains incorrect participant guid"); + goto failed; + } + DDS_Security_ParticipantBuiltinTopicData_free(pdata); + DDS_Security_Deserializer_free(deserializer); + return DDS_SECURITY_VALIDATION_OK; - memset(&cguid, 0, sizeof(DDS_Security_GUID_t)); - result = get_adjusted_participant_guid(cert, &cguid, &aguid, ex); - if (result == DDS_SECURITY_VALIDATION_OK) { - DDS_Security_BuiltinTopicKey_t key; - DDS_Security_BuiltinTopicKeyBE(key, pdata->key); - if (memcmp(key, aguid.prefix, 6) != 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: c.pdata contains incorrect participant guid"); - } - } - -err_incorrect_data: - DDS_Security_ParticipantBuiltinTopicData_free(pdata); - DDS_Security_Deserializer_free(deserializer); -err_invalid_data: - return result; +failed: + DDS_Security_ParticipantBuiltinTopicData_free(pdata); + DDS_Security_Deserializer_free(deserializer); +failed_deser: + return DDS_SECURITY_VALIDATION_FAILED; } -static DDS_Security_ValidationResult_t -validate_handshake_request_token( - const DDS_Security_HandshakeMessageToken *token, - HandshakeInfo *handshake, - X509Seq *trusted_ca_list, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t validate_handshake_request_token(const DDS_Security_HandshakeMessageToken *token, HandshakeInfo *handshake, X509Seq *trusted_ca_list, DDS_Security_SecurityException *ex) { + IdentityRelation *relation = handshake->relation; + X509 *identityCert; + const DDS_Security_BinaryProperty_t *c_id, *c_perm, *c_pdata, *c_dsign_algo, *c_kagree_algo, *dh1, *challenge, *hash_c1; + EVP_PKEY *pdhkey = NULL; + AuthenticationAlgoKind_t dsignAlgoKind, kagreeAlgoKind; + + assert(relation); + + if (!token->class_id || strncmp(AUTH_HANDSHAKE_REQUEST_TOKEN_ID, token->class_id, strlen(AUTH_HANDSHAKE_REQUEST_TOKEN_ID)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken incorrect class_id: %s (expected %s)", token->class_id ? token->class_id : "NULL", AUTH_HANDSHAKE_REQUEST_TOKEN_ID); + goto err_inv_class_id; + } + + /* Check presents of mandatory properties: c.i, c.perm, c.pdata, c.dsign_algo, c.kagree_algo, dh1, challenge1 */ + c_id = DDS_Security_DataHolder_find_binary_property(token, "c.id"); + if (!c_id || c_id->value._length == 0 || c_id->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property c.id missing"); + goto err_no_c_id; + } + + if (load_X509_certificate_from_data((char *)c_id->value._buffer, (int)c_id->value._length, &identityCert, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_identity_cert_load; + + { DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - IdentityRelation *relation = handshake->relation; - X509 *identityCert; - const DDS_Security_BinaryProperty_t *c_id; - const DDS_Security_BinaryProperty_t *c_perm; - const DDS_Security_BinaryProperty_t *c_pdata; - const DDS_Security_BinaryProperty_t *c_dsign_algo; - const DDS_Security_BinaryProperty_t *c_kagree_algo; - const DDS_Security_BinaryProperty_t *dh1; - const DDS_Security_BinaryProperty_t *challenge; - const DDS_Security_BinaryProperty_t *hash_c1; - EVP_PKEY *pdhkey = NULL; - AuthenticationAlgoKind_t dsignAlgoKind; - AuthenticationAlgoKind_t kagreeAlgoKind; - unsigned i; - - assert(relation); - - /* Check class_id */ - if (!token->class_id || - (strncmp(AUTH_HANDSHAKE_REQUEST_TOKEN_ID, token->class_id, strlen(AUTH_HANDSHAKE_REQUEST_TOKEN_ID)) != 0)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken incorrect class_id: %s (expected %s)", token->class_id ? token->class_id: "NULL", AUTH_HANDSHAKE_REQUEST_TOKEN_ID); - goto err_inv_class_id; - } - - /* Check presents of mandatory properties - * - c.id - * - c.perm - * - c.pdata - * - c.dsign_algo - * - c.kagree_algo - * - dh1 - * - challenge1 - */ - c_id = DDS_Security_DataHolder_find_binary_property(token, "c.id"); - if (!c_id || (c_id->value._length == 0) || (c_id->value._buffer == NULL)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property c.id missing"); - goto err_no_c_id; - } - - result = load_X509_certificate_from_data((char*)c_id->value._buffer, (int)c_id->value._length, &identityCert, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_identity_cert_load; - } - - if( trusted_ca_list->length == 0 ){ //no trusted set. check with local CA - result = verify_certificate(identityCert, relation->localIdentity->identityCA, ex); - } - else{ - /* Make sure we have a clean exception, in case it was uninitialized. */ - DDS_Security_Exception_clean(ex); - for (i = 0; i < trusted_ca_list->length; ++i) { - /* We'll only return the exception of the last one, if it failed. */ - DDS_Security_Exception_reset(ex); - result = verify_certificate(identityCert, trusted_ca_list->buffer[i], ex); - if (result == DDS_SECURITY_VALIDATION_OK) { - break; - } - } - } - - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_identity_cert; - } - - result = check_certificate_expiry( identityCert, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_identity_cert; - } - - c_perm = DDS_Security_DataHolder_find_binary_property(token, "c.perm"); - if (!c_perm) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property c.perm missing"); - goto err_no_c_perm; - } - - if (c_perm->value._length > 0) { - ddsrt_free(relation->remoteIdentity->permissionsDocument); - relation->remoteIdentity->permissionsDocument = string_from_data(c_perm->value._buffer, c_perm->value._length); - } - - c_pdata = DDS_Security_DataHolder_find_binary_property(token, "c.pdata"); - if (!c_pdata) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property c.pdata missing"); - goto err_no_c_pdata; - } - - result = validate_pdata(&c_pdata->value, identityCert, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_pdata; - } - - c_dsign_algo = DDS_Security_DataHolder_find_binary_property(token, "c.dsign_algo"); - if (!c_dsign_algo) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property c.dsign_algo missing"); - goto err_no_c_dsign_algo; - } - - dsignAlgoKind = get_dsign_algo_from_string((const char *)c_dsign_algo->value._buffer); - if (dsignAlgoKind == AUTH_ALGO_KIND_UNKNOWN) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property c.dsign_algo not supported"); - goto err_no_c_dsign_algo; - } - - c_kagree_algo = DDS_Security_DataHolder_find_binary_property(token, "c.kagree_algo"); - if (!c_kagree_algo) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property c.kagree_algo missing"); - goto err_no_c_kagree_algo; - } - - kagreeAlgoKind = get_kagree_algo_from_string((const char *)c_kagree_algo->value._buffer); - if (kagreeAlgoKind == AUTH_ALGO_KIND_UNKNOWN) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property c.kagree_algo not support"); - goto err_no_c_kagree_algo; - } - - dh1 = DDS_Security_DataHolder_find_binary_property(token, "dh1"); - if (!dh1 || dh1->value._length == 0 || dh1->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property dh1 missing"); - goto err_no_dh; - } - - result = dh_oct_to_public_key(&pdhkey, kagreeAlgoKind, dh1->value._buffer, dh1->value._length, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_no_dh; - } - - challenge = DDS_Security_DataHolder_find_binary_property(token, "challenge1"); - if (!challenge) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property challenge1 missing"); - goto err_no_challenge; - } - - if (challenge->value._length != sizeof(AuthenticationChallenge) || challenge->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property challenge1 invalid"); - goto err_no_challenge; - } - - /* When validate_remote_identity was provided with a remote_auth_request_token - * then the future_challenge in the remote identity was set and the challenge1 - * property of the handshake_request_token should be the same as the - * future_challenge stored in the remote identity. - */ - if (relation->rchallenge) { - if (memcmp(relation->rchallenge->value, challenge->value._buffer, sizeof(AuthenticationChallenge)) != 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property challenge1 does not match future_challenge"); - goto err_no_challenge; - } - } else { - if (challenge->value._length == sizeof(relation->rchallenge->value)) { - relation->rchallenge = ddsrt_malloc(sizeof(AuthenticationChallenge)); - memcpy(relation->rchallenge, challenge->value._buffer, challenge->value._length); - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property challenge1 invalid (incorrect size)"); - goto err_no_challenge; - } - } - - /* Compute the hash_c1 value */ + if (trusted_ca_list->length == 0) + result = verify_certificate(identityCert, relation->localIdentity->identityCA, ex); + else { - const DDS_Security_BinaryProperty_t * binary_properties[5]; - - binary_properties[0] = c_id; - binary_properties[1] = c_perm; - binary_properties[2] = c_pdata; - binary_properties[3] = c_dsign_algo; - binary_properties[4] = c_kagree_algo; - - (void)compute_hash_value(&handshake->hash_c1[0], binary_properties, 5, NULL); + DDS_Security_Exception_clean(ex); + for (unsigned i = 0; i < trusted_ca_list->length; ++i) + { + DDS_Security_Exception_reset(ex); + if ((result = verify_certificate(identityCert, trusted_ca_list->buffer[i], ex)) == DDS_SECURITY_VALIDATION_OK) + break; + } } + if (result != DDS_SECURITY_VALIDATION_OK) + goto err_inv_identity_cert; + } - hash_c1 = DDS_Security_DataHolder_find_binary_property(token, "hash_c1"); - if (hash_c1) { - if ((hash_c1->value._length == sizeof(HashValue_t)) && - (memcmp(hash_c1->value._buffer, &handshake->hash_c1, sizeof(HashValue_t)) == 0)) { - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property hash_c1 invalid (incorrect size)"); - goto err_inv_hash_c1; - } + if (check_certificate_expiry(identityCert, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_identity_cert; + + if (!(c_perm = DDS_Security_DataHolder_find_binary_property(token, "c.perm"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property c.perm missing"); + goto err_no_c_perm; + } + if (c_perm->value._length > 0) + { + ddsrt_free(relation->remoteIdentity->permissionsDocument); + relation->remoteIdentity->permissionsDocument = string_from_data(c_perm->value._buffer, c_perm->value._length); + } + + if (!(c_pdata = DDS_Security_DataHolder_find_binary_property(token, "c.pdata"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property c.pdata missing"); + goto err_no_c_pdata; + } + if (validate_pdata(&c_pdata->value, identityCert, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_pdata; + + if (!(c_dsign_algo = DDS_Security_DataHolder_find_binary_property(token, "c.dsign_algo"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property c.dsign_algo missing"); + goto err_no_c_dsign_algo; + } + + if ((dsignAlgoKind = get_dsign_algo_from_string((const char *)c_dsign_algo->value._buffer)) == AUTH_ALGO_KIND_UNKNOWN) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property c.dsign_algo not supported"); + goto err_no_c_dsign_algo; + } + + if (!(c_kagree_algo = DDS_Security_DataHolder_find_binary_property(token, "c.kagree_algo"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property c.kagree_algo missing"); + goto err_no_c_kagree_algo; + } + + if ((kagreeAlgoKind = get_kagree_algo_from_string((const char *)c_kagree_algo->value._buffer)) == AUTH_ALGO_KIND_UNKNOWN) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property c.kagree_algo not support"); + goto err_no_c_kagree_algo; + } + + dh1 = DDS_Security_DataHolder_find_binary_property(token, "dh1"); + if (!dh1 || dh1->value._length == 0 || dh1->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property dh1 missing"); + goto err_no_dh; + } + if (dh_oct_to_public_key(&pdhkey, kagreeAlgoKind, dh1->value._buffer, dh1->value._length, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_no_dh; + + if (!(challenge = DDS_Security_DataHolder_find_binary_property(token, "challenge1"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property challenge1 missing"); + goto err_no_challenge; + } + if (challenge->value._length != sizeof(AuthenticationChallenge) || challenge->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property challenge1 invalid"); + goto err_no_challenge; + } + + /* When validate_remote_identity was provided with a remote_auth_request_token then the future_challenge in the remote identity was set and the challenge1 + property of the handshake_request_token should be the same as the future_challenge stored in the remote identity. */ + if (relation->rchallenge) + { + if (memcmp(relation->rchallenge->value, challenge->value._buffer, sizeof(AuthenticationChallenge)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property challenge1 does not match future_challenge"); + goto err_no_challenge; } - - if (!relation->remoteIdentity->identityCert) { - relation->remoteIdentity->identityCert = identityCert; - } else { - X509_free(relation->remoteIdentity->identityCert); - relation->remoteIdentity->identityCert = identityCert; + } + else + { + if (challenge->value._length == sizeof(relation->rchallenge->value)) + { + relation->rchallenge = ddsrt_malloc(sizeof(AuthenticationChallenge)); + memcpy(relation->rchallenge, challenge->value._buffer, challenge->value._length); } + else + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property challenge1 invalid (incorrect size)"); + goto err_no_challenge; + } + } - relation->remoteIdentity->dsignAlgoKind = dsignAlgoKind; - relation->remoteIdentity->kagreeAlgoKind = kagreeAlgoKind; + { + const DDS_Security_BinaryProperty_t *binary_properties[] = { c_id, c_perm, c_pdata, c_dsign_algo, c_kagree_algo }; + (void)compute_hash_value(&handshake->hash_c1[0], binary_properties, 5, NULL); + } + if ((hash_c1 = DDS_Security_DataHolder_find_binary_property(token, "hash_c1"))) + { + if (hash_c1->value._length != sizeof(HashValue_t) || memcmp(hash_c1->value._buffer, &handshake->hash_c1, sizeof(HashValue_t)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property hash_c1 invalid (incorrect size)"); + goto err_inv_hash_c1; + } + } - DDS_Security_OctetSeq_copy(&relation->remoteIdentity->pdata, &c_pdata->value); - - handshake->rdh = pdhkey; - - return result; + if (relation->remoteIdentity->identityCert) + X509_free(relation->remoteIdentity->identityCert); + relation->remoteIdentity->identityCert = identityCert; + relation->remoteIdentity->dsignAlgoKind = dsignAlgoKind; + relation->remoteIdentity->kagreeAlgoKind = kagreeAlgoKind; + DDS_Security_OctetSeq_copy(&relation->remoteIdentity->pdata, &c_pdata->value); + handshake->rdh = pdhkey; + return DDS_SECURITY_VALIDATION_OK; err_inv_hash_c1: err_no_challenge: - EVP_PKEY_free(pdhkey); + EVP_PKEY_free(pdhkey); err_no_dh: err_no_c_kagree_algo: err_no_c_dsign_algo: @@ -1937,349 +1452,243 @@ err_inv_pdata: err_no_c_pdata: err_no_c_perm: err_inv_identity_cert: - X509_free(identityCert); + X509_free(identityCert); err_identity_cert_load: err_no_c_id: err_inv_class_id: - return result; + return DDS_SECURITY_VALIDATION_FAILED; } - -static DDS_Security_ValidationResult_t -validate_handshake_reply_token( - const DDS_Security_HandshakeMessageToken *token, - HandshakeInfo *handshake, - EVP_PKEY **pdhkey, - X509Seq *trusted_ca_list, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t validate_handshake_reply_token(const DDS_Security_HandshakeMessageToken *token, HandshakeInfo *handshake, EVP_PKEY **pdhkey, X509Seq *trusted_ca_list, DDS_Security_SecurityException *ex) { + IdentityRelation *relation = handshake->relation; + X509 *identityCert; + EVP_PKEY *public_key; + const DDS_Security_BinaryProperty_t *c_id, *c_perm, *c_pdata, *c_dsign_algo, *c_kagree_algo, *dh1, *dh2, *hash_c1, *hash_c2, *challenge1, *challenge2, *signature; + AuthenticationAlgoKind_t dsignAlgoKind, kagreeAlgoKind; + + assert(relation); + + if (!token->class_id || strncmp(AUTH_HANDSHAKE_REPLY_TOKEN_ID, token->class_id, strlen(AUTH_HANDSHAKE_REPLY_TOKEN_ID)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken incorrect class_id: %s (expected %s)", token->class_id ? token->class_id : "NULL", AUTH_HANDSHAKE_REPLY_TOKEN_ID); + goto err_inv_class_id; + } + + /* Check presents of mandatory properties: c.id, c.perm, c.pdata, c.dsign_algo, c.kagree_algo, challenge1, dh2, challenge2, signature */ + c_id = DDS_Security_DataHolder_find_binary_property(token, "c.id"); + if (!c_id || (c_id->value._length == 0) || (c_id->value._buffer == NULL)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property c.id missing"); + goto err_no_c_id; + } + + /* Verify Identity Certificate */ + if (load_X509_certificate_from_data((char *)c_id->value._buffer, (int)c_id->value._length, &identityCert, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_identity_cert_load; + + { DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - IdentityRelation *relation = handshake->relation; - X509 *identityCert; - EVP_PKEY *public_key; - const DDS_Security_BinaryProperty_t *c_id; - const DDS_Security_BinaryProperty_t *c_perm; - const DDS_Security_BinaryProperty_t *c_pdata; - const DDS_Security_BinaryProperty_t *c_dsign_algo; - const DDS_Security_BinaryProperty_t *c_kagree_algo; - const DDS_Security_BinaryProperty_t *dh1; - const DDS_Security_BinaryProperty_t *dh2; - const DDS_Security_BinaryProperty_t *hash_c1; - const DDS_Security_BinaryProperty_t *hash_c2; - const DDS_Security_BinaryProperty_t *challenge1; - const DDS_Security_BinaryProperty_t *challenge2; - const DDS_Security_BinaryProperty_t *signature; - AuthenticationAlgoKind_t dsignAlgoKind; - AuthenticationAlgoKind_t kagreeAlgoKind; - - unsigned i; - - assert(relation); - - /* Check class_id */ - if (!token->class_id || - (strncmp(AUTH_HANDSHAKE_REPLY_TOKEN_ID, token->class_id, strlen(AUTH_HANDSHAKE_REPLY_TOKEN_ID)) != 0)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken incorrect class_id: %s (expected %s)", token->class_id ? token->class_id: "NULL", AUTH_HANDSHAKE_REPLY_TOKEN_ID); - goto err_inv_class_id; - } - - /* Check presents of mandatory properties - * - c.id - * - c.perm - * - c.pdata - * - c.dsign_algo - * - c.kagree_algo - * - challenge1 - * - dh2 - * - challenge2 - * - signature - */ - c_id = DDS_Security_DataHolder_find_binary_property(token, "c.id"); - if (!c_id || (c_id->value._length == 0) || (c_id->value._buffer == NULL)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property c.id missing"); - goto err_no_c_id; - } - - /* Verify Identity Certificate */ - result = load_X509_certificate_from_data((char*)c_id->value._buffer, (int)c_id->value._length, &identityCert, ex); - if (result != DDS_SECURITY_VALIDATION_OK ) { - goto err_identity_cert_load; - } - - if( trusted_ca_list->length == 0 ){ //no trusted set. check with local CA - result = verify_certificate(identityCert, relation->localIdentity->identityCA, ex); - } - else{ - /* Make sure we have a clean exception, in case it was uninitialized. */ - DDS_Security_Exception_clean(ex); - for (i = 0; i < trusted_ca_list->length; ++i) { - /* We'll only return the exception of the last one, if it failed. */ - DDS_Security_Exception_reset(ex); - result = verify_certificate(identityCert, trusted_ca_list->buffer[i], ex); - if (result == DDS_SECURITY_VALIDATION_OK) { - break; - } - } - } - - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_identity_cert; - } - - result = check_certificate_expiry( identityCert, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_identity_cert; - } - - c_perm = DDS_Security_DataHolder_find_binary_property(token, "c.perm"); - if (!c_perm) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property c.perm missing"); - goto err_no_c_perm; - } - - if (c_perm->value._length > 0) { - ddsrt_free(relation->remoteIdentity->permissionsDocument); - relation->remoteIdentity->permissionsDocument = string_from_data(c_perm->value._buffer, c_perm->value._length); - } - - c_pdata = DDS_Security_DataHolder_find_binary_property(token, "c.pdata"); - if (!c_pdata) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property c.pdata missing"); - goto err_no_c_pdata; - } - - result = validate_pdata(&c_pdata->value, identityCert, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_pdata; - } - - c_dsign_algo = DDS_Security_DataHolder_find_binary_property(token, "c.dsign_algo"); - if (!c_dsign_algo) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property c.dsign_algo missing"); - goto err_no_c_dsign_algo; - } - - dsignAlgoKind = get_dsign_algo_from_string((const char *)c_dsign_algo->value._buffer); - if (dsignAlgoKind == AUTH_ALGO_KIND_UNKNOWN) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property c.dsign_algo not supported"); - goto err_no_c_dsign_algo; - } - - c_kagree_algo = DDS_Security_DataHolder_find_binary_property(token, "c.kagree_algo"); - if (!c_kagree_algo) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property c.kagree_algo missing"); - goto err_no_c_kagree_algo; - } - - kagreeAlgoKind = get_kagree_algo_from_string((const char *)c_kagree_algo->value._buffer); - if (kagreeAlgoKind == AUTH_ALGO_KIND_UNKNOWN) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property c.kagree_algo not support"); - goto err_no_c_kagree_algo; - } - - /* dh1 is optional */ - dh1 = DDS_Security_DataHolder_find_binary_property(token, "dh1"); - DDSRT_UNUSED_ARG(dh1); /*print it for integration purposes */ - - dh2 = DDS_Security_DataHolder_find_binary_property(token, "dh2"); - if (!dh2 || dh2->value._length == 0 || dh2->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property dh2 missing"); - goto err_no_dh; - } - - hash_c1 = DDS_Security_DataHolder_find_binary_property(token, "hash_c1"); - if (hash_c1) { - if ((hash_c1->value._length == sizeof(HashValue_t)) && - (memcmp(hash_c1->value._buffer, handshake->hash_c1, sizeof(HashValue_t)) == 0)) { - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property hash_c1 invalid"); - goto err_inv_hash_c1; - } - } - - /* Compute the hash_c2 value */ + if (trusted_ca_list->length == 0) + result = verify_certificate(identityCert, relation->localIdentity->identityCA, ex); + else { - const DDS_Security_BinaryProperty_t * binary_properties[5]; - - binary_properties[0] = c_id; - binary_properties[1] = c_perm; - binary_properties[2] = c_pdata; - binary_properties[3] = c_dsign_algo; - binary_properties[4] = c_kagree_algo; - - (void)compute_hash_value(&handshake->hash_c2[0], binary_properties, 5, NULL); + DDS_Security_Exception_clean(ex); + for (unsigned i = 0; i < trusted_ca_list->length; ++i) + { + DDS_Security_Exception_reset(ex); + result = verify_certificate(identityCert, trusted_ca_list->buffer[i], ex); + if (result == DDS_SECURITY_VALIDATION_OK) + break; + } } + if (result != DDS_SECURITY_VALIDATION_OK) + goto err_inv_identity_cert; + } - hash_c2 = DDS_Security_DataHolder_find_binary_property(token, "hash_c2"); - if (hash_c2) { - if ((hash_c2->value._length == sizeof(HashValue_t)) && - (memcmp(hash_c2->value._buffer, handshake->hash_c2, sizeof(HashValue_t)) == 0)) { - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property hash_c2 invalid"); - goto err_inv_hash_c2; - } + if (check_certificate_expiry(identityCert, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_identity_cert; + + if (!(c_perm = DDS_Security_DataHolder_find_binary_property(token, "c.perm"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property c.perm missing"); + goto err_no_c_perm; + } + if (c_perm->value._length > 0) + { + ddsrt_free(relation->remoteIdentity->permissionsDocument); + relation->remoteIdentity->permissionsDocument = string_from_data(c_perm->value._buffer, c_perm->value._length); + } + + if (!(c_pdata = DDS_Security_DataHolder_find_binary_property(token, "c.pdata"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property c.pdata missing"); + goto err_no_c_pdata; + } + if (validate_pdata(&c_pdata->value, identityCert, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_pdata; + + if (!(c_dsign_algo = DDS_Security_DataHolder_find_binary_property(token, "c.dsign_algo"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property c.dsign_algo missing"); + goto err_no_c_dsign_algo; + } + + if ((dsignAlgoKind = get_dsign_algo_from_string((const char *)c_dsign_algo->value._buffer)) == AUTH_ALGO_KIND_UNKNOWN) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property c.dsign_algo not supported"); + goto err_no_c_dsign_algo; + } + + if (!(c_kagree_algo = DDS_Security_DataHolder_find_binary_property(token, "c.kagree_algo"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property c.kagree_algo missing"); + goto err_no_c_kagree_algo; + } + + if ((kagreeAlgoKind = get_kagree_algo_from_string((const char *)c_kagree_algo->value._buffer)) == AUTH_ALGO_KIND_UNKNOWN) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property c.kagree_algo not support"); + goto err_no_c_kagree_algo; + } + + /* dh1 is optional */ + dh1 = DDS_Security_DataHolder_find_binary_property(token, "dh1"); + DDSRT_UNUSED_ARG(dh1); + + dh2 = DDS_Security_DataHolder_find_binary_property(token, "dh2"); + if (!dh2 || dh2->value._length == 0 || dh2->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property dh2 missing"); + goto err_no_dh; + } + + if ((hash_c1 = DDS_Security_DataHolder_find_binary_property(token, "hash_c1"))) + { + if (hash_c1->value._length != sizeof(HashValue_t) || memcmp(hash_c1->value._buffer, handshake->hash_c1, sizeof(HashValue_t)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property hash_c1 invalid"); + goto err_inv_hash_c1; } + } - signature = DDS_Security_DataHolder_find_binary_property(token, "signature"); - if (!signature || signature->value._length == 0 || signature->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property signature missing"); - goto err_no_signature; + { + const DDS_Security_BinaryProperty_t *binary_properties[] = { c_id, c_perm, c_pdata, c_dsign_algo, c_kagree_algo }; + (void)compute_hash_value(&handshake->hash_c2[0], binary_properties, 5, NULL); + } + + if ((hash_c2 = DDS_Security_DataHolder_find_binary_property(token, "hash_c2"))) + { + if (hash_c2->value._length != sizeof(HashValue_t) || memcmp(hash_c2->value._buffer, handshake->hash_c2, sizeof(HashValue_t)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property hash_c2 invalid"); + goto err_inv_hash_c2; } + } - *pdhkey = NULL; - result = dh_oct_to_public_key(pdhkey, kagreeAlgoKind, dh2->value._buffer, dh2->value._length, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_dh; + signature = DDS_Security_DataHolder_find_binary_property(token, "signature"); + if (!signature || signature->value._length == 0 || signature->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property signature missing"); + goto err_no_signature; + } + + *pdhkey = NULL; + if (dh_oct_to_public_key(pdhkey, kagreeAlgoKind, dh2->value._buffer, dh2->value._length, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_dh; + + if (!(challenge1 = DDS_Security_DataHolder_find_binary_property(token, "challenge1"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge1 missing"); + goto err_no_challenge; + } + if (challenge1->value._length != sizeof(AuthenticationChallenge) || challenge1->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge1 invalid"); + goto err_no_challenge; + } + + if (!(challenge2 = DDS_Security_DataHolder_find_binary_property(token, "challenge2"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge2 missing"); + goto err_no_challenge; + } + if (challenge2->value._length != sizeof(AuthenticationChallenge) || challenge2->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge2 invalid"); + goto err_no_challenge; + } + + /* When validate_remote_identity was provided with a remote_auth_request_token then the future_challenge in the remote identity was set and the challenge2 + property of the handshake_reply_token should be the same as the future_challenge stored in the remote identity. */ + if (relation->rchallenge) + { + if (memcmp(relation->rchallenge->value, challenge2->value._buffer, sizeof(AuthenticationChallenge)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge2 does not match future_challenge"); + goto err_no_challenge; } - - challenge1 = DDS_Security_DataHolder_find_binary_property(token, "challenge1"); - if (!challenge1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge1 missing"); - goto err_no_challenge; + } + else + { + if (challenge2->value._length == sizeof(relation->rchallenge->value)) + { + relation->rchallenge = ddsrt_malloc(sizeof(AuthenticationChallenge)); + memcpy(relation->rchallenge, challenge2->value._buffer, challenge2->value._length); } - - if (challenge1->value._length != sizeof(AuthenticationChallenge) || challenge1->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge1 invalid"); - goto err_no_challenge; + else + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge2 invalid (incorrect size)"); + goto err_no_challenge; } + } - - challenge2 = DDS_Security_DataHolder_find_binary_property(token, "challenge2"); - if (!challenge2) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge2 missing"); - goto err_no_challenge; + if (relation->lchallenge) + { + if (memcmp(relation->lchallenge->value, challenge1->value._buffer, sizeof(AuthenticationChallenge)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge1 does not match future_challenge"); + goto err_no_challenge; } + } + else + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: No future challenge exists for this token"); + goto err_no_challenge; + } - if (challenge2->value._length != sizeof(AuthenticationChallenge) || challenge2->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge2 invalid"); - goto err_no_challenge; - } - /* When validate_remote_identity was provided with a remote_auth_request_token - * then the future_challenge in the remote identity was set and the challenge2 - * property of the handshake_reply_token should be the same as the - * future_challenge stored in the remote identity. - */ + /* TODO: check if an identity certificate was already associated with the remote identity and when that is the case both should be the same */ + if (relation->remoteIdentity->identityCert) + X509_free(relation->remoteIdentity->identityCert); + relation->remoteIdentity->identityCert = identityCert; + relation->remoteIdentity->dsignAlgoKind = dsignAlgoKind; + relation->remoteIdentity->kagreeAlgoKind = kagreeAlgoKind; + if ((public_key = X509_get_pubkey(relation->remoteIdentity->identityCert))) + { + DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); + DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); + const DDS_Security_BinaryProperty_t *properties[HANDSHAKE_SIGNATURE_CONTENT_SIZE] = { hash_c2_val, challenge2, dh2, challenge1, dh1, hash_c1_val }; + DDS_Security_ValidationResult_t result = validate_signature(public_key, properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE, signature->value._buffer, signature->value._length, ex); + EVP_PKEY_free(public_key); + DDS_Security_BinaryProperty_free(hash_c1_val); + DDS_Security_BinaryProperty_free(hash_c2_val); + if (result != DDS_SECURITY_VALIDATION_OK) + goto err_inv_signature; + } + else + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_get_pubkey failed"); + goto err_inv_signature; + } - - if (relation->rchallenge) { - if (memcmp(relation->rchallenge->value, challenge2->value._buffer, sizeof(AuthenticationChallenge)) != 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge2 does not match future_challenge"); - goto err_no_challenge; - } - } else { - if (challenge2->value._length == sizeof(relation->rchallenge->value)) { - relation->rchallenge = ddsrt_malloc(sizeof(AuthenticationChallenge)); - memcpy(relation->rchallenge, challenge2->value._buffer, challenge2->value._length); - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge2 invalid (incorrect size)"); - goto err_no_challenge; - } - } - - - if (relation->lchallenge) { - if (memcmp(relation->lchallenge->value, challenge1->value._buffer, sizeof(AuthenticationChallenge)) != 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge1 does not match future_challenge"); - goto err_no_challenge; - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: No future challenge exists for this token"); - goto err_no_challenge; - } - - - /* TODO: check if an identity certificate was already associated with the remote identity and - * when that is the case both should be the same - */ - if (!relation->remoteIdentity->identityCert) { - relation->remoteIdentity->identityCert = identityCert; - } else { - X509_free(relation->remoteIdentity->identityCert); - relation->remoteIdentity->identityCert = identityCert; - } - - relation->remoteIdentity->dsignAlgoKind = dsignAlgoKind; - relation->remoteIdentity->kagreeAlgoKind = kagreeAlgoKind; - - - public_key = X509_get_pubkey(relation->remoteIdentity->identityCert); - if (public_key) { - /*prepare properties*/ - const DDS_Security_BinaryProperty_t *properties[HANDSHAKE_SIGNATURE_CONTENT_SIZE]; - DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); - DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); - - properties[0] = hash_c2_val; - properties[1] = challenge2; - properties[2] = dh2; - properties[3] = challenge1; - properties[4] = dh1; - properties[5] = hash_c1_val; - - result = validate_signature(public_key,properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE, signature->value._buffer,signature->value._length, ex); - - EVP_PKEY_free(public_key); - DDS_Security_BinaryProperty_free(hash_c1_val); - DDS_Security_BinaryProperty_free(hash_c2_val); - - if( result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_signature; - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "X509_get_pubkey failed"); - goto err_inv_identity_cert; - } - - - DDS_Security_OctetSeq_copy(&relation->remoteIdentity->pdata, &c_pdata->value); - - return result; + DDS_Security_OctetSeq_copy(&relation->remoteIdentity->pdata, &c_pdata->value); + return DDS_SECURITY_VALIDATION_OK; err_inv_signature: err_no_challenge: err_inv_dh: + EVP_PKEY_free(*pdhkey); err_no_signature: err_inv_hash_c2: err_inv_hash_c1: @@ -2290,1203 +1699,847 @@ err_inv_pdata: err_no_c_pdata: err_no_c_perm: err_inv_identity_cert: - X509_free(identityCert); + X509_free(identityCert); err_identity_cert_load: err_no_c_id: err_inv_class_id: - return result; + return DDS_SECURITY_VALIDATION_FAILED; } - -static DDS_Security_ValidationResult_t -validate_handshake_final_token( - const DDS_Security_HandshakeMessageToken *token, - HandshakeInfo *handshake, - DDS_Security_SecurityException *ex) +static DDS_Security_ValidationResult_t validate_handshake_final_token(const DDS_Security_HandshakeMessageToken *token, HandshakeInfo *handshake, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - IdentityRelation *relation = handshake->relation; - const DDS_Security_BinaryProperty_t *dh1; - const DDS_Security_BinaryProperty_t *dh2; - const DDS_Security_BinaryProperty_t *hash_c1; - const DDS_Security_BinaryProperty_t *hash_c2; - const DDS_Security_BinaryProperty_t *challenge1; - const DDS_Security_BinaryProperty_t *challenge2; - const DDS_Security_BinaryProperty_t *signature; - EVP_PKEY *public_key; + IdentityRelation *relation = handshake->relation; + const DDS_Security_BinaryProperty_t *dh1, *dh2, *hash_c1, *hash_c2, *challenge1, *challenge2, *signature; + EVP_PKEY *public_key; + assert(relation); + + if (!token->class_id || strncmp(AUTH_HANDSHAKE_FINAL_TOKEN_ID, token->class_id, strlen(AUTH_HANDSHAKE_FINAL_TOKEN_ID)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken incorrect class_id: %s (expected %s)", token->class_id ? token->class_id : "NULL", AUTH_HANDSHAKE_FINAL_TOKEN_ID); + goto failed; + } + + /* Check presents of mandatory properties: challenge1, challenge2, signature */ + + /* dh1 and dh2 are optional */ + dh1 = DDS_Security_DataHolder_find_binary_property(token, "dh1"); + DDSRT_UNUSED_ARG(dh1); + dh2 = DDS_Security_DataHolder_find_binary_property(token, "dh2"); + DDSRT_UNUSED_ARG(dh2); + + /* hash_c1 is optional */ + if ((hash_c1 = DDS_Security_DataHolder_find_binary_property(token, "hash_c1"))) + { + if (hash_c1->value._length != sizeof(HashValue_t) || memcmp(hash_c1->value._buffer, handshake->hash_c1, sizeof(HashValue_t)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property hash_c1 invalid"); + goto failed; + } + } + + /* hash_c2 is optional */ + if ((hash_c2 = DDS_Security_DataHolder_find_binary_property(token, "hash_c2"))) + { + if (hash_c2->value._length != sizeof(HashValue_t) || memcmp(hash_c2->value._buffer, handshake->hash_c2, sizeof(HashValue_t)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: HandshakeMessageToken property hash_c2 invalid"); + goto failed; + } + } + + if (!(challenge1 = DDS_Security_DataHolder_find_binary_property(token, "challenge1"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge1 missing"); + goto failed; + } + if (challenge1->value._length != sizeof(AuthenticationChallenge) || challenge1->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge1 invalid"); + goto failed; + } + + if (!(challenge2 = DDS_Security_DataHolder_find_binary_property(token, "challenge2"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge2 missing"); + goto failed; + } + if (challenge2->value._length != sizeof(AuthenticationChallenge) || challenge2->value._buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge2 invalid"); + goto failed; + } + + /* When validate_remote_identity was provided with a remote_auth_request_token then the future_challenge in the remote identity was set and the challenge1 + property of the handshake_reply_token should be the same as the future_challenge stored in the remote identity. */ + if (relation->rchallenge) + { + if (memcmp(relation->rchallenge->value, challenge1->value._buffer, sizeof(AuthenticationChallenge)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge1 does not match future_challenge"); + goto failed; + } + } + else + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: No challenge exists to check challenge1 in the token."); + goto failed; + } + + if (relation->lchallenge) + { + if (memcmp(relation->lchallenge->value, challenge2->value._buffer, sizeof(AuthenticationChallenge)) != 0) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property challenge2 does not match future_challenge"); + goto failed; + } + } + else + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: No challenge exists to check challenge2 in the token."); + goto failed; + } + + if (!(signature = DDS_Security_DataHolder_find_binary_property(token, "signature"))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: HandshakeMessageToken property signature missing"); + goto failed; + } + + /* Validate signature */ + if ((public_key = X509_get_pubkey(relation->remoteIdentity->identityCert))) + { + DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); + DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); + const DDS_Security_BinaryProperty_t *properties[HANDSHAKE_SIGNATURE_CONTENT_SIZE] = { hash_c1_val, challenge1, dh1, challenge2, dh2, hash_c2_val }; + DDS_Security_ValidationResult_t result = validate_signature(public_key, properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE, signature->value._buffer, signature->value._length, ex); + EVP_PKEY_free(public_key); + DDS_Security_BinaryProperty_free(hash_c1_val); + DDS_Security_BinaryProperty_free(hash_c2_val); + if (result != DDS_SECURITY_VALIDATION_OK) + goto failed; + } + else + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "X509_get_pubkey failed"); + goto failed; + } + return DDS_SECURITY_VALIDATION_OK; + +failed: + return DDS_SECURITY_VALIDATION_FAILED; +} + +DDS_Security_ValidationResult_t begin_handshake_reply(dds_security_authentication *instance, DDS_Security_HandshakeHandle *handshake_handle, + DDS_Security_HandshakeMessageToken *handshake_message_out, const DDS_Security_HandshakeMessageToken *handshake_message_in, + const DDS_Security_IdentityHandle initiator_identity_handle, const DDS_Security_IdentityHandle replier_identity_handle, + const DDS_Security_OctetSeq *serialized_local_participant_data, DDS_Security_SecurityException *ex) +{ + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + HandshakeInfo *handshake = NULL; + IdentityRelation *relation = NULL; + SecurityObject *obj; + LocalIdentityInfo *localIdent; + RemoteIdentityInfo *remoteIdent; + EVP_PKEY *dhkeyLocal = NULL; + DDS_Security_BinaryProperty_t *tokens, *c_id, *c_perm, *c_pdata, *c_dsign_algo, *c_kagree_algo, *hash_c1, *hash_c2, *dh1, *dh2, *challenge1, *challenge2, *signature; + const DDS_Security_BinaryProperty_t *hash_c1_ref, *dh1_ref; + unsigned char *certData, *dhPubKeyData; + uint32_t certDataSize, dhPubKeyDataSize, tokenSize; + int created = 0; + + if (!instance || !handshake_handle || !handshake_message_out || !handshake_message_in || !serialized_local_participant_data) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: Invalid parameter provided"); + goto err_bad_param; + } + + if (serialized_local_participant_data->_length == 0 || serialized_local_participant_data->_buffer == NULL) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: Invalid parameter provided"); + goto err_bad_param; + } + + ddsrt_mutex_lock(&impl->lock); + + obj = security_object_find(impl->objectHash, replier_identity_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: Invalid replier_identity_handle provided"); + goto err_inv_handle; + } + localIdent = (LocalIdentityInfo *)obj; + + obj = security_object_find(impl->objectHash, initiator_identity_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_REMOTE_IDENTITY)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "begin_handshake_reply: Invalid initiator_identity_handle provided"); + goto err_inv_handle; + } + remoteIdent = (RemoteIdentityInfo *)obj; + if (!(handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(localIdent), SECURITY_OBJECT_HANDLE(remoteIdent)))) + { + relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)); assert(relation); + handshake = handshake_info_new(localIdent, remoteIdent, relation); + handshake->created_in = CREATEDREPLY; + (void)ddsrt_hh_add(impl->objectHash, handshake); + created = 1; + } + else + { + relation = handshake->relation; + assert(relation); + } - /* Check class_id */ - if (!token->class_id || - (strncmp(AUTH_HANDSHAKE_FINAL_TOKEN_ID, token->class_id, strlen(AUTH_HANDSHAKE_FINAL_TOKEN_ID)) != 0)) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken incorrect class_id: %s (expected %s)", token->class_id ? token->class_id: "NULL", AUTH_HANDSHAKE_FINAL_TOKEN_ID); - goto err_inv_class_id; - } + if (validate_handshake_request_token(handshake_message_in, handshake, &(impl->trustedCAList), ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_token; + if (get_certificate_contents(localIdent->identityCert, &certData, &certDataSize, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_alloc_cid; - /* Check presents of mandatory properties - * - challenge1 - * - challenge2 - * - signature - */ + if (!handshake->ldh) + { + if (generate_dh_keys(&dhkeyLocal, remoteIdent->kagreeAlgoKind, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_gen_dh_keys; + handshake->ldh = dhkeyLocal; + EVP_PKEY_copy_parameters(handshake->rdh, handshake->ldh); + } - /* dh1 is optional */ - dh1 = DDS_Security_DataHolder_find_binary_property(token, "dh1"); + if (dh_public_key_to_oct(handshake->ldh, remoteIdent->kagreeAlgoKind, &dhPubKeyData, &dhPubKeyDataSize, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_get_public_key; - DDSRT_UNUSED_ARG(dh1); /*print it for integration purposes */ + if (localIdent->pdata._length == 0) + DDS_Security_OctetSeq_copy(&localIdent->pdata, serialized_local_participant_data); - /* dh2 is optional */ - dh2 = DDS_Security_DataHolder_find_binary_property(token, "dh2"); - DDSRT_UNUSED_ARG(dh2); /*print it for integration purposes */ + hash_c1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "hash_c1"); + tokenSize = hash_c1_ref ? 12 : 11; - /* hash_c1 is optional */ - hash_c1 = DDS_Security_DataHolder_find_binary_property(token, "hash_c1"); - if (hash_c1) { - if ((hash_c1->value._length == sizeof(HashValue_t)) && - (memcmp(hash_c1->value._buffer, handshake->hash_c1, sizeof(HashValue_t)) == 0)) { - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property hash_c1 invalid"); - goto err_inv_hash_c1; - } - } + tokens = DDS_Security_BinaryPropertySeq_allocbuf(tokenSize); + c_id = &tokens[0]; + c_perm = &tokens[1]; + c_pdata = &tokens[2]; + c_dsign_algo = &tokens[3]; + c_kagree_algo = &tokens[4]; + signature = &tokens[5]; + hash_c2 = &tokens[6]; + challenge2 = &tokens[7]; + dh2 = &tokens[8]; + challenge1 = &tokens[9]; + dh1 = &tokens[10]; + hash_c1 = hash_c1_ref ? &tokens[11] : NULL; - /* hash_c2 is optional */ - hash_c2 = DDS_Security_DataHolder_find_binary_property(token, "hash_c2"); - if (hash_c2) { - if ((hash_c2->value._length == sizeof(HashValue_t)) && - (memcmp(hash_c2->value._buffer, handshake->hash_c2, sizeof(HashValue_t)) == 0)) { - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "begin_handshake_reply: HandshakeMessageToken property hash_c2 invalid"); - goto err_inv_hash_c2; - } - } + /* Store the Identity Certificate associated with the local identify in c.id property */ + DDS_Security_BinaryProperty_set_by_ref(c_id, "c.id", certData, certDataSize); + certData = NULL; + DDS_Security_BinaryProperty_set_by_string(c_perm, "c.perm", localIdent->permissionsDocument ? localIdent->permissionsDocument : ""); + DDS_Security_BinaryProperty_set_by_value(c_pdata, "c.pdata", serialized_local_participant_data->_buffer, serialized_local_participant_data->_length); + DDS_Security_BinaryProperty_set_by_string(c_dsign_algo, "c.dsign_algo", get_dsign_algo(localIdent->dsignAlgoKind)); + DDS_Security_BinaryProperty_set_by_string(c_kagree_algo, "c.kagree_algo", get_kagree_algo(remoteIdent->kagreeAlgoKind)); - challenge1 = DDS_Security_DataHolder_find_binary_property(token, "challenge1"); - if (!challenge1) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge1 missing"); - goto err_no_challenge; - } + /* Calculate the hash_c2 */ + { + DDS_Security_BinaryPropertySeq bseq = { ._length = 5, ._buffer = tokens }; + get_hash_binary_property_seq(&bseq, handshake->hash_c2); + DDS_Security_BinaryProperty_set_by_value(hash_c2, "hash_c2", handshake->hash_c2, sizeof(HashValue_t)); + } - if (challenge1->value._length != sizeof(AuthenticationChallenge) || challenge1->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge1 invalid"); - goto err_no_challenge; - } + /* Set the DH public key associated with the local participant in dh2 property */ + DDS_Security_BinaryProperty_set_by_ref(dh2, "dh2", dhPubKeyData, dhPubKeyDataSize); + /* Set the DH public key associated with the local participant in hash_c1 property */ + if (hash_c1) + DDS_Security_BinaryProperty_set_by_value(hash_c1, "hash_c1", hash_c1_ref->value._buffer, hash_c1_ref->value._length); - challenge2 = DDS_Security_DataHolder_find_binary_property(token, "challenge2"); - if (!challenge2) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge2 missing"); - goto err_no_challenge; - } + /* Set the DH public key associated with the local participant in dh1 property */ + if (dh1) + { + dh1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "dh1"); + if (dh1_ref) + DDS_Security_BinaryProperty_set_by_value(dh1, "dh1", dh1_ref->value._buffer, dh1_ref->value._length); + } - if (challenge2->value._length != sizeof(AuthenticationChallenge) || challenge2->value._buffer == NULL) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge2 invalid"); - goto err_no_challenge; - } + assert(relation->rchallenge); + DDS_Security_BinaryProperty_set_by_value(challenge1, "challenge1", relation->rchallenge->value, sizeof(AuthenticationChallenge)); + assert(relation->lchallenge); + DDS_Security_BinaryProperty_set_by_value(challenge2, "challenge2", relation->lchallenge->value, sizeof(AuthenticationChallenge)); - /* When validate_remote_identity was provided with a remote_auth_request_token - * then the future_challenge in the remote identity was set and the challenge1 - * property of the handshake_reply_token should be the same as the - * future_challenge stored in the remote identity. - */ + /* Calculate the signature */ + { + unsigned char *sign; + size_t signlen; + DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); + DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); + const DDS_Security_BinaryProperty_t *binary_properties[HANDSHAKE_SIGNATURE_CONTENT_SIZE] = { hash_c2_val, challenge2, dh2, challenge1, dh1, hash_c1_val }; + DDS_Security_ValidationResult_t result = create_signature(localIdent->privateKey, binary_properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE, &sign, &signlen, ex); + DDS_Security_BinaryProperty_free(hash_c1_val); + DDS_Security_BinaryProperty_free(hash_c2_val); + if (result != DDS_SECURITY_VALIDATION_OK) + goto err_signature; + DDS_Security_BinaryProperty_set_by_ref(signature, "signature", sign, (uint32_t)signlen); + } + (void)ddsrt_hh_add(impl->objectHash, handshake); + handshake_message_out->class_id = ddsrt_strdup(AUTH_HANDSHAKE_REPLY_TOKEN_ID); + handshake_message_out->binary_properties._length = tokenSize; + handshake_message_out->binary_properties._buffer = tokens; + ddsrt_mutex_unlock(&impl->lock); - if (relation->rchallenge) { - if (memcmp(relation->rchallenge->value, challenge1->value._buffer, sizeof(AuthenticationChallenge)) != 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge1 does not match future_challenge"); - goto err_no_challenge; - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: No challenge exists to check challenge1 in the token."); - goto err_no_challenge; - } + *handshake_handle = HANDSHAKE_HANDLE(handshake); + return DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE; - if (relation->lchallenge) { - if (memcmp(relation->lchallenge->value, challenge2->value._buffer, sizeof(AuthenticationChallenge)) != 0) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property challenge2 does not match future_challenge"); - goto err_no_challenge; - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: No challenge exists to check challenge2 in the token."); - goto err_no_challenge; - } - - signature = DDS_Security_DataHolder_find_binary_property(token, "signature"); - if (!signature) { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, - "process_handshake: HandshakeMessageToken property signature missing"); - goto err_no_challenge; - } - - /* Validate signature */ - public_key = X509_get_pubkey(relation->remoteIdentity->identityCert); - if (public_key) { - /*prepare properties*/ - const DDS_Security_BinaryProperty_t *properties[HANDSHAKE_SIGNATURE_CONTENT_SIZE]; - DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); - DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); - - properties[0] = hash_c1_val; - properties[1] = challenge1; - properties[2] = dh1; - properties[3] = challenge2; - properties[4] = dh2; - properties[5] = hash_c2_val; - - result = validate_signature(public_key,properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE ,signature->value._buffer,signature->value._length,ex ); - - EVP_PKEY_free(public_key); - DDS_Security_BinaryProperty_free(hash_c1_val); - DDS_Security_BinaryProperty_free(hash_c2_val); - - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_signature; - } - } else { - result = DDS_SECURITY_VALIDATION_FAILED; - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "X509_get_pubkey failed"); - goto err_inv_identity_cert; - } - -err_inv_hash_c2: -err_inv_hash_c1: -err_no_challenge: -err_inv_class_id: -err_inv_identity_cert: -err_inv_signature: - return result; +err_signature: + free_binary_properties(tokens, tokenSize); +err_get_public_key: +err_gen_dh_keys: + ddsrt_free(certData); +err_alloc_cid: +err_inv_token: + if (created) + { + (void)ddsrt_hh_remove(impl->objectHash, handshake); + security_object_free((SecurityObject *)handshake); + } +err_inv_handle: + ddsrt_mutex_unlock(&impl->lock); +err_bad_param: + return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_ValidationResult_t -begin_handshake_reply( - dds_security_authentication *instance, - DDS_Security_HandshakeHandle *handshake_handle, - DDS_Security_HandshakeMessageToken *handshake_message_out, - const DDS_Security_HandshakeMessageToken *handshake_message_in, - const DDS_Security_IdentityHandle initiator_identity_handle, - const DDS_Security_IdentityHandle replier_identity_handle, - const DDS_Security_OctetSeq *serialized_local_participant_data, - DDS_Security_SecurityException *ex) +static bool generate_shared_secret(const HandshakeInfo *handshake, unsigned char **shared_secret, DDS_Security_long *length, DDS_Security_SecurityException *ex) { - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - HandshakeInfo *handshake = NULL; - IdentityRelation *relation = NULL; - SecurityObject *obj; - LocalIdentityInfo *localIdent; - RemoteIdentityInfo *remoteIdent; - EVP_PKEY *dhkeyLocal = NULL; - 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; - const DDS_Security_BinaryProperty_t *hash_c1_ref; - DDS_Security_BinaryProperty_t *hash_c2; - DDS_Security_BinaryProperty_t *dh1; - const DDS_Security_BinaryProperty_t *dh1_ref; - DDS_Security_BinaryProperty_t *dh2; - DDS_Security_BinaryProperty_t *challenge1; - DDS_Security_BinaryProperty_t *challenge2; - DDS_Security_BinaryProperty_t *signature; - unsigned char *certData; - unsigned char *dhPubKeyData; - uint32_t certDataSize, dhPubKeyDataSize; - uint32_t tokenSize, idx; - int created = 0; + EVP_PKEY_CTX *ctx; + size_t skeylen; + unsigned char *secret = NULL; + *shared_secret = NULL; - /* validate provided arguments */ - if (!instance || !handshake_handle || !handshake_message_out || !handshake_message_in || !serialized_local_participant_data) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "begin_handshake_reply: Invalid parameter provided"); - goto err_bad_param; - } + if (!(ctx = EVP_PKEY_CTX_new(handshake->ldh, NULL /* no engine */))) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: Shared secret failed to create context: "); + goto fail_ctx_new; + } - if ((serialized_local_participant_data->_length == 0) || (serialized_local_participant_data->_buffer == NULL)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "begin_handshake_reply: Invalid parameter provided"); - goto err_bad_param; - } + if (EVP_PKEY_derive_init(ctx) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: Shared secret failed to initialize context: "); + goto fail_derive; + } + if (EVP_PKEY_derive_set_peer(ctx, handshake->rdh) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: Shared secret failed to set peer key: "); + goto fail_derive; + } - ddsrt_mutex_lock(&impl->lock); + /* Determine buffer length */ + if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: Shared secret failed to determine key length: "); + goto fail_derive; + } - obj = security_object_find(impl->objectHash, replier_identity_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_LOCAL_IDENTITY)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "begin_handshake_reply: Invalid replier_identity_handle provided"); - goto err_inv_handle; - } - localIdent = (LocalIdentityInfo *) obj; + secret = ddsrt_malloc(skeylen); + if (EVP_PKEY_derive(ctx, secret, &skeylen) <= 0) + { + DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: Could not compute the shared secret: "); + goto fail_derive; + } - obj = security_object_find(impl->objectHash, initiator_identity_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_REMOTE_IDENTITY)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "begin_handshake_reply: Invalid initiator_identity_handle provided"); - goto err_inv_handle; - } - remoteIdent = (RemoteIdentityInfo *)obj; + *shared_secret = ddsrt_malloc(SHA256_DIGEST_LENGTH); + *length = SHA256_DIGEST_LENGTH; + SHA256(secret, skeylen, *shared_secret); + ddsrt_free(secret); + EVP_PKEY_CTX_free(ctx); + return true; - handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(localIdent), SECURITY_OBJECT_HANDLE(remoteIdent)); - if (!handshake) { - relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)); - assert(relation); - handshake = handshakeInfoNew(localIdent, remoteIdent, relation); - handshake->created_in = CREATEDREPLY; - (void)ddsrt_hh_add(impl->objectHash, handshake); - created = 1; - } else { - relation = handshake->relation; - assert(relation); - } +fail_derive: + ddsrt_free(secret); + EVP_PKEY_CTX_free(ctx); +fail_ctx_new: + return false; +} - result = validate_handshake_request_token(handshake_message_in, handshake, &(impl->trustedCAList), ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_token; - } +DDS_Security_ValidationResult_t process_handshake(dds_security_authentication *instance, DDS_Security_HandshakeMessageToken *handshake_message_out, + const DDS_Security_HandshakeMessageToken *handshake_message_in, const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex) +{ + DDS_Security_ValidationResult_t hs_result = DDS_SECURITY_VALIDATION_OK; + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + HandshakeInfo *handshake = NULL; + IdentityRelation *relation = NULL; + SecurityObject *obj; + EVP_PKEY *dhkeyRemote = NULL; + DDS_Security_BinaryProperty_t *tokens = NULL, *hash_c1 = NULL, *hash_c2 = NULL, *dh1, *dh2, *challenge1, *challenge2, *signature; + const DDS_Security_BinaryProperty_t *hash_c1_ref, *hash_c2_ref, *challenge1_ref, *challenge2_ref, *dh1_ref, *dh2_ref; + uint32_t tokenSize = 0, idx; + DDS_Security_octet *challenge1_ref_for_shared_secret, *challenge2_ref_for_shared_secret; - result = get_certificate_contents(localIdent->identityCert, &certData, &certDataSize, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_alloc_cid; - } + /* validate provided arguments */ + if (!instance || !handshake_handle || !handshake_message_out || !handshake_message_in) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: Invalid parameter provided"); + goto err_bad_param; + } - if (!handshake->ldh) { - result = generate_dh_keys(&dhkeyLocal, remoteIdent->kagreeAlgoKind, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_gen_dh_keys; - } + memset(handshake_message_out, 0, sizeof(DDS_Security_HandshakeMessageToken)); - handshake->ldh = dhkeyLocal; - EVP_PKEY_copy_parameters(handshake->rdh, handshake->ldh); - } + ddsrt_mutex_lock(&impl->lock); + obj = security_object_find(impl->objectHash, handshake_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_HANDSHAKE)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "process_handshake: Invalid replier_identity_handle provided"); + goto err_inv_handle; + } + handshake = (HandshakeInfo *)obj; + relation = handshake->relation; + assert(relation); - result = dh_public_key_to_oct(handshake->ldh, remoteIdent->kagreeAlgoKind, &dhPubKeyData, &dhPubKeyDataSize, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_get_public_key; - } + /* check if the handle created by a handshake_request or handshake_reply */ + switch (handshake->created_in) + { + case CREATEDREQUEST: + /* The source of the handshake_handle is a begin_handshake_request function. So, handshake_message_in is from a remote begin_handshake_reply function */ + /* Verify Message Token contents according to Spec 9.3.2.5.2 (Reply Message) */ + if (validate_handshake_reply_token(handshake_message_in, handshake, &dhkeyRemote, &(impl->trustedCAList), ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_token; - if (localIdent->pdata._length == 0) { - DDS_Security_OctetSeq_copy(&localIdent->pdata, serialized_local_participant_data); - } + handshake->rdh = dhkeyRemote; + EVP_PKEY_copy_parameters(handshake->rdh, handshake->ldh); + /* Prepare HandshakeFinalMessageToken */ hash_c1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "hash_c1"); - tokenSize = hash_c1_ref ? 12 : 11; - + hash_c2_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "hash_c2"); + dh1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "dh1"); + dh2_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "dh2"); + challenge1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "challenge1"); + challenge2_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "challenge2"); + tokenSize = 3; /* challenge1, challenge2 and signature are in already */ + if (hash_c1_ref) tokenSize++; + if (hash_c2_ref) tokenSize++; + if (dh1_ref) tokenSize++; + if (dh2_ref) tokenSize++; tokens = DDS_Security_BinaryPropertySeq_allocbuf(tokenSize); idx = 0; - c_id = &tokens[idx++]; - c_perm = &tokens[idx++]; - c_pdata = &tokens[idx++]; - c_dsign_algo = &tokens[idx++]; - c_kagree_algo = &tokens[idx++]; signature = &tokens[idx++]; - hash_c2 = &tokens[idx++]; + hash_c2 = hash_c2_ref ? &tokens[idx++] : NULL; challenge2 = &tokens[idx++]; - dh2 = &tokens[idx++]; + dh2 = dh2_ref ? &tokens[idx++] : NULL; challenge1 = &tokens[idx++]; - dh1 = &tokens[idx++]; + dh1 = dh1_ref ? &tokens[idx++] : NULL; hash_c1 = hash_c1_ref ? &tokens[idx++] : NULL; - /* Store the Identity Certificate associated with the local identify in c.id property */ - DDS_Security_BinaryProperty_set_by_ref(c_id, "c.id", certData, certDataSize); - certData = NULL; - - /* Store the permission document in the c.perm property */ - if (localIdent->permissionsDocument) { - DDS_Security_BinaryProperty_set_by_string(c_perm, "c.perm", localIdent->permissionsDocument); - } else { - DDS_Security_BinaryProperty_set_by_string(c_perm, "c.perm", ""); - } - - /* Store the provided local_participant_data in the c.pdata property */ - DDS_Security_BinaryProperty_set_by_value(c_pdata, "c.pdata", serialized_local_participant_data->_buffer, serialized_local_participant_data->_length); - - /* Set the used signing algorithm descriptor in c.dsign_algo */ - DDS_Security_BinaryProperty_set_by_string(c_dsign_algo, "c.dsign_algo", get_dsign_algo(localIdent->dsignAlgoKind)); - - /* Set the used key algorithm descriptor in c.kagree_algo */ - DDS_Security_BinaryProperty_set_by_string(c_kagree_algo, "c.kagree_algo", get_kagree_algo(remoteIdent->kagreeAlgoKind)); - - /* Calculate the hash_c2 */ - { - DDS_Security_BinaryPropertySeq bseq; - - bseq._length = 5; - bseq._buffer = tokens; - - get_hash_binary_property_seq(&bseq, handshake->hash_c2); - DDS_Security_BinaryProperty_set_by_value(hash_c2, "hash_c2", handshake->hash_c2, sizeof(HashValue_t)); - } - - /* Set the DH public key associated with the local participant in dh2 property */ - DDS_Security_BinaryProperty_set_by_ref(dh2, "dh2", dhPubKeyData, dhPubKeyDataSize); - - /* Set the DH public key associated with the local participant in hash_c1 property */ - if (hash_c1) { - DDS_Security_BinaryProperty_set_by_value(hash_c1, "hash_c1", hash_c1_ref->value._buffer, hash_c1_ref->value._length); - } - - /* Set the DH public key associated with the local participant in dh1 property */ - if (dh1) { - dh1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "dh1"); - if (dh1_ref) { - DDS_Security_BinaryProperty_set_by_value(dh1, "dh1", dh1_ref->value._buffer, dh1_ref->value._length); - } - } - - /* Set the challenge in challenge1 property */ - assert(relation->rchallenge); - DDS_Security_BinaryProperty_set_by_value(challenge1, "challenge1", relation->rchallenge->value, sizeof(AuthenticationChallenge)); - - /* Set the challenge in challenge2 property */ + if (hash_c1) + DDS_Security_BinaryProperty_set_by_value(hash_c1, "hash_c1", hash_c1_ref->value._buffer, hash_c1_ref->value._length); + if (hash_c2) + DDS_Security_BinaryProperty_set_by_value(hash_c2, "hash_c2", hash_c2_ref->value._buffer, hash_c2_ref->value._length); + if (dh1) + DDS_Security_BinaryProperty_set_by_value(dh1, "dh1", dh1_ref->value._buffer, dh1_ref->value._length); + if (dh2) + DDS_Security_BinaryProperty_set_by_value(dh2, "dh2", dh2_ref->value._buffer, dh2_ref->value._length); assert(relation->lchallenge); - - DDS_Security_BinaryProperty_set_by_value(challenge2, "challenge2", relation->lchallenge->value, sizeof(AuthenticationChallenge)); + if (challenge1 && challenge1_ref) + DDS_Security_BinaryProperty_set_by_value(challenge1, "challenge1", challenge1_ref->value._buffer, challenge1_ref->value._length); + assert(relation->rchallenge); + if (challenge2 && challenge2_ref) + DDS_Security_BinaryProperty_set_by_value(challenge2, "challenge2", challenge2_ref->value._buffer, challenge2_ref->value._length); /* Calculate the signature */ { - unsigned char *sign; - size_t signlen; - const DDS_Security_BinaryProperty_t * binary_properties[ HANDSHAKE_SIGNATURE_CONTENT_SIZE ]; - DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); - DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); - - binary_properties[0] = hash_c2_val; - binary_properties[1] = challenge2; - binary_properties[2] = dh2; - binary_properties[3] = challenge1; - binary_properties[4] = dh1; - binary_properties[5] = hash_c1_val; - - result = create_signature(localIdent->privateKey, binary_properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE , &sign, &signlen, ex); - - DDS_Security_BinaryProperty_free(hash_c1_val); - DDS_Security_BinaryProperty_free(hash_c2_val); - - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_signature; - } - DDS_Security_BinaryProperty_set_by_ref(signature, "signature", sign, (uint32_t)signlen); + unsigned char *sign; + size_t signlen; + DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); + DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); + const DDS_Security_BinaryProperty_t *binary_properties[HANDSHAKE_SIGNATURE_CONTENT_SIZE] = { hash_c1_val, challenge1, dh1, challenge2, dh2, hash_c2_val }; + DDS_Security_ValidationResult_t result = create_signature(relation->localIdentity->privateKey, binary_properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE, &sign, &signlen, ex); + DDS_Security_BinaryProperty_free(hash_c1_val); + DDS_Security_BinaryProperty_free(hash_c2_val); + if (result != DDS_SECURITY_VALIDATION_OK) + goto err_signature; + DDS_Security_BinaryProperty_set_by_ref(signature, "signature", sign, (uint32_t)signlen); } - (void)ddsrt_hh_add(impl->objectHash, handshake); - - handshake_message_out->class_id = ddsrt_strdup(AUTH_HANDSHAKE_REPLY_TOKEN_ID); + handshake_message_out->class_id = ddsrt_strdup(AUTH_HANDSHAKE_FINAL_TOKEN_ID); handshake_message_out->binary_properties._length = tokenSize; handshake_message_out->binary_properties._buffer = tokens; + challenge1_ref_for_shared_secret = (DDS_Security_octet *)(handshake->relation->lchallenge); + challenge2_ref_for_shared_secret = (DDS_Security_octet *)(handshake->relation->rchallenge); + hs_result = DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE; + break; + case CREATEDREPLY: + /* The source of the handshake_handle is a begin_handshake_reply function So, handshake_message_in is from a remote process_handshake function */ + /* Verify Message Token contents according to Spec 9.3.2.5.3 (Final Message) */ + if (validate_handshake_final_token(handshake_message_in, handshake, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_inv_token; + challenge2_ref_for_shared_secret = (DDS_Security_octet *)(handshake->relation->lchallenge); + challenge1_ref_for_shared_secret = (DDS_Security_octet *)(handshake->relation->rchallenge); + hs_result = DDS_SECURITY_VALIDATION_OK; + break; + + default: ddsrt_mutex_unlock(&impl->lock); + goto err_bad_param; + } + { + DDS_Security_long shared_secret_length; + unsigned char *shared_secret; + if (!generate_shared_secret(handshake, &shared_secret, &shared_secret_length, ex)) + goto err_openssl; + handshake->shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl)); + handshake->shared_secret_handle_impl->shared_secret = shared_secret; + handshake->shared_secret_handle_impl->shared_secret_size = shared_secret_length; + memcpy(handshake->shared_secret_handle_impl->challenge1, challenge1_ref_for_shared_secret, DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + memcpy(handshake->shared_secret_handle_impl->challenge2, challenge2_ref_for_shared_secret, DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); + } - *handshake_handle = HANDSHAKE_HANDLE(handshake); - - if (result == DDS_SECURITY_VALIDATION_OK) { - result = DDS_SECURITY_VALIDATION_PENDING_HANDSHAKE_MESSAGE; - } - - return result; - -err_signature: - free_binary_properties(tokens, tokenSize); -err_get_public_key: -err_gen_dh_keys: - ddsrt_free(certData); -err_alloc_cid: -err_inv_token: - if (created) { - (void)ddsrt_hh_remove(impl->objectHash, handshake); - security_object_free((SecurityObject *)handshake); - } -err_inv_handle: - ddsrt_mutex_unlock(&impl->lock); -err_bad_param: - return DDS_SECURITY_VALIDATION_FAILED; -} - - -static bool -generate_shared_secret( - const HandshakeInfo *handshake, - unsigned char **shared_secret, - DDS_Security_long *length, - DDS_Security_SecurityException *ex) -{ - bool result = false; - EVP_PKEY_CTX *ctx; - size_t skeylen; - unsigned char *secret = NULL; - - *shared_secret = NULL; - - ctx = EVP_PKEY_CTX_new( handshake->ldh, NULL /* no engine */); - if (!ctx) + { + /* setup expiry listener */ + dds_time_t cert_exp = get_certificate_expiry(handshake->relation->remoteIdentity->identityCert); + if (cert_exp == DDS_TIME_INVALID) { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "process_handshake: Shared secret failed to create context: "); - goto fail_ctx_new; + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "Expiry date of the certificate is invalid"); + goto err_invalid_expiry; } - - if (EVP_PKEY_derive_init(ctx) <= 0) - { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "process_handshake: Shared secret failed to initialize context: "); - goto fail_derive; - } - if (EVP_PKEY_derive_set_peer(ctx, handshake->rdh) <= 0) - { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "process_handshake: Shared secret failed to set peer key: "); - goto fail_derive; - } - - /* Determine buffer length */ - if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0) - { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "process_handshake: Shared secret failed to determine key length: "); - goto fail_derive; - } - - secret = ddsrt_malloc(skeylen); - if (EVP_PKEY_derive(ctx, secret, &skeylen) <= 0) - { - DDS_Security_Exception_set_with_openssl_error(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "process_handshake: Could not compute the shared secret: "); - goto fail_derive; - } - - *shared_secret = ddsrt_malloc(SHA256_DIGEST_LENGTH); - *length = SHA256_DIGEST_LENGTH; - - SHA256(secret, skeylen, *shared_secret); - - result = true; - -fail_derive: - ddsrt_free(secret); - EVP_PKEY_CTX_free(ctx); -fail_ctx_new: - return result; -} - - - - -DDS_Security_ValidationResult_t -process_handshake( - dds_security_authentication *instance, - DDS_Security_HandshakeMessageToken *handshake_message_out, - const DDS_Security_HandshakeMessageToken *handshake_message_in, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex) -{ - DDS_Security_ValidationResult_t result = DDS_SECURITY_VALIDATION_OK; - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - HandshakeInfo *handshake = NULL; - IdentityRelation *relation = NULL; - SecurityObject *obj; - EVP_PKEY *dhkeyRemote = NULL; - DDS_Security_BinaryProperty_t *tokens = NULL; - DDS_Security_BinaryProperty_t *hash_c1 = NULL; - const DDS_Security_BinaryProperty_t *hash_c1_ref; - const DDS_Security_BinaryProperty_t *hash_c2_ref; - const DDS_Security_BinaryProperty_t *challenge1_ref; - const DDS_Security_BinaryProperty_t *challenge2_ref; - const DDS_Security_BinaryProperty_t *dh1_ref; - const DDS_Security_BinaryProperty_t *dh2_ref; - DDS_Security_BinaryProperty_t *hash_c2 = NULL; - 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; - uint32_t tokenSize=0, idx; - DDS_Security_octet * challenge1_ref_for_shared_secret, *challenge2_ref_for_shared_secret; - - /* validate provided arguments */ - if (!instance || !handshake_handle || !handshake_message_out || !handshake_message_in) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "process_handshake: Invalid parameter provided"); - goto err_bad_param; - } - - memset(handshake_message_out, 0, sizeof(DDS_Security_HandshakeMessageToken)); - - ddsrt_mutex_lock(&impl->lock); - - obj = security_object_find(impl->objectHash, handshake_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_HANDSHAKE)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, - "process_handshake: Invalid replier_identity_handle provided"); - goto err_inv_handle; - } - handshake = (HandshakeInfo *) obj; - relation = handshake->relation; - assert(relation); - - /* check if the handle created by a handshake_request or handshake_reply */ - - switch (handshake->created_in) { - case CREATEDREQUEST: - /* The source of the handshake_handle is a begin_handshake_request function - * So, handshake_message_in should have been came from a remote begin_handshake_reply function - */ - /* Verify Message Token contents according to Spec 9.3.2.5.2 (Reply Message) */ - result = validate_handshake_reply_token(handshake_message_in, handshake, &dhkeyRemote, &(impl->trustedCAList), ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_token; - } - - /*set received remote DH (dh2) */ - handshake->rdh = dhkeyRemote; - - EVP_PKEY_copy_parameters(handshake->rdh, handshake->ldh); - - /* Prepare HandshakeFinalMessageToken */ - - /* Get references from message_in */ - hash_c1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "hash_c1"); - hash_c2_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "hash_c2"); - dh1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "dh1"); - dh2_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, "dh2"); - challenge1_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, - "challenge1"); - challenge2_ref = DDS_Security_DataHolder_find_binary_property(handshake_message_in, - "challenge2"); - - tokenSize = 3; /* challenge1, challenge2 and signature are already exist */ - if (hash_c1_ref) - tokenSize++; - if (hash_c2_ref) - tokenSize++; - if (dh1_ref) - tokenSize++; - if (dh2_ref) - tokenSize++; - - tokens = DDS_Security_BinaryPropertySeq_allocbuf(tokenSize); - idx = 0; - signature = &tokens[idx++]; - hash_c2 = hash_c2_ref ? &tokens[idx++] : NULL; - challenge2 = &tokens[idx++]; - dh2 = dh2_ref ? &tokens[idx++] : NULL; - challenge1 = &tokens[idx++]; - dh1 = dh1_ref ? &tokens[idx++] : NULL; - hash_c1 = hash_c1_ref ? &tokens[idx++] : NULL; - - if (hash_c1) { - DDS_Security_BinaryProperty_set_by_value(hash_c1, "hash_c1", hash_c1_ref->value._buffer, - hash_c1_ref->value._length); - } - if (hash_c2) { - DDS_Security_BinaryProperty_set_by_value(hash_c2, "hash_c2", hash_c2_ref->value._buffer, - hash_c2_ref->value._length); - } - if (dh1) { - DDS_Security_BinaryProperty_set_by_value(dh1, "dh1", dh1_ref->value._buffer, - dh1_ref->value._length); - } - if (dh2) { - DDS_Security_BinaryProperty_set_by_value(dh2, "dh2", dh2_ref->value._buffer, - dh2_ref->value._length); - } - assert(relation->lchallenge); - if (challenge1 && challenge1_ref) { - DDS_Security_BinaryProperty_set_by_value(challenge1, "challenge1", challenge1_ref->value._buffer, - challenge1_ref->value._length); - } - assert(relation->rchallenge); - if (challenge2 && challenge2_ref) { - DDS_Security_BinaryProperty_set_by_value(challenge2, "challenge2", challenge2_ref->value._buffer, - challenge2_ref->value._length); - } - - - /* Calculate the signature */ - { - const DDS_Security_BinaryProperty_t * binary_properties[ HANDSHAKE_SIGNATURE_CONTENT_SIZE ]; - DDS_Security_BinaryProperty_t *hash_c1_val = hash_value_to_binary_property("hash_c1", handshake->hash_c1); - DDS_Security_BinaryProperty_t *hash_c2_val = hash_value_to_binary_property("hash_c2", handshake->hash_c2); - unsigned char *sign; - size_t signlen; - - binary_properties[0] = hash_c1_val; - binary_properties[1] = challenge1; - binary_properties[2] = dh1; - binary_properties[3] = challenge2; - binary_properties[4] = dh2; - binary_properties[5] = hash_c2_val; - - result = create_signature(relation->localIdentity->privateKey, binary_properties, HANDSHAKE_SIGNATURE_CONTENT_SIZE, &sign, &signlen, ex); - - DDS_Security_BinaryProperty_free(hash_c1_val); - DDS_Security_BinaryProperty_free(hash_c2_val); - - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_signature; - } - - DDS_Security_BinaryProperty_set_by_ref(signature, "signature", sign, (uint32_t)signlen); - } - - handshake_message_out->class_id = ddsrt_strdup(AUTH_HANDSHAKE_FINAL_TOKEN_ID); - handshake_message_out->binary_properties._length = tokenSize; - handshake_message_out->binary_properties._buffer = tokens; - - challenge1_ref_for_shared_secret = (DDS_Security_octet*)(handshake->relation->lchallenge); - challenge2_ref_for_shared_secret = (DDS_Security_octet*)(handshake->relation->rchallenge); - - result = DDS_SECURITY_VALIDATION_OK_FINAL_MESSAGE; - - break; - case CREATEDREPLY: - /* The source of the handshake_handle is a begin_handshake_reply function - * So, handshake_message_in should have been came from a remote process_handshake function - */ - - /* Verify Message Token contents according to Spec 9.3.2.5.3 (Final Message) */ - result = validate_handshake_final_token(handshake_message_in, handshake, ex); - if (result != DDS_SECURITY_VALIDATION_OK) { - goto err_inv_token; - } - - - challenge2_ref_for_shared_secret = (DDS_Security_octet*)(handshake->relation->lchallenge); - challenge1_ref_for_shared_secret = (DDS_Security_octet*)(handshake->relation->rchallenge); - - result = DDS_SECURITY_VALIDATION_OK; - - break; - default: - ddsrt_mutex_unlock(&impl->lock); - goto err_bad_param; - } - - /* Compute shared secret */ - { - DDS_Security_long shared_secret_length; - unsigned char *shared_secret; - - if (!generate_shared_secret(handshake, &shared_secret, &shared_secret_length, ex)) { - goto err_openssl; - } - - handshake->shared_secret_handle_impl = ddsrt_malloc( sizeof(DDS_Security_SharedSecretHandleImpl)); - handshake->shared_secret_handle_impl->shared_secret = shared_secret; - handshake->shared_secret_handle_impl->shared_secret_size = shared_secret_length; - - /* put references to challenge1 and challenge2 into shared secret object */ - memcpy( handshake->shared_secret_handle_impl->challenge1, challenge1_ref_for_shared_secret, DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); - memcpy( handshake->shared_secret_handle_impl->challenge2, challenge2_ref_for_shared_secret, DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE); - } - - { /* setup expiry listener */ - dds_time_t certExpiry = get_certificate_expiry( handshake->relation->remoteIdentity->identityCert ); - - if( certExpiry == DDS_TIME_INVALID ){ - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, (int)result, "Expiry date of the certificate is invalid"); - goto err_invalid_expiry; - } else if( certExpiry != DDS_NEVER ){ - add_validity_end_trigger( impl, - IDENTITY_HANDLE( handshake->relation->remoteIdentity ), - certExpiry); - } - - } - - ddsrt_mutex_unlock(&impl->lock); - - return result; + else if (cert_exp != DDS_NEVER) + add_validity_end_trigger(impl, IDENTITY_HANDLE(handshake->relation->remoteIdentity), cert_exp); + } + ddsrt_mutex_unlock(&impl->lock); + return hs_result; err_invalid_expiry: - ddsrt_free( handshake->shared_secret_handle_impl->shared_secret ); - ddsrt_free( handshake->shared_secret_handle_impl ); + ddsrt_free(handshake->shared_secret_handle_impl->shared_secret); + ddsrt_free(handshake->shared_secret_handle_impl); + handshake->shared_secret_handle_impl = NULL; err_openssl: err_signature: - if (handshake_message_out->class_id) { - DDS_Security_DataHolder_deinit(handshake_message_out); - } + if (handshake_message_out->class_id) + DDS_Security_DataHolder_deinit(handshake_message_out); err_inv_token: err_inv_handle: - ddsrt_mutex_unlock(&impl->lock); + ddsrt_mutex_unlock(&impl->lock); err_bad_param: - return DDS_SECURITY_VALIDATION_FAILED; + return DDS_SECURITY_VALIDATION_FAILED; } -DDS_Security_SharedSecretHandle get_shared_secret( - dds_security_authentication *instance, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex) +DDS_Security_SharedSecretHandle get_shared_secret(dds_security_authentication *instance, const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex) { + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + SecurityObject *obj; - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - SecurityObject *obj; + if (!instance || !handshake_handle) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid parameter provided"); + goto err_bad_param; + } + ddsrt_mutex_lock(&impl->lock); + obj = security_object_find(impl->objectHash, handshake_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_HANDSHAKE)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid handle provided"); + goto err_invalid_handle; + } + ddsrt_mutex_unlock(&impl->lock); + return (DDS_Security_SharedSecretHandle)(ddsrt_address)((HandshakeInfo *)obj)->shared_secret_handle_impl; - /* validate provided arguments */ - if (!instance || !handshake_handle) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid parameter provided"); - goto err_bad_param; - } - - ddsrt_mutex_lock(&impl->lock); - obj = security_object_find(impl->objectHash, handshake_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_HANDSHAKE)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid handle provided"); - goto err_invalid_handle; - } - - ddsrt_mutex_unlock(&impl->lock); - return (DDS_Security_SharedSecretHandle)(ddsrt_address)((HandshakeInfo*)obj)->shared_secret_handle_impl; - - - err_invalid_handle: - ddsrt_mutex_unlock(&impl->lock); - err_bad_param: - return DDS_SECURITY_HANDLE_NIL; +err_invalid_handle: + ddsrt_mutex_unlock(&impl->lock); +err_bad_param: + return DDS_SECURITY_HANDLE_NIL; } -DDS_Security_boolean -get_authenticated_peer_credential_token( - dds_security_authentication *instance, - DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex) +DDS_Security_boolean get_authenticated_peer_credential_token(dds_security_authentication *instance, DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, + const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex) { - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - HandshakeInfo *handshake = NULL; - X509 *identity_cert; - char *permissions_doc; - unsigned char *cert_data; - uint32_t cert_data_size; + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + HandshakeInfo *handshake = NULL; + X509 *identity_cert; + char *permissions_doc; + unsigned char *cert_data; + uint32_t cert_data_size; - /* validate provided arguments */ - if (!instance || !handshake_handle || !peer_credential_token) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_INVALID_PARAMETER_CODE, 0, - DDS_SECURITY_ERR_INVALID_PARAMETER_MESSAGE); - return false; - } + if (!instance || !handshake_handle || !peer_credential_token) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_PARAMETER_CODE, 0, DDS_SECURITY_ERR_INVALID_PARAMETER_MESSAGE); + return false; + } - ddsrt_mutex_lock(&impl->lock); + ddsrt_mutex_lock(&impl->lock); - handshake = (HandshakeInfo *) security_object_find(impl->objectHash, handshake_handle); - if (!handshake || !SECURITY_OBJECT_VALID(handshake, SECURITY_OBJECT_KIND_HANDSHAKE)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_INVALID_PARAMETER_CODE, 0, - DDS_SECURITY_ERR_INVALID_PARAMETER_MESSAGE); - goto err_inv_handle; - } + handshake = (HandshakeInfo *)security_object_find(impl->objectHash, handshake_handle); + if (!handshake || !SECURITY_OBJECT_VALID(handshake, SECURITY_OBJECT_KIND_HANDSHAKE)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_PARAMETER_CODE, 0, DDS_SECURITY_ERR_INVALID_PARAMETER_MESSAGE); + goto err_inv_handle; + } - identity_cert = handshake->relation->remoteIdentity->identityCert; - if (!identity_cert) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_OPERATION_NOT_PERMITTED_CODE, 0, - DDS_SECURITY_ERR_OPERATION_NOT_PERMITTED_MESSAGE); - goto err_missing_attr; - } + if (!(identity_cert = handshake->relation->remoteIdentity->identityCert)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_OPERATION_NOT_PERMITTED_CODE, 0, DDS_SECURITY_ERR_OPERATION_NOT_PERMITTED_MESSAGE); + goto err_missing_attr; + } - permissions_doc = handshake->relation->remoteIdentity->permissionsDocument; - if (!permissions_doc) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, - DDS_SECURITY_ERR_MISSING_REMOTE_PERMISSIONS_DOCUMENT_CODE, 0, - DDS_SECURITY_ERR_MISSING_REMOTE_PERMISSIONS_DOCUMENT_MESSAGE); - goto err_missing_attr; - } + if (!(permissions_doc = handshake->relation->remoteIdentity->permissionsDocument)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_MISSING_REMOTE_PERMISSIONS_DOCUMENT_CODE, 0, DDS_SECURITY_ERR_MISSING_REMOTE_PERMISSIONS_DOCUMENT_MESSAGE); + goto err_missing_attr; + } - if (get_certificate_contents(identity_cert, &cert_data, &cert_data_size, ex) != DDS_SECURITY_VALIDATION_OK) { - goto err_alloc_cid; - } + if (get_certificate_contents(identity_cert, &cert_data, &cert_data_size, ex) != DDS_SECURITY_VALIDATION_OK) + goto err_alloc_cid; - memset(peer_credential_token, 0, sizeof(*peer_credential_token)); - - peer_credential_token->class_id = get_authentication_class_id(); - - peer_credential_token->properties._length = 2; - peer_credential_token->properties._buffer = DDS_Security_PropertySeq_allocbuf(peer_credential_token->properties._length); - - peer_credential_token->properties._buffer[0].name = ddsrt_strdup("c.id"); - peer_credential_token->properties._buffer[0].value = (char *)cert_data; - peer_credential_token->properties._buffer[0].propagate = false; - - peer_credential_token->properties._buffer[1].name = ddsrt_strdup("c.perm"); - peer_credential_token->properties._buffer[1].value = ddsrt_strdup(permissions_doc); - peer_credential_token->properties._buffer[1].propagate = false; - - ddsrt_mutex_unlock(&impl->lock); - - return true; + memset(peer_credential_token, 0, sizeof(*peer_credential_token)); + peer_credential_token->class_id = get_authentication_class_id(); + peer_credential_token->properties._length = 2; + peer_credential_token->properties._buffer = DDS_Security_PropertySeq_allocbuf(peer_credential_token->properties._length); + peer_credential_token->properties._buffer[0].name = ddsrt_strdup("c.id"); + peer_credential_token->properties._buffer[0].value = (char *)cert_data; + peer_credential_token->properties._buffer[0].propagate = false; + peer_credential_token->properties._buffer[1].name = ddsrt_strdup("c.perm"); + peer_credential_token->properties._buffer[1].value = ddsrt_strdup(permissions_doc); + peer_credential_token->properties._buffer[1].propagate = false; + ddsrt_mutex_unlock(&impl->lock); + return true; err_alloc_cid: err_missing_attr: err_inv_handle: - ddsrt_mutex_unlock(&impl->lock); + ddsrt_mutex_unlock(&impl->lock); + return false; +} + +DDS_Security_boolean set_listener(dds_security_authentication *instance, const dds_security_authentication_listener *listener, DDS_Security_SecurityException *ex) +{ + DDSRT_UNUSED_ARG(ex); + dds_security_authentication_impl *auth = (dds_security_authentication_impl *)instance; + if (listener) + dds_security_timed_dispatcher_enable(auth->timed_callbacks, auth->dispatcher, (void *)listener); + else + dds_security_timed_dispatcher_disable(auth->timed_callbacks, auth->dispatcher); + return true; +} + +DDS_Security_boolean return_identity_token(dds_security_authentication *instance, const DDS_Security_IdentityToken *token, DDS_Security_SecurityException *ex) +{ + DDSRT_UNUSED_ARG(token); + DDSRT_UNUSED_ARG(ex); + DDSRT_UNUSED_ARG(instance); + return true; +} + +DDS_Security_boolean return_identity_status_token(dds_security_authentication *instance, const DDS_Security_IdentityStatusToken *token, DDS_Security_SecurityException *ex) +{ + DDSRT_UNUSED_ARG(token); + DDSRT_UNUSED_ARG(ex); + DDSRT_UNUSED_ARG(instance); + return true; +} + +DDS_Security_boolean return_authenticated_peer_credential_token(dds_security_authentication *instance, const DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, DDS_Security_SecurityException *ex) +{ + if (!instance || !peer_credential_token) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_PARAMETER_CODE, 0, DDS_SECURITY_ERR_INVALID_PARAMETER_MESSAGE); return false; + } + DDS_Security_DataHolder_deinit((DDS_Security_DataHolder *)peer_credential_token); + return true; } -DDS_Security_boolean set_listener(dds_security_authentication *instance, - const dds_security_authentication_listener *listener, - DDS_Security_SecurityException *ex) +DDS_Security_boolean return_handshake_handle(dds_security_authentication *instance, const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex) { - dds_security_authentication_impl *auth = (dds_security_authentication_impl*)instance; + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; - DDSRT_UNUSED_ARG(ex); + if (!instance || !handshake_handle) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid parameter provided"); + goto err_bad_param; + } - if (listener) { - dds_security_timed_dispatcher_enable(auth->timed_callbacks, auth->dispatcher, (void*)listener); - } else { - dds_security_timed_dispatcher_disable(auth->timed_callbacks, auth->dispatcher); + ddsrt_mutex_lock(&impl->lock); + SecurityObject *obj = security_object_find(impl->objectHash, handshake_handle); + if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_HANDSHAKE)) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid handle provided"); + goto err_invalid_handle; + } + HandshakeInfo *handshake = (HandshakeInfo *)obj; + assert(handshake->relation); + (void)ddsrt_hh_remove(impl->objectHash, obj); + security_object_free((SecurityObject *)handshake); + ddsrt_mutex_unlock(&impl->lock); + return true; + +err_invalid_handle: + ddsrt_mutex_unlock(&impl->lock); +err_bad_param: + return false; +} + +static void invalidate_local_related_objects(dds_security_authentication_impl *impl, LocalIdentityInfo *localIdent) +{ + struct ddsrt_hh_iter it; + SecurityObject *obj; + + for (obj = ddsrt_hh_iter_first(impl->objectHash, &it); obj != NULL; obj = ddsrt_hh_iter_next(&it)) + { + if (obj->kind == SECURITY_OBJECT_KIND_REMOTE_IDENTITY) + { + RemoteIdentityInfo *remoteIdent = (RemoteIdentityInfo *)obj; + HandshakeInfo *handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(localIdent), SECURITY_OBJECT_HANDLE(remoteIdent)); + if (handshake) + { + (void)ddsrt_hh_remove(impl->objectHash, handshake); + security_object_free((SecurityObject *)handshake); + } + IdentityRelation *relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)); + if (relation) + remove_identity_relation(remoteIdent, relation); } - - return true; + } } -DDS_Security_boolean return_identity_token(dds_security_authentication *instance, - const DDS_Security_IdentityToken *token, - DDS_Security_SecurityException *ex) +static void invalidate_remote_related_objects(dds_security_authentication_impl *impl, RemoteIdentityInfo *remoteIdentity) { - DDSRT_UNUSED_ARG(token); - DDSRT_UNUSED_ARG(ex); - DDSRT_UNUSED_ARG(instance); - - return true; -} - -DDS_Security_boolean return_identity_status_token( - dds_security_authentication *instance, - const DDS_Security_IdentityStatusToken *token, - DDS_Security_SecurityException *ex) -{ - DDSRT_UNUSED_ARG(token); - DDSRT_UNUSED_ARG(ex); - DDSRT_UNUSED_ARG(instance); - - return true; -} - -DDS_Security_boolean return_authenticated_peer_credential_token( - dds_security_authentication *instance, - const DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, - DDS_Security_SecurityException *ex) -{ - if ((!instance) || (!peer_credential_token)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_PARAMETER_CODE, 0, DDS_SECURITY_ERR_INVALID_PARAMETER_MESSAGE); - return false; + struct ddsrt_hh_iter it; + for (IdentityRelation *relation = ddsrt_hh_iter_first(remoteIdentity->linkHash, &it); relation != NULL; relation = ddsrt_hh_iter_next(&it)) + { + HandshakeInfo *handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(relation->localIdentity), SECURITY_OBJECT_HANDLE(remoteIdentity)); + if (handshake) + { + (void)ddsrt_hh_remove(impl->objectHash, handshake); + security_object_free((SecurityObject *)handshake); } - - DDS_Security_DataHolder_deinit((DDS_Security_DataHolder *)peer_credential_token); - - return true; + (void)ddsrt_hh_remove(remoteIdentity->linkHash, relation); + security_object_free((SecurityObject *)relation); + } } -DDS_Security_boolean -return_handshake_handle(dds_security_authentication *instance, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex) +DDS_Security_boolean return_identity_handle(dds_security_authentication *instance, const DDS_Security_IdentityHandle identity_handle, DDS_Security_SecurityException *ex) { - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - SecurityObject *obj; - HandshakeInfo *handshake; + dds_security_authentication_impl *impl = (dds_security_authentication_impl *)instance; + SecurityObject *obj; + LocalIdentityInfo *localIdent; + RemoteIdentityInfo *remoteIdent; - /* validate provided arguments */ - if (!instance || !handshake_handle) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid parameter provided"); - goto err_bad_param; - } - - ddsrt_mutex_lock(&impl->lock); - obj = security_object_find(impl->objectHash, handshake_handle); - if (!obj || !security_object_valid(obj, SECURITY_OBJECT_KIND_HANDSHAKE)) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_handshake_handle: Invalid handle provided"); - goto err_invalid_handle; - } - handshake = (HandshakeInfo *)obj; - - assert(handshake->relation); + if (!instance || !identity_handle) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_identity_handle: Invalid parameter provided"); + goto err_bad_param; + } + /* Currently the implementation of the handle does not provide information about the kind of handle. In this case a valid handle could refer to a LocalIdentityObject or a RemoteIdentityObject */ + ddsrt_mutex_lock(&impl->lock); + if (!(obj = security_object_find(impl->objectHash, identity_handle))) + { + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_identity_handle: Invalid handle provided"); + goto failed; + } + switch (obj->kind) + { + case SECURITY_OBJECT_KIND_LOCAL_IDENTITY: + localIdent = (LocalIdentityInfo *)obj; + invalidate_local_related_objects(impl, localIdent); (void)ddsrt_hh_remove(impl->objectHash, obj); - security_object_free((SecurityObject *)handshake); + security_object_free(obj); + break; + case SECURITY_OBJECT_KIND_REMOTE_IDENTITY: + remoteIdent = (RemoteIdentityInfo *)obj; + invalidate_remote_related_objects(impl, remoteIdent); + (void)ddsrt_hh_remove(impl->remoteGuidHash, remoteIdent); + (void)ddsrt_hh_remove(impl->objectHash, obj); + security_object_free(obj); + break; + default: + DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_identity_handle: Invalid handle provided"); + goto failed; + } + ddsrt_mutex_unlock(&impl->lock); + return true; - ddsrt_mutex_unlock(&impl->lock); - - return true; - -err_invalid_handle: - ddsrt_mutex_unlock(&impl->lock); +failed: + ddsrt_mutex_unlock(&impl->lock); err_bad_param: - return false; + return false; } - -static void -invalidate_local_related_objects( - dds_security_authentication_impl *impl, - LocalIdentityInfo *localIdent) +DDS_Security_boolean return_sharedsecret_handle(dds_security_authentication *instance, const DDS_Security_SharedSecretHandle sharedsecret_handle, DDS_Security_SecurityException *ex) { - struct ddsrt_hh_iter it; - SecurityObject *obj; - - for (obj = ddsrt_hh_iter_first(impl->objectHash, &it); obj != NULL; obj = ddsrt_hh_iter_next(&it)) { - if (obj->kind == SECURITY_OBJECT_KIND_REMOTE_IDENTITY) { - RemoteIdentityInfo *remoteIdent = (RemoteIdentityInfo *)obj; - IdentityRelation *relation; - HandshakeInfo *handshake; - - handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(localIdent), SECURITY_OBJECT_HANDLE(remoteIdent)); - if (handshake) { - (void)ddsrt_hh_remove(impl->objectHash, handshake); - security_object_free((SecurityObject *) handshake); - } - - relation = find_identity_relation(remoteIdent, SECURITY_OBJECT_HANDLE(localIdent)); - if (relation) { - remove_identity_relation(remoteIdent, relation); - } - } - } + DDSRT_UNUSED_ARG(sharedsecret_handle); + DDSRT_UNUSED_ARG(ex); + DDSRT_UNUSED_ARG(instance); + return true; } -static void -invalidate_remote_related_objects( - dds_security_authentication_impl *impl, - RemoteIdentityInfo *remoteIdentity) +int32_t init_authentication(const char *argument, void **context) { - struct ddsrt_hh_iter it; - IdentityRelation *relation; - HandshakeInfo *handshake; + DDSRT_UNUSED_ARG(argument); + dds_security_authentication_impl *authentication; - for (relation = ddsrt_hh_iter_first(remoteIdentity->linkHash, &it); relation != NULL; relation = ddsrt_hh_iter_next(&it)) { - handshake = find_handshake(impl, SECURITY_OBJECT_HANDLE(relation->localIdentity), SECURITY_OBJECT_HANDLE(remoteIdentity)); - if (handshake) { - (void)ddsrt_hh_remove(impl->objectHash, handshake); - security_object_free((SecurityObject *) handshake); - } + authentication = (dds_security_authentication_impl *)ddsrt_malloc(sizeof(dds_security_authentication_impl)); + memset(authentication, 0, sizeof(dds_security_authentication_impl)); - (void)ddsrt_hh_remove(remoteIdentity->linkHash, relation); - security_object_free((SecurityObject *) relation); - } -} + authentication->timed_callbacks = dds_security_timed_cb_new(); + authentication->dispatcher = dds_security_timed_dispatcher_new(authentication->timed_callbacks); -DDS_Security_boolean -return_identity_handle( - dds_security_authentication *instance, - const DDS_Security_IdentityHandle identity_handle, - DDS_Security_SecurityException *ex) -{ - DDS_Security_boolean result = true; - dds_security_authentication_impl *impl = (dds_security_authentication_impl *) instance; - SecurityObject *obj; - LocalIdentityInfo *localIdent; - RemoteIdentityInfo *remoteIdent; + authentication->base.validate_local_identity = &validate_local_identity; + authentication->base.get_identity_token = &get_identity_token; + authentication->base.get_identity_status_token = &get_identity_status_token; + authentication->base.set_permissions_credential_and_token = &set_permissions_credential_and_token; + authentication->base.validate_remote_identity = &validate_remote_identity; + authentication->base.begin_handshake_request = &begin_handshake_request; + authentication->base.begin_handshake_reply = &begin_handshake_reply; + authentication->base.process_handshake = &process_handshake; + authentication->base.get_shared_secret = &get_shared_secret; + authentication->base.get_authenticated_peer_credential_token = &get_authenticated_peer_credential_token; + authentication->base.set_listener = &set_listener; + authentication->base.return_identity_token = &return_identity_token; + authentication->base.return_identity_status_token = &return_identity_status_token; + authentication->base.return_authenticated_peer_credential_token = &return_authenticated_peer_credential_token; + authentication->base.return_handshake_handle = &return_handshake_handle; + authentication->base.return_identity_handle = &return_identity_handle; + authentication->base.return_sharedsecret_handle = &return_sharedsecret_handle; + ddsrt_mutex_init(&authentication->lock); + authentication->objectHash = ddsrt_hh_new(32, security_object_hash, security_object_equal); + authentication->remoteGuidHash = ddsrt_hh_new(32, remote_guid_hash, remote_guid_equal); + memset(&authentication->trustedCAList, 0, sizeof(X509Seq)); - /* validate provided arguments */ - if (!instance || !identity_handle) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_identity_handle: Invalid parameter provided"); - goto err_bad_param; - } + OpenSSL_add_all_algorithms(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); + ERR_load_BIO_strings(); + ERR_load_crypto_strings(); - /* Currently the implementation of the handle does not provide information - * about the kind of handle. In this case a valid handle could refer to a - * LocalIdentityObject or a RemoteIdentityObject - */ - - ddsrt_mutex_lock(&impl->lock); - - obj = security_object_find(impl->objectHash, identity_handle); - if (!obj) { - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_identity_handle: Invalid handle provided"); - goto err_invalid_handle; - } - - switch (obj->kind) { - case SECURITY_OBJECT_KIND_LOCAL_IDENTITY: - localIdent = (LocalIdentityInfo *) obj; - invalidate_local_related_objects(impl, localIdent); - (void)ddsrt_hh_remove(impl->objectHash, obj); - security_object_free(obj); - break; - case SECURITY_OBJECT_KIND_REMOTE_IDENTITY: - remoteIdent = (RemoteIdentityInfo *) obj; - invalidate_remote_related_objects(impl, remoteIdent); - (void)ddsrt_hh_remove(impl->remoteGuidHash, remoteIdent); - (void)ddsrt_hh_remove(impl->objectHash, obj); - security_object_free(obj); - break; - default: - DDS_Security_Exception_set(ex, DDS_AUTH_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, DDS_SECURITY_VALIDATION_FAILED, "return_identity_handle: Invalid handle provided"); - result = false; - break; - } - - ddsrt_mutex_unlock(&impl->lock); - - return result; - -err_invalid_handle: - ddsrt_mutex_unlock(&impl->lock); -err_bad_param: - return false; -} - -DDS_Security_boolean return_sharedsecret_handle( - dds_security_authentication *instance, - const DDS_Security_SharedSecretHandle sharedsecret_handle, - DDS_Security_SecurityException *ex) -{ - DDSRT_UNUSED_ARG(sharedsecret_handle); - DDSRT_UNUSED_ARG(ex); - DDSRT_UNUSED_ARG(instance); - - return true; -} - -int32_t -init_authentication( const char *argument, void **context) -{ - - dds_security_authentication_impl *authentication; - - DDSRT_UNUSED_ARG(argument); - - /* allocate implementation wrapper */ - authentication = (dds_security_authentication_impl*) ddsrt_malloc( - sizeof(dds_security_authentication_impl)); - memset(authentication, 0, sizeof(dds_security_authentication_impl)); - - /* assign dispatcher to be notified when a validity date ends */ - 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; - - authentication->base.get_identity_token = &get_identity_token; - - authentication->base.get_identity_status_token = &get_identity_status_token; - - authentication->base.set_permissions_credential_and_token = - &set_permissions_credential_and_token; - - authentication->base.validate_remote_identity = &validate_remote_identity; - - authentication->base.begin_handshake_request = &begin_handshake_request; - - authentication->base.begin_handshake_reply = &begin_handshake_reply; - - authentication->base.process_handshake = &process_handshake; - - authentication->base.get_shared_secret = &get_shared_secret; - - authentication->base.get_authenticated_peer_credential_token = - &get_authenticated_peer_credential_token; - - authentication->base.set_listener = &set_listener; - - authentication->base.return_identity_token = &return_identity_token; - - authentication->base.return_identity_status_token = - &return_identity_status_token; - - authentication->base.return_authenticated_peer_credential_token = - &return_authenticated_peer_credential_token; - - authentication->base.return_handshake_handle = &return_handshake_handle; - - authentication->base.return_identity_handle = &return_identity_handle; - - authentication->base.return_sharedsecret_handle = &return_sharedsecret_handle; - - ddsrt_mutex_init(&authentication->lock); - - authentication->objectHash = ddsrt_hh_new(32, security_object_hash, security_object_equal); - authentication->remoteGuidHash = ddsrt_hh_new(32, remote_guid_hash, remote_guid_equal); - - memset( &authentication->trustedCAList, 0, sizeof(X509Seq)); - - - /* Initialize openssl */ - OpenSSL_add_all_algorithms(); - OpenSSL_add_all_ciphers(); - OpenSSL_add_all_digests(); - ERR_load_BIO_strings(); - ERR_load_crypto_strings(); - - //return the instance - *context = authentication; - return 0; - -/* we can not get ddsrt_mutex_init result. So ignore the lines below */ -#if MUTEX_INIT_RESULT_IMPLEMENTED -err_mutex_failed: - ddsrt_free(authentication); - return -1; -#endif + *context = authentication; + return 0; } int32_t finalize_authentication(void *instance) { - dds_security_authentication_impl *authentication = instance; - - if( authentication ){ - ddsrt_mutex_lock(&authentication->lock); - - 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); - } - - if (authentication->objectHash) { - struct ddsrt_hh_iter it; - SecurityObject *obj; - for (obj = ddsrt_hh_iter_first(authentication->objectHash, &it); obj != NULL; obj = ddsrt_hh_iter_next(&it)) { - security_object_free(obj); - } - ddsrt_hh_free(authentication->objectHash); - } - - free_ca_list_contents(&(authentication->trustedCAList)); - - ddsrt_mutex_unlock(&authentication->lock); - - ddsrt_mutex_destroy(&authentication->lock); - - ddsrt_free((dds_security_authentication_impl*) instance); + dds_security_authentication_impl *authentication = instance; + if (authentication) + { + ddsrt_mutex_lock(&authentication->lock); + 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); + if (authentication->objectHash) + { + struct ddsrt_hh_iter it; + for (SecurityObject *obj = ddsrt_hh_iter_first(authentication->objectHash, &it); obj != NULL; obj = ddsrt_hh_iter_next(&it)) + security_object_free(obj); + ddsrt_hh_free(authentication->objectHash); } + free_ca_list_contents(&(authentication->trustedCAList)); + ddsrt_mutex_unlock(&authentication->lock); + ddsrt_mutex_destroy(&authentication->lock); + ddsrt_free((dds_security_authentication_impl *)instance); + } - RAND_cleanup(); - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); - REMOVE_THREAD_STATE(); - ERR_free_strings(); - - return 0; + RAND_cleanup(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + REMOVE_THREAD_STATE(); + ERR_free_strings(); + return 0; } diff --git a/src/security/builtin_plugins/authentication/src/authentication.h b/src/security/builtin_plugins/authentication/src/authentication.h index dcbcfd6..4e56a12 100644 --- a/src/security/builtin_plugins/authentication/src/authentication.h +++ b/src/security/builtin_plugins/authentication/src/authentication.h @@ -10,7 +10,6 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ - #ifndef SECURITY_BUILTIN_PLUGINS_AUTHENTICATION_H_ #define SECURITY_BUILTIN_PLUGINS_AUTHENTICATION_H_ @@ -18,129 +17,34 @@ #include "dds/security/dds_security_api.h" #include "dds/security/export.h" -SECURITY_EXPORT int32_t -init_authentication(const char *argument, void **context); - -SECURITY_EXPORT int32_t -finalize_authentication(void *context); - - - - -DDS_Security_ValidationResult_t -validate_local_identity( - dds_security_authentication *instance, - DDS_Security_IdentityHandle *local_identity_handle, - DDS_Security_GUID_t *adjusted_participant_guid, - const DDS_Security_DomainId domain_id, - const DDS_Security_Qos *participant_qos, - const DDS_Security_GUID_t *candidate_participant_guid, - - DDS_Security_SecurityException *ex); -DDS_Security_boolean -get_identity_token(dds_security_authentication *instance, - DDS_Security_IdentityToken *identity_token, - const DDS_Security_IdentityHandle handle, - DDS_Security_SecurityException *ex); -DDS_Security_boolean -set_permissions_credential_and_token( - dds_security_authentication *instance, - const DDS_Security_IdentityHandle handle, - const DDS_Security_PermissionsCredentialToken *permissions_credential, - const DDS_Security_PermissionsToken *permissions_token, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -validate_remote_identity( - dds_security_authentication *instance, - DDS_Security_IdentityHandle *remote_identity_handle, - DDS_Security_AuthRequestMessageToken *local_auth_request_token, - const DDS_Security_AuthRequestMessageToken *remote_auth_request_token, - const DDS_Security_IdentityHandle local_identity_handle, - const DDS_Security_IdentityToken *remote_identity_token, - const DDS_Security_GUID_t *remote_participant_guid, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -begin_handshake_request( - dds_security_authentication *instance, - DDS_Security_HandshakeHandle *handshake_handle, - DDS_Security_HandshakeMessageToken *handshake_message, - const DDS_Security_IdentityHandle initiator_identity_handle, - const DDS_Security_IdentityHandle replier_identity_handle, - const DDS_Security_OctetSeq *serialized_local_participant_data, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -begin_handshake_reply( - dds_security_authentication *instance, - DDS_Security_HandshakeHandle *handshake_handle, - DDS_Security_HandshakeMessageToken *handshake_message_out, - const DDS_Security_HandshakeMessageToken *handshake_message_in, - const DDS_Security_IdentityHandle initiator_identity_handle, - const DDS_Security_IdentityHandle replier_identity_handle, - const DDS_Security_OctetSeq *serialized_local_participant_data, - DDS_Security_SecurityException *ex); - -DDS_Security_ValidationResult_t -process_handshake( - dds_security_authentication *instance, - DDS_Security_HandshakeMessageToken *handshake_message_out, - const DDS_Security_HandshakeMessageToken *handshake_message_in, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex); - -DDS_Security_SharedSecretHandle get_shared_secret( - dds_security_authentication *instance, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex); - -DDS_Security_boolean -get_authenticated_peer_credential_token( - dds_security_authentication *instance, - DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex); - - -DDS_Security_boolean get_identity_status_token( - dds_security_authentication *instance, - DDS_Security_IdentityStatusToken *identity_status_token, - const DDS_Security_IdentityHandle handle, - DDS_Security_SecurityException *ex); - -DDS_Security_boolean set_listener(dds_security_authentication *instance, - const dds_security_authentication_listener *listener, - DDS_Security_SecurityException *ex); - -DDS_Security_boolean return_identity_token(dds_security_authentication *instance, - const DDS_Security_IdentityToken *token, - DDS_Security_SecurityException *ex); - -DDS_Security_boolean return_identity_status_token( - dds_security_authentication *instance, - const DDS_Security_IdentityStatusToken *token, - DDS_Security_SecurityException *ex); - -DDS_Security_boolean return_authenticated_peer_credential_token( - dds_security_authentication *instance, - const DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, - DDS_Security_SecurityException *ex); - -DDS_Security_boolean -return_handshake_handle(dds_security_authentication *instance, - const DDS_Security_HandshakeHandle handshake_handle, - DDS_Security_SecurityException *ex); -DDS_Security_boolean -return_identity_handle( - dds_security_authentication *instance, - const DDS_Security_IdentityHandle identity_handle, - DDS_Security_SecurityException *ex); - -DDS_Security_boolean return_sharedsecret_handle( - dds_security_authentication *instance, - const DDS_Security_SharedSecretHandle sharedsecret_handle, - DDS_Security_SecurityException *ex); +SECURITY_EXPORT int32_t init_authentication(const char *argument, void **context); +SECURITY_EXPORT int32_t finalize_authentication(void *context); +DDS_Security_ValidationResult_t validate_local_identity(dds_security_authentication *instance, DDS_Security_IdentityHandle *local_identity_handle, DDS_Security_GUID_t *adjusted_participant_guid, + const DDS_Security_DomainId domain_id, const DDS_Security_Qos *participant_qos, const DDS_Security_GUID_t *candidate_participant_guid, DDS_Security_SecurityException *ex); +DDS_Security_boolean get_identity_token(dds_security_authentication *instance, DDS_Security_IdentityToken *identity_token, const DDS_Security_IdentityHandle handle, DDS_Security_SecurityException *ex); +DDS_Security_boolean set_permissions_credential_and_token(dds_security_authentication *instance, const DDS_Security_IdentityHandle handle, const DDS_Security_PermissionsCredentialToken *permissions_credential, + const DDS_Security_PermissionsToken *permissions_token, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t validate_remote_identity(dds_security_authentication *instance, DDS_Security_IdentityHandle *remote_identity_handle, DDS_Security_AuthRequestMessageToken *local_auth_request_token, + const DDS_Security_AuthRequestMessageToken *remote_auth_request_token, const DDS_Security_IdentityHandle local_identity_handle, const DDS_Security_IdentityToken *remote_identity_token, + const DDS_Security_GUID_t *remote_participant_guid, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t begin_handshake_request(dds_security_authentication *instance, DDS_Security_HandshakeHandle *handshake_handle, DDS_Security_HandshakeMessageToken *handshake_message, + const DDS_Security_IdentityHandle initiator_identity_handle, const DDS_Security_IdentityHandle replier_identity_handle, const DDS_Security_OctetSeq *serialized_local_participant_data, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t begin_handshake_reply(dds_security_authentication *instance, DDS_Security_HandshakeHandle *handshake_handle, DDS_Security_HandshakeMessageToken *handshake_message_out, + const DDS_Security_HandshakeMessageToken *handshake_message_in, const DDS_Security_IdentityHandle initiator_identity_handle, const DDS_Security_IdentityHandle replier_identity_handle, + const DDS_Security_OctetSeq *serialized_local_participant_data, DDS_Security_SecurityException *ex); +DDS_Security_ValidationResult_t process_handshake(dds_security_authentication *instance, DDS_Security_HandshakeMessageToken *handshake_message_out, const DDS_Security_HandshakeMessageToken *handshake_message_in, + const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex); +DDS_Security_SharedSecretHandle get_shared_secret(dds_security_authentication *instance, const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex); +DDS_Security_boolean get_authenticated_peer_credential_token(dds_security_authentication *instance, DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, + const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex); +DDS_Security_boolean get_identity_status_token(dds_security_authentication *instance, DDS_Security_IdentityStatusToken *identity_status_token, const DDS_Security_IdentityHandle handle, DDS_Security_SecurityException *ex); +DDS_Security_boolean set_listener(dds_security_authentication *instance, const dds_security_authentication_listener *listener, DDS_Security_SecurityException *ex); +DDS_Security_boolean return_identity_token(dds_security_authentication *instance, const DDS_Security_IdentityToken *token, DDS_Security_SecurityException *ex); +DDS_Security_boolean return_identity_status_token(dds_security_authentication *instance, const DDS_Security_IdentityStatusToken *token, DDS_Security_SecurityException *ex); +DDS_Security_boolean return_authenticated_peer_credential_token(dds_security_authentication *instance, const DDS_Security_AuthenticatedPeerCredentialToken *peer_credential_token, DDS_Security_SecurityException *ex); +DDS_Security_boolean return_handshake_handle(dds_security_authentication *instance, const DDS_Security_HandshakeHandle handshake_handle, DDS_Security_SecurityException *ex); +DDS_Security_boolean return_identity_handle(dds_security_authentication *instance, const DDS_Security_IdentityHandle identity_handle, DDS_Security_SecurityException *ex); +DDS_Security_boolean return_sharedsecret_handle(dds_security_authentication *instance, const DDS_Security_SharedSecretHandle sharedsecret_handle, DDS_Security_SecurityException *ex); #endif /* SECURITY_BUILTIN_PLUGINS_AUTHENTICATION_H_ */