DDS Security built-in Cryptographic plugin (#306)
* DDS Security built-in Cryptographic plugin This commit adds the built-in Cryptographic plugin that is part of the DDS Security implementation for Cyclone. The Cryptographic plugin defines the types and operations necessary to support encryption, digest, message authentication codes, and key exchange for DDS DomainParticipants, DataWriters and DDS DataReaders. Similar to other builtin plugins, the DDS Security cryptographic plugin is built as a shared library to allow dynamic library loading on runtime. This enables DDS participants to use specific plugin implementations with different configurations. Although I think this initial version is a reasonable starting point to be merged in the security branch, some parts of the code will need refactoring: * crypto_key_factory.c: crypto_factory_get_endpoint_relation returns arbitrary local-remote relation if no specific key for remote is found, which will not work in Cyclone because participants can have different security settings * performance of encoding data can be improved by not copying plain_rtps_message to a new buffer (to enable this, crypto_cipher_encrypt_data should allow encrypting parts of a message) * when decoding a message the message is split in several parts (header, body, footer, etc) and for this memory is allocated which is probably not necessary. Performance should be improved by removing these allocations and use pointers to the data instead. Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * WIP processing crypto plugin review comments Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * WIP more refactoring based on review comments Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * WIP fixing crypto plugin support for 128 bit key size Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * WIP refactored master key storage to reduce memory usage when using 128 bit keys Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * WIP fixing windows build linker issue Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * WIP refactored crypto key types, avoid returning pointers to released ref-counted object Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * Fixed bug in test decode_datareader_submessage.invalid_data Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com> * Fixed issues from review: use correct constant for hashing and handle different src/dst keysize correctly Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
This commit is contained in:
parent
37c64e0965
commit
30bd6e4c1c
54 changed files with 24804 additions and 272 deletions
|
@ -37,7 +37,8 @@ typedef enum {
|
|||
|
||||
#define DDS_SECURITY_HANDLE_NIL (0)
|
||||
|
||||
|
||||
#define DDS_SECURITY_SUCCESS (0)
|
||||
#define DDS_SECURITY_FAILED (-1)
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -45,30 +46,30 @@ typedef enum {
|
|||
* Attribute flags. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_PROTECTED (0x00000001 )
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (0x00000001 << 1)
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (0x00000001 << 2)
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID (0x00000001 << 31)
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_PROTECTED (1u )
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (1u << 1)
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (1u << 2)
|
||||
#define DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID (1u << 31)
|
||||
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED (0x00000001 )
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_DISCOVERY_ENCRYPTED (0x00000001 << 1)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED (0x00000001 << 2)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_AUTHENTICATED (0x00000001 << 3)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_DISCOVERY_AUTHENTICATED (0x00000001 << 4)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_LIVELINESS_AUTHENTICATED (0x00000001 << 5)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED (1u )
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_DISCOVERY_ENCRYPTED (1u << 1)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_LIVELINESS_ENCRYPTED (1u << 2)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_AUTHENTICATED (1u << 3)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_DISCOVERY_AUTHENTICATED (1u << 4)
|
||||
#define DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_LIVELINESS_AUTHENTICATED (1u << 5)
|
||||
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_READ_PROTECTED (0x00000001 )
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_WRITE_PROTECTED (0x00000001 << 1)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (0x00000001 << 2)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED (0x00000001 << 3)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED (0x00000001 << 4)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_KEY_PROTECTED (0x00000001 << 5)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (0x00000001 << 6)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_VALID (0x00000001 << 31)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_READ_PROTECTED (1u )
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_WRITE_PROTECTED (1u << 1)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_DISCOVERY_PROTECTED (1u << 2)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_PROTECTED (1u << 3)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_PROTECTED (1u << 4)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_KEY_PROTECTED (1u << 5)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_LIVELINESS_PROTECTED (1u << 6)
|
||||
#define DDS_SECURITY_ENDPOINT_ATTRIBUTES_FLAG_IS_VALID (1u << 31)
|
||||
|
||||
#define DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED (0x00000001 )
|
||||
#define DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED (0x00000001 << 1)
|
||||
#define DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED (0x00000001 << 2)
|
||||
#define DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED (1u )
|
||||
#define DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED (1u << 1)
|
||||
#define DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED (1u << 2)
|
||||
|
||||
|
||||
|
||||
|
@ -175,10 +176,12 @@ typedef enum {
|
|||
**************************************************************************/
|
||||
#define DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE 32
|
||||
|
||||
#define DDS_SECURITY_MASTER_SALT_SIZE 32
|
||||
#define DDS_SECURITY_MASTER_SENDER_KEY_SIZE 32
|
||||
#define DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE 32
|
||||
|
||||
#define DDS_SECURITY_MASTER_SALT_SIZE_128 16
|
||||
#define DDS_SECURITY_MASTER_SALT_SIZE_256 32
|
||||
#define DDS_SECURITY_MASTER_SENDER_KEY_SIZE_128 16
|
||||
#define DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256 32
|
||||
#define DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_128 16
|
||||
#define DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_256 32
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
|
|
|
@ -106,6 +106,8 @@ extern "C" {
|
|||
#define DDS_SECURITY_ERR_PERMISSIONS_OUT_OF_VALIDITY_DATE_MESSAGE "Permissions of subject (%s) outside validity date: %s - %s"
|
||||
#define DDS_SECURITY_ERR_URI_TYPE_NOT_SUPPORTED_CODE 151
|
||||
#define DDS_SECURITY_ERR_URI_TYPE_NOT_SUPPORTED_MESSAGE "Unsupported URI type: %s"
|
||||
#define DDS_SECURITY_ERR_INVALID_CRYPTO_DATA_NOT_ALIGNED_CODE 152
|
||||
#define DDS_SECURITY_ERR_INVALID_CRYPTO_DATA_NOT_ALIGNED_MESSAGE "The payload is not aligned at 4 bytes"
|
||||
|
||||
#define DDS_SECURITY_ERR_UNDEFINED_CODE 200
|
||||
#define DDS_SECURITY_ERR_UNDEFINED_MESSAGE "Undefined Error Message"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/authentication")
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/cryptographic")
|
||||
|
||||
# TODO: improve test inclusion.
|
||||
if((BUILD_TESTING) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800")))
|
||||
|
|
|
@ -1687,7 +1687,7 @@ validate_pdata(
|
|||
|
||||
pdata = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
|
||||
if (!DDD_Security_Deserialize_ParticipantBuiltinTopicData(deserializer, pdata, ex)) {
|
||||
if (!DDS_Security_Deserialize_ParticipantBuiltinTopicData(deserializer, pdata, ex)) {
|
||||
result = DDS_SECURITY_VALIDATION_FAILED;
|
||||
goto err_incorrect_data;
|
||||
}
|
||||
|
@ -1696,7 +1696,7 @@ validate_pdata(
|
|||
result = get_adjusted_participant_guid(cert, &cguid, &aguid, ex);
|
||||
if (result == DDS_SECURITY_VALIDATION_OK) {
|
||||
DDS_Security_BuiltinTopicKey_t key;
|
||||
DDD_Security_BuiltinTopicKeyBE(key, pdata->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,
|
||||
|
|
58
src/security/builtin_plugins/cryptographic/CMakeLists.txt
Normal file
58
src/security/builtin_plugins/cryptographic/CMakeLists.txt
Normal file
|
@ -0,0 +1,58 @@
|
|||
#
|
||||
# Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the Eclipse Public License v. 2.0 which is available at
|
||||
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
# v. 1.0 which is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
#
|
||||
include (GenerateExportHeader)
|
||||
|
||||
find_package(OpenSSL)
|
||||
|
||||
PREPEND(srcs_cryptographic "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||
crypto_cipher.c
|
||||
crypto_key_exchange
|
||||
crypto_key_factory.c
|
||||
crypto_objects.c
|
||||
crypto_transform.c
|
||||
crypto_utils.c
|
||||
cryptography.c
|
||||
)
|
||||
|
||||
add_library(dds_security_crypto SHARED "")
|
||||
|
||||
generate_export_header(
|
||||
dds_security_crypto
|
||||
BASE_NAME SECURITY
|
||||
EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/security/export.h"
|
||||
)
|
||||
|
||||
add_definitions(-DDDSI_INCLUDE_SSL)
|
||||
|
||||
target_link_libraries(dds_security_crypto PUBLIC ddsc)
|
||||
target_link_libraries(dds_security_crypto PUBLIC OpenSSL::SSL)
|
||||
|
||||
target_sources(dds_security_crypto
|
||||
PRIVATE
|
||||
${srcs_cryptographic}
|
||||
)
|
||||
|
||||
target_include_directories(dds_security_crypto
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:$<TARGET_PROPERTY:security_api,INTERFACE_INCLUDE_DIRECTORIES>>"
|
||||
"$<BUILD_INTERFACE:$<TARGET_PROPERTY:security_core,INTERFACE_INCLUDE_DIRECTORIES>>"
|
||||
"$<BUILD_INTERFACE:$<TARGET_PROPERTY:ddsrt,INTERFACE_INCLUDE_DIRECTORIES>>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
EXPORT "${PROJECT_NAME}"
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lib
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
|
||||
)
|
258
src/security/builtin_plugins/cryptographic/src/crypto_cipher.c
Normal file
258
src/security/builtin_plugins/cryptographic/src/crypto_cipher.c
Normal file
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "crypto_defs.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "crypto_cipher.h"
|
||||
|
||||
bool crypto_cipher_encrypt_data(
|
||||
const crypto_session_key_t *session_key,
|
||||
uint32_t key_size,
|
||||
const unsigned char *iv,
|
||||
const unsigned char *data,
|
||||
uint32_t data_len,
|
||||
const unsigned char *aad,
|
||||
uint32_t aad_len,
|
||||
unsigned char *encrypted,
|
||||
uint32_t *encrypted_len,
|
||||
crypto_hmac_t *tag,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int len = 0;
|
||||
|
||||
/* create the cipher context */
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx)
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_CIPHER_CTX_new failed: ");
|
||||
goto fail_ctx_new;
|
||||
}
|
||||
|
||||
/* initialize the cipher and set to AES GCM */
|
||||
if (key_size == 128)
|
||||
{
|
||||
if (!EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptInit_ex to set aes_128_gcm failed: ");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
}
|
||||
else if (key_size == 256)
|
||||
{
|
||||
if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptInit_ex to set aes_256_gcm failed: ");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptInit_ex invalid key size: %u", key_size);
|
||||
goto fail_encrypt;
|
||||
}
|
||||
|
||||
/* Initialise key and IV */
|
||||
if (!EVP_EncryptInit_ex(ctx, NULL, NULL, session_key->data, iv))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptInit_ex failed: ");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
|
||||
if (aad)
|
||||
{
|
||||
if (aad_len > INT_MAX)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptUpdate to update aad failed: aad_len exceeds INT_MAX");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
|
||||
/* Provide any AAD data */
|
||||
if (!EVP_EncryptUpdate(ctx, NULL, &len, aad, (int) aad_len))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptUpdate to update aad failed: %s");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
if (data_len > INT_MAX)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptUpdate to update data failed: data_len exceeds INT_MAX");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
|
||||
/* encrypt the message */
|
||||
if (!EVP_EncryptUpdate(ctx, encrypted, &len, data, (int) data_len))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptUpdate update data failed: ");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
assert (len >= 0); /* conform openssl spec */
|
||||
*encrypted_len = (uint32_t) len;
|
||||
}
|
||||
|
||||
/* finalize the encryption */
|
||||
if (data)
|
||||
{
|
||||
if (!EVP_EncryptFinal_ex(ctx, encrypted + len, &len))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptFinal_ex to finalize encryption failed: ");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
assert (len >= 0); /* conform openssl spec */
|
||||
*encrypted_len += (uint32_t) len;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char temp[32];
|
||||
if (!EVP_EncryptFinal_ex(ctx, temp, &len))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_EncryptFinal_ex to finalize aad failed: ");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the tag */
|
||||
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, CRYPTO_HMAC_SIZE, tag->data))
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_CIPHER_CTX_ctrl to get the tag failed: ");
|
||||
goto fail_encrypt;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return true;
|
||||
|
||||
fail_encrypt:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
fail_ctx_new:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool crypto_cipher_decrypt_data(
|
||||
const remote_session_info *session,
|
||||
const unsigned char *iv,
|
||||
const unsigned char *encrypted,
|
||||
uint32_t encrypted_len,
|
||||
const unsigned char *aad,
|
||||
uint32_t aad_len,
|
||||
unsigned char *data,
|
||||
uint32_t *data_len,
|
||||
crypto_hmac_t *tag,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int len = 0;
|
||||
|
||||
/* create the cipher context */
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx)
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_CIPHER_CTX_new failed: ");
|
||||
goto fail_ctx_new;
|
||||
}
|
||||
|
||||
/* initialize the cipher and set to AES GCM */
|
||||
if (session->key_size == 128)
|
||||
{
|
||||
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_DecryptInit_ex to set aes_128_gcm failed: ");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
}
|
||||
else if (session->key_size == 256)
|
||||
{
|
||||
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_DecryptInit_ex to set aes_256_gcm failed: ");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "Internal key_size is not correct: %u", session->key_size);
|
||||
goto fail_decrypt;
|
||||
}
|
||||
|
||||
/* Initialise key and IV */
|
||||
if (EVP_DecryptInit_ex(ctx, NULL, NULL, session->key.data, iv) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_DecryptInit_ex to set aes_256_gcm failed: %s");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
|
||||
if (aad)
|
||||
{
|
||||
assert (aad_len <= INT32_MAX);
|
||||
/* Provide any AAD data for signature */
|
||||
if (EVP_DecryptUpdate(ctx, NULL, &len, aad, (int) aad_len) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_DecryptUpdate to update aad failed: ");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set expected tag value. */
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, CRYPTO_HMAC_SIZE, tag->data) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_CIPHER_CTX_ctrl to get tag failed: ");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
/* decrypt the message */
|
||||
if (EVP_DecryptUpdate(ctx, data, &len, encrypted, (int) encrypted_len) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_DecryptUpdate update data failed: ");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
assert (len >= 0);
|
||||
*data_len = (uint32_t)len;
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
if (EVP_DecryptFinal_ex(ctx, data + len, &len) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_DecryptFinal_ex to finalize decryption failed: ");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
assert (len >= 0);
|
||||
*data_len += (uint32_t)len;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char temp[32];
|
||||
if (EVP_DecryptFinal_ex(ctx, temp, &len) != 1)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "EVP_DecryptFinal_ex to finalize signature check failed: ");
|
||||
goto fail_decrypt;
|
||||
}
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return true;
|
||||
|
||||
fail_decrypt:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
fail_ctx_new:
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTO_CIPHER_H
|
||||
#define CRYPTO_CIPHER_H
|
||||
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
/**
|
||||
* @brief Encodes the provide data using the provided key
|
||||
*
|
||||
* This function encodes the provide data using the provided key, key_size
|
||||
* and initialization_vector. It also computes the common_mac from the provided data.
|
||||
* The data parameter contains the data that has to encoded. The aad parameter contains
|
||||
* the data that is not encoded but is used in the computation of the common_mac
|
||||
* On return the encrypted parameter contains the encoded data and the tag parameter
|
||||
* the common mac.
|
||||
* This function will be used either to encode the provided data in that case the
|
||||
* data parameter should be set to the data to be encoded and the aad parameter should
|
||||
* be NULL. Also the encrypted parameter should be set and contain a buffer large enough
|
||||
* to contain the encoded data.
|
||||
* This function is also used to only computer the common_mac. In that case the
|
||||
* data parameter should be NULL and the aad parameter should point to the data on
|
||||
* which the common_mac has to be computed. The encryped parameter is not relevant
|
||||
* in this case.
|
||||
*
|
||||
* @param[in] session_key The session key used to encode the provided data
|
||||
* @param[in] key_size The size of the session key (128 or 256 bit)
|
||||
* @param[in] iv The init vector used by the encoding
|
||||
* @param[in] data The data to be encoded
|
||||
* @param[in] data_len The size of the data to be encoded
|
||||
* @param[in] aad The additional data not be encoded but only used in the computation of the mac
|
||||
* @param[in] aad_len The size of the additional data
|
||||
* @param[in,out] encrypted The buffer to hold on return the encoded data
|
||||
* @param[in,out] encrypted_len The size of the encrypted data buffer
|
||||
* @param[in,out] tag Contains on return the mac value calculated over the provided data
|
||||
* @param[in,out] ex Security exception (optional)
|
||||
*/
|
||||
bool crypto_cipher_encrypt_data(
|
||||
const crypto_session_key_t *session_key,
|
||||
uint32_t key_size,
|
||||
const unsigned char *iv,
|
||||
const unsigned char *data,
|
||||
uint32_t data_len,
|
||||
const unsigned char *aad,
|
||||
uint32_t aad_len,
|
||||
unsigned char *encrypted,
|
||||
uint32_t *encrypted_len,
|
||||
crypto_hmac_t *tag,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
/**
|
||||
* @brief Decodes the provided data using the session key and key_size
|
||||
*
|
||||
* This function decodes the provided data using the session key and key_size provided
|
||||
* by by the session parameter. The iv parameter contains the initialization_vector used
|
||||
* by the decode operation which is the concatination of received session_id and init_vector_suffix.
|
||||
* The function checks if the common_mac (tag parameter) is corresponds with the provided data.
|
||||
* This function will be used either to decode the provided data in that case the
|
||||
* encrypted parameter should be set to the data to be decoded and the aad parameter should
|
||||
* be NULL. Also the data parameter should be set and contain a buffer large enough
|
||||
* to contain the decoded data.
|
||||
* This function is also used to only verify the common_mac. In that case the
|
||||
* data and the encrypted parameter should be NULL and the aad parameter should point to
|
||||
* the data for which the common_mac has to be verified.
|
||||
*
|
||||
* @param[in] session Contains the session key and key size used of the decoding
|
||||
* @param[in] iv The init vector used by the decoding
|
||||
* @param[in] encrypted The encoded data
|
||||
* @param[in] encrypted_len The size of the encoded data
|
||||
* @param[in] aad The not encoded data used in the verification of the provided mac
|
||||
* @param[in] aad_len The size of the additional data
|
||||
* @param[in,out] data The buffer to hold on return the decoded data
|
||||
* @param[in,out] data_len The size of the decoded data buffer
|
||||
* @param[in,out] tag The mac value which has to be verified
|
||||
* @param[in,out] ex Security exception (optional)
|
||||
*/
|
||||
bool crypto_cipher_decrypt_data(
|
||||
const remote_session_info *session,
|
||||
const unsigned char *iv,
|
||||
const unsigned char *encrypted,
|
||||
uint32_t encrypted_len,
|
||||
const unsigned char *aad,
|
||||
uint32_t aad_len,
|
||||
unsigned char *data,
|
||||
uint32_t *data_len,
|
||||
crypto_hmac_t *tag,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
#endif /* CRYPTO_CIPHER_H */
|
114
src/security/builtin_plugins/cryptographic/src/crypto_defs.h
Normal file
114
src/security/builtin_plugins/cryptographic/src/crypto_defs.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTO_DEFS_H
|
||||
#define CRYPTO_DEFS_H
|
||||
|
||||
#include "dds/security/dds_security_api.h"
|
||||
|
||||
#define DDS_CRYPTO_PLUGIN_CONTEXT "Cryptographic"
|
||||
|
||||
#define CRYPTO_HMAC_SIZE 16
|
||||
#define CRYPTO_KEY_SIZE_128 16
|
||||
#define CRYPTO_KEY_SIZE_256 32
|
||||
#define CRYPTO_KEY_SIZE_MAX CRYPTO_KEY_SIZE_256
|
||||
|
||||
#define CRYPTO_SESSION_ID_SIZE 4
|
||||
#define CRYPTO_INIT_VECTOR_SUFFIX_SIZE 8
|
||||
#define CRYPTO_CIPHER_BLOCK_SIZE 16
|
||||
|
||||
typedef enum SecureSubmsgKind_t
|
||||
{
|
||||
SMID_SEC_BODY_KIND = 0x30,
|
||||
SMID_SEC_PREFIX_KIND = 0x31,
|
||||
SMID_SEC_POSTFIX_KIND = 0x32,
|
||||
SMID_SRTPS_PREFIX_KIND = 0x33,
|
||||
SMID_SRTPS_POSTFIX_KIND = 0x34,
|
||||
SMID_SRTPS_INFO_SRC_KIND = 0x0c
|
||||
} SecureSubmsgKind_t;
|
||||
|
||||
typedef struct crypto_session_key_t
|
||||
{
|
||||
unsigned char data[CRYPTO_KEY_SIZE_MAX];
|
||||
} crypto_session_key_t;
|
||||
|
||||
typedef struct crypto_hmac_t
|
||||
{
|
||||
unsigned char data[CRYPTO_HMAC_SIZE];
|
||||
} crypto_hmac_t;
|
||||
|
||||
typedef enum RTPS_Message_Type
|
||||
{
|
||||
/** The Constant PAD. */
|
||||
RTPS_Message_Type_PAD = 0x01,
|
||||
|
||||
/** The Constant ACKNACK. */
|
||||
RTPS_Message_Type_ACKNACK = 0x06,
|
||||
|
||||
/** The Constant HEARTBEAT. */
|
||||
RTPS_Message_Type_HEARTBEAT = 0x07,
|
||||
|
||||
/** The Constant GAP. */
|
||||
RTPS_Message_Type_GAP = 0x08,
|
||||
|
||||
/** The Constant INFO_TS. */
|
||||
RTPS_Message_Type_INFO_TS = 0x09,
|
||||
|
||||
/** The Constant INFO_SRC. */
|
||||
RTPS_Message_Type_INFO_SRC = 0x0c,
|
||||
|
||||
/** The Constant INFO_REPLY_IP4. */
|
||||
RTPS_Message_Type_INFO_REPLY_IP4 = 0x0d,
|
||||
|
||||
/** The Constant INFO_DST. */
|
||||
RTPS_Message_Type_INFO_DST = 0x0e,
|
||||
|
||||
/** The Constant INFO_REPLY. */
|
||||
RTPS_Message_Type_INFO_REPLY = 0x0f,
|
||||
|
||||
/** The Constant NACK_FRAG. */
|
||||
RTPS_Message_Type_NACK_FRAG = 0x12,
|
||||
|
||||
/** The Constant HEARTBEAT_FRAG. */
|
||||
RTPS_Message_Type_HEARTBEAT_FRAG = 0x13,
|
||||
|
||||
/** The Constant DATA. */
|
||||
RTPS_Message_Type_DATA = 0x15,
|
||||
|
||||
/** The Constant DATA_FRAG. */
|
||||
RTPS_Message_Type_DATA_FRAG = 0x16,
|
||||
|
||||
/** The Constant MSG_LENGTH. */
|
||||
RTPS_Message_Type_MSG_LEN = 0x81,
|
||||
|
||||
/** The Constant MSG_ENTITY_ID. */
|
||||
RTPS_Message_Type_MSG_ENTITY_ID = 0x82,
|
||||
|
||||
/** The Constant INFO_LASTHB. */
|
||||
RTPS_Message_Type_INFO_LASTHB = 0x83,
|
||||
|
||||
/** The Constant SEC_PREFIX. */
|
||||
RTPS_Message_Type_SEC_BODY = 0x30,
|
||||
|
||||
/** The Constant SEC_PREFIX. */
|
||||
RTPS_Message_Type_SEC_PREFIX = 0x31,
|
||||
|
||||
/** The Constant SEC_POSTFIX. */
|
||||
RTPS_Message_Type_SEC_POSTFIX = 0x32,
|
||||
|
||||
/** The Constant SRTPS_PREFIX. */
|
||||
RTPS_Message_Type_SRTPS_PREFIX = 0x33,
|
||||
|
||||
/** The Constant SRTPS_POSTFIX. */
|
||||
RTPS_Message_Type_SRTPS_POSTFIX = 0x34
|
||||
} RTPS_Message_Type;
|
||||
|
||||
#endif /* CRYPTO_DEFS_H */
|
|
@ -0,0 +1,538 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "crypto_defs.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "cryptography.h"
|
||||
#include "crypto_key_exchange.h"
|
||||
#include "crypto_key_factory.h"
|
||||
|
||||
static const char *CRYPTO_TOKEN_CLASS_ID = "DDS:Crypto:AES_GCM_GMAC";
|
||||
static const char *CRYPTO_TOKEN_PROPERTY_NAME = "dds.cryp.keymat";
|
||||
|
||||
/**
|
||||
* Implementation structure for storing encapsulated members of the instance
|
||||
* while giving only the interface definition to user
|
||||
*/
|
||||
|
||||
typedef struct dds_security_crypto_key_exchange_impl
|
||||
{
|
||||
dds_security_crypto_key_exchange base;
|
||||
const dds_security_cryptography *crypto;
|
||||
} dds_security_crypto_key_exchange_impl;
|
||||
|
||||
static bool check_crypto_tokens(const DDS_Security_DataHolderSeq *tokens)
|
||||
{
|
||||
bool status = true;
|
||||
uint32_t i;
|
||||
|
||||
if (tokens->_length == 0 || tokens->_buffer == NULL)
|
||||
status = false;
|
||||
|
||||
for (i = 0; status && (i < tokens->_length); i++)
|
||||
{
|
||||
status = (tokens->_buffer[i].class_id != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_CLASS_ID, tokens->_buffer[i].class_id) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._length == 1) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer != NULL) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].name != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_PROPERTY_NAME, tokens->_buffer[i].binary_properties._buffer[0].name) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._length > 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._buffer != NULL);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool check_not_data_empty(const DDS_Security_OctetSeq *seq)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < seq->_length; i++)
|
||||
{
|
||||
if (seq->_buffer[i] != 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_crypto_keymaterial(const DDS_Security_KeyMaterial_AES_GCM_GMAC *keymat)
|
||||
{
|
||||
bool status;
|
||||
|
||||
uint32_t transform_kind = CRYPTO_TRANSFORM_KIND(keymat->transformation_kind);
|
||||
uint32_t key_sz = CRYPTO_KEY_SIZE_BYTES(transform_kind);
|
||||
|
||||
status = (transform_kind >= CRYPTO_TRANSFORMATION_KIND_AES128_GMAC && transform_kind <= CRYPTO_TRANSFORMATION_KIND_AES256_GCM &&
|
||||
keymat->master_salt._length == key_sz && keymat->master_salt._buffer != NULL && check_not_data_empty(&keymat->master_salt) &&
|
||||
keymat->master_sender_key._length == key_sz && keymat->master_sender_key._buffer != NULL && check_not_data_empty(&keymat->master_sender_key));
|
||||
|
||||
if (status && CRYPTO_TRANSFORM_ID(keymat->receiver_specific_key_id))
|
||||
{
|
||||
status = (keymat->master_receiver_specific_key._length == key_sz &&
|
||||
keymat->master_receiver_specific_key._buffer != NULL && check_not_data_empty(&keymat->master_receiver_specific_key));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// serialized_key_material
|
||||
// {
|
||||
// uint32_t transformation_kind
|
||||
// uint32_t master_salt_len
|
||||
// uint8_t[SALT_SIZE] master_salt
|
||||
// uint32_t sender_key_id
|
||||
// uint32_t master_sender_key_len
|
||||
// uint8_t[KEY_SIZE] master_sender_key
|
||||
// uint32_t receiver_specific_key_id
|
||||
// uint32_t master_receiver_specific_key_len
|
||||
// uint8_t[KEY_SIZE] master_receiver_specific_key
|
||||
// }
|
||||
static void
|
||||
serialize_master_key_material(
|
||||
const master_key_material *keymat,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length)
|
||||
{
|
||||
uint32_t *sd;
|
||||
size_t i = 0;
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(keymat->transformation_kind);
|
||||
size_t sz = 6 * sizeof (uint32_t) + 2 * key_bytes;
|
||||
if (keymat->receiver_specific_key_id)
|
||||
sz += key_bytes;
|
||||
*buffer = ddsrt_malloc(sz);
|
||||
*length = (uint32_t)sz;
|
||||
sd = (uint32_t *)(*buffer);
|
||||
|
||||
sd[i++] = ddsrt_toBE4u(keymat->transformation_kind);
|
||||
sd[i++] = ddsrt_toBE4u(key_bytes);
|
||||
memcpy(&sd[i], keymat->master_salt, key_bytes);
|
||||
i += key_bytes / sizeof (uint32_t);
|
||||
sd[i++] = ddsrt_toBE4u(keymat->sender_key_id);
|
||||
sd[i++] = ddsrt_toBE4u(key_bytes);
|
||||
memcpy(&sd[i], keymat->master_sender_key, key_bytes);
|
||||
i += key_bytes / sizeof (uint32_t);
|
||||
sd[i++] = ddsrt_toBE4u(keymat->receiver_specific_key_id);
|
||||
if (keymat->receiver_specific_key_id)
|
||||
{
|
||||
sd[i++] = ddsrt_toBE4u(key_bytes);
|
||||
memcpy(&sd[i], keymat->master_receiver_specific_key, key_bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
sd[i++] = ddsrt_toBE4u(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function implementations
|
||||
*/
|
||||
static DDS_Security_boolean
|
||||
create_local_participant_crypto_tokens(
|
||||
dds_security_crypto_key_exchange *instance,
|
||||
DDS_Security_ParticipantCryptoTokenSeq *tokens,
|
||||
const DDS_Security_ParticipantCryptoHandle local_id,
|
||||
const DDS_Security_ParticipantCryptoHandle remote_id,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
dds_security_crypto_key_exchange_impl *impl = (dds_security_crypto_key_exchange_impl *)instance;
|
||||
dds_security_crypto_key_factory *factory;
|
||||
participant_key_material *pp_key_material;
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
|
||||
if (!instance || !tokens || local_id == 0 || remote_id == 0)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"create_local_participant_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
goto fail_invalid_arg;
|
||||
}
|
||||
|
||||
factory = cryptography_get_crypto_key_factory(impl->crypto);
|
||||
if (!crypto_factory_get_participant_crypto_tokens(factory, local_id, remote_id, &pp_key_material, NULL, ex))
|
||||
goto fail_invalid_arg;
|
||||
serialize_master_key_material(pp_key_material->local_P2P_key_material, &buffer, &length);
|
||||
CRYPTO_OBJECT_RELEASE(pp_key_material);
|
||||
|
||||
tokens->_buffer = DDS_Security_DataHolderSeq_allocbuf(1);
|
||||
tokens->_length = tokens->_maximum = 1;
|
||||
tokens->_buffer[0].class_id = ddsrt_strdup(CRYPTO_TOKEN_CLASS_ID);
|
||||
tokens->_buffer[0].binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1);
|
||||
tokens->_buffer[0].binary_properties._length = tokens->_buffer[0].binary_properties._maximum = 1;
|
||||
tokens->_buffer[0].binary_properties._buffer[0].name = ddsrt_strdup(CRYPTO_TOKEN_PROPERTY_NAME);
|
||||
tokens->_buffer[0].binary_properties._buffer[0].value._length =
|
||||
tokens->_buffer[0].binary_properties._buffer[0].value._maximum = length;
|
||||
tokens->_buffer[0].binary_properties._buffer[0].value._buffer = buffer;
|
||||
return true;
|
||||
|
||||
fail_invalid_arg:
|
||||
return false;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean
|
||||
set_remote_participant_crypto_tokens(
|
||||
dds_security_crypto_key_exchange *instance,
|
||||
const DDS_Security_ParticipantCryptoHandle local_id,
|
||||
const DDS_Security_ParticipantCryptoHandle remote_id,
|
||||
const DDS_Security_ParticipantCryptoTokenSeq *tokens,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
DDS_Security_boolean result = false;
|
||||
dds_security_crypto_key_exchange_impl *impl = (dds_security_crypto_key_exchange_impl *)instance;
|
||||
dds_security_crypto_key_factory *factory;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC remote_key_mat;
|
||||
const DDS_Security_OctetSeq *tdata;
|
||||
DDS_Security_Deserializer deserializer;
|
||||
|
||||
if (!instance || !tokens || local_id == 0 || remote_id == 0)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_participant_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_crypto_tokens(tokens))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_participant_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
tdata = &tokens->_buffer[0].binary_properties._buffer[0].value;
|
||||
|
||||
deserializer = DDS_Security_Deserializer_new(tdata->_buffer, tdata->_length);
|
||||
if (!deserializer)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_participant_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else if (!DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(deserializer, &remote_key_mat))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_participant_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else if (!check_crypto_keymaterial(&remote_key_mat))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_participant_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
factory = cryptography_get_crypto_key_factory(impl->crypto);
|
||||
result = crypto_factory_set_participant_crypto_tokens(factory, local_id, remote_id, &remote_key_mat, ex);
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&remote_key_mat);
|
||||
}
|
||||
|
||||
DDS_Security_Deserializer_free(deserializer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean
|
||||
create_local_datawriter_crypto_tokens(
|
||||
dds_security_crypto_key_exchange *instance,
|
||||
DDS_Security_DatawriterCryptoTokenSeq *tokens,
|
||||
const DDS_Security_DatawriterCryptoHandle local_writer_handle,
|
||||
const DDS_Security_DatareaderCryptoHandle remote_reader_handle,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
dds_security_crypto_key_exchange_impl *impl = (dds_security_crypto_key_exchange_impl *)instance;
|
||||
dds_security_crypto_key_factory *factory;
|
||||
master_key_material *key_mat[2];
|
||||
uint32_t num_key_mat = 2;
|
||||
uint32_t i;
|
||||
|
||||
if (!instance || !tokens || local_writer_handle == DDS_SECURITY_HANDLE_NIL || remote_reader_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"create_local_datawriter_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
factory = cryptography_get_crypto_key_factory(impl->crypto);
|
||||
|
||||
if (!crypto_factory_get_datawriter_crypto_tokens(factory, local_writer_handle, remote_reader_handle, key_mat, &num_key_mat, ex))
|
||||
return false;
|
||||
|
||||
tokens->_length = tokens->_maximum = num_key_mat;
|
||||
tokens->_buffer = (num_key_mat > 0) ? DDS_Security_DataHolderSeq_allocbuf(num_key_mat) : NULL;
|
||||
|
||||
for (i = 0; i < num_key_mat; i++)
|
||||
{
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
|
||||
serialize_master_key_material(key_mat[i], &buffer, &length);
|
||||
|
||||
tokens->_buffer[i].class_id = ddsrt_strdup(CRYPTO_TOKEN_CLASS_ID);
|
||||
tokens->_buffer[i].binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1);
|
||||
tokens->_buffer[i].binary_properties._length = tokens->_buffer[0].binary_properties._maximum = 1;
|
||||
tokens->_buffer[i].binary_properties._buffer[0].name = ddsrt_strdup(CRYPTO_TOKEN_PROPERTY_NAME);
|
||||
tokens->_buffer[i].binary_properties._buffer[0].value._length =
|
||||
tokens->_buffer[i].binary_properties._buffer[0].value._maximum = length;
|
||||
tokens->_buffer[i].binary_properties._buffer[0].value._buffer = buffer;
|
||||
CRYPTO_OBJECT_RELEASE(key_mat[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean
|
||||
set_remote_datawriter_crypto_tokens(
|
||||
dds_security_crypto_key_exchange *instance,
|
||||
const DDS_Security_DatareaderCryptoHandle local_reader_handle,
|
||||
const DDS_Security_DatawriterCryptoHandle remote_writer_handle,
|
||||
const DDS_Security_DatawriterCryptoTokenSeq *tokens,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
DDS_Security_boolean result = true;
|
||||
dds_security_crypto_key_exchange_impl *impl = (dds_security_crypto_key_exchange_impl *)instance;
|
||||
dds_security_crypto_key_factory *factory;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC remote_key_mat[2];
|
||||
uint32_t i;
|
||||
|
||||
if (!instance || !tokens || local_reader_handle == DDS_SECURITY_HANDLE_NIL || remote_writer_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_datawriter_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_crypto_tokens(tokens))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_datawriter_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tokens->_length > 2)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_datawriter_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; result && (i < tokens->_length); i++)
|
||||
{
|
||||
const DDS_Security_OctetSeq *tdata = &tokens->_buffer[i].binary_properties._buffer[0].value;
|
||||
DDS_Security_Deserializer deserializer = DDS_Security_Deserializer_new(tdata->_buffer, tdata->_length);
|
||||
if (!deserializer)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_datawriter_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else if (!DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(deserializer, &remote_key_mat[i]))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_datawriter_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else if (!check_crypto_keymaterial(&remote_key_mat[i]))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_datawriter_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
DDS_Security_Deserializer_free(deserializer);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
factory = cryptography_get_crypto_key_factory(impl->crypto);
|
||||
result = crypto_factory_set_datawriter_crypto_tokens(factory, local_reader_handle, remote_writer_handle, remote_key_mat, tokens->_length, ex);
|
||||
}
|
||||
|
||||
for (i = 0; i < tokens->_length; i++)
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&remote_key_mat[i]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean
|
||||
create_local_datareader_crypto_tokens(
|
||||
dds_security_crypto_key_exchange *instance,
|
||||
DDS_Security_DatareaderCryptoTokenSeq *tokens,
|
||||
const DDS_Security_DatareaderCryptoHandle local_reader_handle,
|
||||
const DDS_Security_DatawriterCryptoHandle remote_writer_handle,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
dds_security_crypto_key_exchange_impl *impl = (dds_security_crypto_key_exchange_impl *)instance;
|
||||
dds_security_crypto_key_factory *factory;
|
||||
master_key_material *key_mat = NULL;
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
|
||||
if (!instance || !tokens || local_reader_handle == DDS_SECURITY_HANDLE_NIL || remote_writer_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"create_local_datareader_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
factory = cryptography_get_crypto_key_factory(impl->crypto);
|
||||
|
||||
if (!crypto_factory_get_datareader_crypto_tokens(factory, local_reader_handle, remote_writer_handle, &key_mat, ex))
|
||||
return false;
|
||||
|
||||
if (key_mat != NULL)
|
||||
{ /* there may be no keymaterial according to configuration */
|
||||
|
||||
serialize_master_key_material(key_mat, &buffer, &length);
|
||||
|
||||
tokens->_buffer = DDS_Security_DataHolderSeq_allocbuf(1);
|
||||
tokens->_length = tokens->_maximum = 1;
|
||||
|
||||
tokens->_buffer[0].class_id = ddsrt_strdup(CRYPTO_TOKEN_CLASS_ID);
|
||||
tokens->_buffer[0].binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1);
|
||||
tokens->_buffer[0].binary_properties._length = tokens->_buffer[0].binary_properties._maximum = 1;
|
||||
tokens->_buffer[0].binary_properties._buffer[0].name = ddsrt_strdup(CRYPTO_TOKEN_PROPERTY_NAME);
|
||||
tokens->_buffer[0].binary_properties._buffer[0].value._length =
|
||||
tokens->_buffer[0].binary_properties._buffer[0].value._maximum = length;
|
||||
tokens->_buffer[0].binary_properties._buffer[0].value._buffer = buffer;
|
||||
|
||||
CRYPTO_OBJECT_RELEASE(key_mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
tokens->_buffer = NULL;
|
||||
tokens->_length = 0;
|
||||
tokens->_maximum = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean
|
||||
set_remote_datareader_crypto_tokens(
|
||||
dds_security_crypto_key_exchange *instance,
|
||||
const DDS_Security_DatawriterCryptoHandle local_writer_handle,
|
||||
const DDS_Security_DatareaderCryptoHandle remote_reader_handle,
|
||||
const DDS_Security_DatareaderCryptoTokenSeq *tokens,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
DDS_Security_boolean result = false;
|
||||
dds_security_crypto_key_exchange_impl *impl = (dds_security_crypto_key_exchange_impl *)instance;
|
||||
dds_security_crypto_key_factory *factory;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC remote_key_mat;
|
||||
const DDS_Security_OctetSeq *tdata;
|
||||
DDS_Security_Deserializer deserializer;
|
||||
|
||||
if (!instance || !tokens || local_writer_handle == DDS_SECURITY_HANDLE_NIL || remote_reader_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_datareader_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_crypto_tokens(tokens))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_datareader_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
tdata = &tokens->_buffer[0].binary_properties._buffer[0].value;
|
||||
|
||||
deserializer = DDS_Security_Deserializer_new(tdata->_buffer, tdata->_length);
|
||||
if (!deserializer)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_datareader_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else if (!DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(deserializer, &remote_key_mat))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_datareader_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else if (!check_crypto_keymaterial(&remote_key_mat))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_CODE, 0,
|
||||
"set_remote_datareader_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_TOKEN_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
factory = cryptography_get_crypto_key_factory(impl->crypto);
|
||||
result = crypto_factory_set_datareader_crypto_tokens(factory, local_writer_handle, remote_reader_handle, &remote_key_mat, ex);
|
||||
}
|
||||
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&remote_key_mat);
|
||||
|
||||
DDS_Security_Deserializer_free(deserializer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean
|
||||
return_crypto_tokens(
|
||||
dds_security_crypto_key_exchange *instance,
|
||||
DDS_Security_CryptoTokenSeq *tokens,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
dds_security_crypto_key_exchange_impl *impl = (dds_security_crypto_key_exchange_impl *)instance;
|
||||
|
||||
if (!impl || !tokens)
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"return_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
goto fail_invalid_arg;
|
||||
}
|
||||
|
||||
if (!check_crypto_tokens(tokens))
|
||||
{
|
||||
DDS_Security_Exception_set(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_CODE, 0,
|
||||
"set_remote_participant_crypto_tokens: " DDS_SECURITY_ERR_INVALID_CRYPTO_ARGUMENT_MESSAGE);
|
||||
goto fail_invalid_arg;
|
||||
}
|
||||
|
||||
DDS_Security_CryptoTokenSeq_freebuf(tokens);
|
||||
memset(tokens, 0, sizeof(*tokens));
|
||||
return true;
|
||||
|
||||
fail_invalid_arg:
|
||||
return false;
|
||||
}
|
||||
|
||||
dds_security_crypto_key_exchange *
|
||||
dds_security_crypto_key_exchange__alloc(
|
||||
const dds_security_cryptography *crypto)
|
||||
{
|
||||
dds_security_crypto_key_exchange_impl *instance = ddsrt_malloc(sizeof(*instance));
|
||||
instance->crypto = crypto;
|
||||
instance->base.create_local_participant_crypto_tokens = &create_local_participant_crypto_tokens;
|
||||
instance->base.set_remote_participant_crypto_tokens = &set_remote_participant_crypto_tokens;
|
||||
instance->base.create_local_datawriter_crypto_tokens = &create_local_datawriter_crypto_tokens;
|
||||
instance->base.set_remote_datawriter_crypto_tokens = &set_remote_datawriter_crypto_tokens;
|
||||
instance->base.create_local_datareader_crypto_tokens = &create_local_datareader_crypto_tokens;
|
||||
instance->base.set_remote_datareader_crypto_tokens = &set_remote_datareader_crypto_tokens;
|
||||
instance->base.return_crypto_tokens = &return_crypto_tokens;
|
||||
return (dds_security_crypto_key_exchange *)instance;
|
||||
}
|
||||
|
||||
void dds_security_crypto_key_exchange__dealloc(
|
||||
dds_security_crypto_key_exchange *instance)
|
||||
{
|
||||
ddsrt_free(instance);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTO_KEY_EXCHANGE_H
|
||||
#define CRYPTO_KEY_EXCHANGE_H
|
||||
|
||||
#include "dds/security/dds_security_api.h"
|
||||
|
||||
/**
|
||||
* @brief Allocation function for implementer structure (with internal variables) transparently.
|
||||
*/
|
||||
dds_security_crypto_key_exchange *
|
||||
dds_security_crypto_key_exchange__alloc(
|
||||
const dds_security_cryptography *crypto);
|
||||
|
||||
void dds_security_crypto_key_exchange__dealloc(
|
||||
dds_security_crypto_key_exchange *instance);
|
||||
|
||||
#endif /* CRYPTO_KEY_EXCHANGE_H */
|
1869
src/security/builtin_plugins/cryptographic/src/crypto_key_factory.c
Normal file
1869
src/security/builtin_plugins/cryptographic/src/crypto_key_factory.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTO_KEY_FACTORY_H
|
||||
#define CRYPTO_KEY_FACTORY_H
|
||||
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
/**
|
||||
* @brief Allocation function for implementer structure (with internal variables) transparently.
|
||||
*/
|
||||
dds_security_crypto_key_factory *
|
||||
dds_security_crypto_key_factory__alloc(
|
||||
const dds_security_cryptography *crypto);
|
||||
|
||||
void dds_security_crypto_key_factory__dealloc(
|
||||
dds_security_crypto_key_factory *instance);
|
||||
|
||||
int generate_key_pairs(
|
||||
char **private_key,
|
||||
char **public_key);
|
||||
|
||||
bool crypto_factory_get_participant_crypto_tokens(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
DDS_Security_ParticipantCryptoHandle local_id,
|
||||
DDS_Security_ParticipantCryptoHandle remote_id,
|
||||
participant_key_material **pp_key_material,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_set_participant_crypto_tokens(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_ParticipantCryptoHandle local_id,
|
||||
const DDS_Security_ParticipantCryptoHandle remote_id,
|
||||
const DDS_Security_KeyMaterial_AES_GCM_GMAC *remote_key_mat,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_datawriter_crypto_tokens(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
DDS_Security_DatawriterCryptoHandle local_writer_handle,
|
||||
DDS_Security_DatareaderCryptoHandle remote_reader_handle,
|
||||
master_key_material **key_mat,
|
||||
uint32_t *num_key_mat,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_set_datawriter_crypto_tokens(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatawriterCryptoHandle local_reader_handle,
|
||||
const DDS_Security_DatareaderCryptoHandle remote_writer_handle,
|
||||
const DDS_Security_KeyMaterial_AES_GCM_GMAC *key_mat,
|
||||
const uint32_t num_key_mat,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_datareader_crypto_tokens(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
DDS_Security_DatawriterCryptoHandle local_reader_handle,
|
||||
DDS_Security_DatareaderCryptoHandle remote_writer_handle,
|
||||
master_key_material **key_mat,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_set_datareader_crypto_tokens(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatawriterCryptoHandle local_writer_handle,
|
||||
const DDS_Security_DatareaderCryptoHandle remote_reader_handle,
|
||||
const DDS_Security_KeyMaterial_AES_GCM_GMAC *key_mat,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_writer_key_material(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatawriterCryptoHandle writer_id,
|
||||
const DDS_Security_DatareaderCryptoHandle reader_id,
|
||||
bool payload,
|
||||
session_key_material **session_key,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_reader_key_material(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatareaderCryptoHandle reader_id,
|
||||
const DDS_Security_DatawriterCryptoHandle writer_id,
|
||||
session_key_material **session_key,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_remote_writer_key_material(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatareaderCryptoHandle reader_id,
|
||||
const DDS_Security_DatawriterCryptoHandle writer_id,
|
||||
uint32_t key_id,
|
||||
master_key_material **master_key,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_BasicProtectionKind *basic_protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_local_participant_data_key_material(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_ParticipantCryptoHandle local_id,
|
||||
session_key_material **session_key,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_remote_reader_key_material(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatawriterCryptoHandle writer_id,
|
||||
const DDS_Security_DatareaderCryptoHandle reader_id,
|
||||
uint32_t key_id,
|
||||
master_key_material **master_key,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_remote_writer_sign_key_material(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatareaderCryptoHandle writer_id,
|
||||
master_key_material **key_material,
|
||||
session_key_material **session_key,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_remote_reader_sign_key_material(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
const DDS_Security_DatareaderCryptoHandle reader_id,
|
||||
master_key_material **key_material,
|
||||
session_key_material **session_key,
|
||||
DDS_Security_ProtectionKind *protection_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
bool crypto_factory_get_endpoint_relation(
|
||||
const dds_security_crypto_key_factory *factory,
|
||||
DDS_Security_ParticipantCryptoHandle local_participant_handle,
|
||||
DDS_Security_ParticipantCryptoHandle remote_participant_handle,
|
||||
uint32_t key_id,
|
||||
DDS_Security_Handle *remote_handle,
|
||||
DDS_Security_Handle *local_handle,
|
||||
DDS_Security_SecureSubmessageCategory_t *category,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
#endif /* CRYPTO_KEY_FACTORY_H */
|
593
src/security/builtin_plugins/cryptographic/src/crypto_objects.c
Normal file
593
src/security/builtin_plugins/cryptographic/src/crypto_objects.c
Normal file
|
@ -0,0 +1,593 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/hopscotch.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "crypto_objects.h"
|
||||
#include "crypto_utils.h"
|
||||
|
||||
bool crypto_object_valid(CryptoObject *obj, CryptoObjectKind_t kind)
|
||||
{
|
||||
return (obj && obj->kind == kind && obj->handle == (int64_t)(uintptr_t)obj);
|
||||
}
|
||||
|
||||
static uint32_t crypto_object_hash(const void *obj)
|
||||
{
|
||||
const CryptoObject *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 crypto_object_equal(const void *ha, const void *hb)
|
||||
{
|
||||
const CryptoObject *la = ha;
|
||||
const CryptoObject *lb = hb;
|
||||
return la->handle == lb->handle;
|
||||
}
|
||||
|
||||
void crypto_object_init(CryptoObject *obj, CryptoObjectKind_t kind, CryptoObjectDestructor destructor)
|
||||
{
|
||||
assert(obj);
|
||||
obj->kind = kind;
|
||||
obj->handle = (int64_t)(uintptr_t)obj;
|
||||
obj->destructor = destructor;
|
||||
ddsrt_atomic_st32 (&obj->refcount, 1);
|
||||
}
|
||||
|
||||
static void crypto_object_deinit(CryptoObject *obj)
|
||||
{
|
||||
assert(obj);
|
||||
obj->handle = DDS_SECURITY_HANDLE_NIL;
|
||||
obj->kind = CRYPTO_OBJECT_KIND_UNKNOWN;
|
||||
obj->destructor = NULL;
|
||||
}
|
||||
|
||||
void crypto_object_free(CryptoObject *obj)
|
||||
{
|
||||
if (obj && obj->destructor)
|
||||
obj->destructor(obj);
|
||||
}
|
||||
|
||||
CryptoObject * crypto_object_keep(CryptoObject *obj)
|
||||
{
|
||||
if (obj)
|
||||
ddsrt_atomic_inc32(&obj->refcount);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void crypto_object_release(CryptoObject *obj)
|
||||
{
|
||||
if (obj && ddsrt_atomic_dec32_nv(&obj->refcount) == 0)
|
||||
crypto_object_free(obj);
|
||||
}
|
||||
|
||||
static uint32_t participant_key_material_hash(const void *obj)
|
||||
{
|
||||
const participant_key_material *object = obj;
|
||||
return (uint32_t)object->pp_local_handle;
|
||||
}
|
||||
|
||||
static int participant_key_material_equal(const void *ha, const void *hb)
|
||||
{
|
||||
const participant_key_material *la = ha;
|
||||
const participant_key_material *lb = hb;
|
||||
return la->pp_local_handle == lb->pp_local_handle;
|
||||
}
|
||||
|
||||
static CryptoObject * participant_key_material_find(const struct CryptoObjectTable *table, const void *arg)
|
||||
{
|
||||
struct participant_key_material template;
|
||||
template.pp_local_handle = *(int64_t *)arg;
|
||||
return crypto_object_table_find_by_template(table, &template);
|
||||
}
|
||||
|
||||
CryptoObject * crypto_object_table_find_by_template(const struct CryptoObjectTable *table, const void *template)
|
||||
{
|
||||
return (CryptoObject *)ddsrt_hh_lookup(table->htab, template);
|
||||
}
|
||||
|
||||
static CryptoObject * default_crypto_table_find(const struct CryptoObjectTable *table, const void *arg)
|
||||
{
|
||||
struct CryptoObject template;
|
||||
template.handle = *(int64_t *)arg;
|
||||
return crypto_object_table_find_by_template(table, &template);
|
||||
}
|
||||
|
||||
struct CryptoObjectTable * crypto_object_table_new(CryptoObjectHashFunction hashfnc, CryptoObjectEqualFunction equalfnc, CryptoObjectFindFunction findfnc)
|
||||
{
|
||||
struct CryptoObjectTable *table;
|
||||
if (!hashfnc)
|
||||
hashfnc = crypto_object_hash;
|
||||
if (!equalfnc)
|
||||
equalfnc = crypto_object_equal;
|
||||
table = ddsrt_malloc(sizeof(*table));
|
||||
table->htab = ddsrt_hh_new(32, hashfnc, equalfnc);
|
||||
ddsrt_mutex_init(&table->lock);
|
||||
table->findfnc = findfnc ? findfnc : default_crypto_table_find;
|
||||
return table;
|
||||
}
|
||||
|
||||
void crypto_object_table_free(struct CryptoObjectTable *table)
|
||||
{
|
||||
struct ddsrt_hh_iter it;
|
||||
CryptoObject *obj;
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
ddsrt_mutex_lock(&table->lock);
|
||||
for (obj = ddsrt_hh_iter_first(table->htab, &it); obj; obj = ddsrt_hh_iter_next(&it))
|
||||
{
|
||||
ddsrt_hh_remove(table->htab, obj);
|
||||
crypto_object_release(obj);
|
||||
}
|
||||
ddsrt_hh_free(table->htab);
|
||||
ddsrt_mutex_unlock(&table->lock);
|
||||
ddsrt_mutex_destroy(&table->lock);
|
||||
ddsrt_free(table);
|
||||
}
|
||||
|
||||
CryptoObject * crypto_object_table_insert(struct CryptoObjectTable *table, CryptoObject *object)
|
||||
{
|
||||
CryptoObject *cur;
|
||||
|
||||
assert(table);
|
||||
assert(object);
|
||||
|
||||
ddsrt_mutex_lock(&table->lock);
|
||||
if (!(cur = crypto_object_keep (table->findfnc(table, &object->handle))))
|
||||
ddsrt_hh_add(table->htab, crypto_object_keep(object));
|
||||
else
|
||||
crypto_object_release(cur);
|
||||
ddsrt_mutex_unlock(&table->lock);
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
void crypto_object_table_remove_object(struct CryptoObjectTable *table, CryptoObject *object)
|
||||
{
|
||||
assert (table);
|
||||
assert (object);
|
||||
|
||||
ddsrt_mutex_lock (&table->lock);
|
||||
ddsrt_hh_remove (table->htab, object);
|
||||
ddsrt_mutex_unlock (&table->lock);
|
||||
|
||||
crypto_object_release (object);
|
||||
}
|
||||
|
||||
CryptoObject * crypto_object_table_remove(struct CryptoObjectTable *table, int64_t handle)
|
||||
{
|
||||
CryptoObject *object;
|
||||
assert (table);
|
||||
ddsrt_mutex_lock (&table->lock);
|
||||
if ((object = crypto_object_keep (table->findfnc(table, &handle))))
|
||||
{
|
||||
ddsrt_hh_remove (table->htab, object);
|
||||
crypto_object_release (object);
|
||||
}
|
||||
ddsrt_mutex_unlock (&table->lock);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
CryptoObject * crypto_object_table_find(struct CryptoObjectTable *table, int64_t handle)
|
||||
{
|
||||
CryptoObject *object;
|
||||
assert (table);
|
||||
ddsrt_mutex_lock (&table->lock);
|
||||
object = crypto_object_keep (table->findfnc(table, &handle));
|
||||
ddsrt_mutex_unlock (&table->lock);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void crypto_object_table_walk(struct CryptoObjectTable *table, CryptoObjectTableCallback callback, void *arg)
|
||||
{
|
||||
struct ddsrt_hh_iter it;
|
||||
CryptoObject *obj;
|
||||
int r = 1;
|
||||
|
||||
assert(table);
|
||||
assert(callback);
|
||||
ddsrt_mutex_lock (&table->lock);
|
||||
for (obj = ddsrt_hh_iter_first (table->htab, &it); r && obj; obj = ddsrt_hh_iter_next (&it))
|
||||
r = callback(obj, arg);
|
||||
ddsrt_mutex_unlock(&table->lock);
|
||||
}
|
||||
|
||||
static void master_key_material__free(CryptoObject *obj)
|
||||
{
|
||||
master_key_material *keymat = (master_key_material *)obj;
|
||||
if (obj)
|
||||
{
|
||||
CHECK_CRYPTO_OBJECT_KIND(obj, CRYPTO_OBJECT_KIND_KEY_MATERIAL);
|
||||
if (CRYPTO_TRANSFORM_HAS_KEYS(keymat->transformation_kind))
|
||||
{
|
||||
ddsrt_free (keymat->master_salt);
|
||||
ddsrt_free (keymat->master_sender_key);
|
||||
ddsrt_free (keymat->master_receiver_specific_key);
|
||||
}
|
||||
crypto_object_deinit ((CryptoObject *)keymat);
|
||||
memset (keymat, 0, sizeof (*keymat));
|
||||
ddsrt_free (keymat);
|
||||
}
|
||||
}
|
||||
|
||||
master_key_material * crypto_master_key_material_new(DDS_Security_CryptoTransformKind_Enum transform_kind)
|
||||
{
|
||||
master_key_material *keymat = ddsrt_calloc (1, sizeof(*keymat));
|
||||
crypto_object_init((CryptoObject *)keymat, CRYPTO_OBJECT_KIND_KEY_MATERIAL, master_key_material__free);
|
||||
keymat->transformation_kind = transform_kind;
|
||||
if (CRYPTO_TRANSFORM_HAS_KEYS(transform_kind))
|
||||
{
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(keymat->transformation_kind);
|
||||
keymat->master_salt = ddsrt_calloc(1, key_bytes);
|
||||
keymat->master_sender_key = ddsrt_calloc(1, key_bytes);
|
||||
keymat->master_receiver_specific_key = ddsrt_calloc(1, key_bytes);
|
||||
}
|
||||
return keymat;
|
||||
}
|
||||
|
||||
void crypto_master_key_material_set(master_key_material *dst, const master_key_material *src)
|
||||
{
|
||||
if (CRYPTO_TRANSFORM_HAS_KEYS(dst->transformation_kind) && !CRYPTO_TRANSFORM_HAS_KEYS(src->transformation_kind))
|
||||
{
|
||||
ddsrt_free(dst->master_salt);
|
||||
ddsrt_free(dst->master_sender_key);
|
||||
ddsrt_free(dst->master_receiver_specific_key);
|
||||
}
|
||||
else if (CRYPTO_TRANSFORM_HAS_KEYS(src->transformation_kind))
|
||||
{
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(src->transformation_kind);
|
||||
if (!CRYPTO_TRANSFORM_HAS_KEYS(dst->transformation_kind))
|
||||
{
|
||||
dst->master_salt = ddsrt_calloc(1, key_bytes);
|
||||
dst->master_sender_key = ddsrt_calloc(1, key_bytes);
|
||||
dst->master_receiver_specific_key = ddsrt_calloc(1, key_bytes);
|
||||
}
|
||||
memcpy (dst->master_salt, src->master_salt, key_bytes);
|
||||
dst->sender_key_id = src->sender_key_id;
|
||||
memcpy (dst->master_sender_key, src->master_sender_key, key_bytes);
|
||||
/* Fixme: set the receiver specific key? */
|
||||
dst->receiver_specific_key_id = 0;
|
||||
}
|
||||
dst->transformation_kind = src->transformation_kind;
|
||||
}
|
||||
|
||||
static bool generate_session_key(session_key_material *session, DDS_Security_SecurityException *ex)
|
||||
{
|
||||
session->id++;
|
||||
session->block_counter = 0;
|
||||
return crypto_calculate_session_key(&session->key, session->id, session->master_key_material->master_salt, session->master_key_material->master_sender_key, session->master_key_material->transformation_kind, ex);
|
||||
}
|
||||
|
||||
static void session_key_material__free(CryptoObject *obj)
|
||||
{
|
||||
session_key_material *session = (session_key_material *)obj;
|
||||
if (obj)
|
||||
{
|
||||
CHECK_CRYPTO_OBJECT_KIND(obj, CRYPTO_OBJECT_KIND_SESSION_KEY_MATERIAL);
|
||||
CRYPTO_OBJECT_RELEASE(session->master_key_material);
|
||||
crypto_object_deinit((CryptoObject *)session);
|
||||
memset (session, 0, sizeof (*session));
|
||||
ddsrt_free(session);
|
||||
}
|
||||
}
|
||||
|
||||
session_key_material * crypto_session_key_material_new(master_key_material *master_key)
|
||||
{
|
||||
session_key_material *session = ddsrt_malloc(sizeof(*session));
|
||||
crypto_object_init((CryptoObject *)session, CRYPTO_OBJECT_KIND_SESSION_KEY_MATERIAL, session_key_material__free);
|
||||
memset (session->key.data, 0, CRYPTO_KEY_SIZE_MAX);
|
||||
session->block_size = CRYPTO_CIPHER_BLOCK_SIZE;
|
||||
session->key_size = crypto_get_key_size(master_key->transformation_kind);
|
||||
session->id = crypto_get_random_uint32();
|
||||
session->init_vector_suffix = crypto_get_random_uint64();
|
||||
session->max_blocks_per_session = INT64_MAX; /* FIXME: should be a config parameter */
|
||||
session->block_counter = session->max_blocks_per_session;
|
||||
session->master_key_material = (master_key_material *)CRYPTO_OBJECT_KEEP(master_key);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
bool crypto_session_key_material_update(session_key_material *session, uint32_t size, DDS_Security_SecurityException *ex)
|
||||
{
|
||||
if (session->block_counter + (size / session->block_size) >= session->max_blocks_per_session)
|
||||
return generate_session_key(session, ex);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void local_participant_crypto__free(CryptoObject *obj)
|
||||
{
|
||||
local_participant_crypto *participant_crypto = (local_participant_crypto *)obj;
|
||||
if (participant_crypto)
|
||||
{
|
||||
CHECK_CRYPTO_OBJECT_KIND (obj, CRYPTO_OBJECT_KIND_LOCAL_CRYPTO);
|
||||
CRYPTO_OBJECT_RELEASE (participant_crypto->session);
|
||||
CRYPTO_OBJECT_RELEASE (participant_crypto->key_material);
|
||||
crypto_object_deinit ((CryptoObject *)participant_crypto);
|
||||
ddsrt_free (participant_crypto);
|
||||
}
|
||||
}
|
||||
|
||||
local_participant_crypto * crypto_local_participant_crypto__new(DDS_Security_IdentityHandle participant_identity)
|
||||
{
|
||||
assert (participant_identity);
|
||||
assert (sizeof(DDS_Security_ParticipantCryptoHandle) == 8);
|
||||
local_participant_crypto *participant_crypto = ddsrt_calloc (1, sizeof(*participant_crypto));
|
||||
participant_crypto->identity_handle = participant_identity;
|
||||
crypto_object_init ((CryptoObject *)participant_crypto, CRYPTO_OBJECT_KIND_LOCAL_CRYPTO, local_participant_crypto__free);
|
||||
return participant_crypto;
|
||||
}
|
||||
|
||||
static void remote_participant_crypto__free(CryptoObject *obj)
|
||||
{
|
||||
remote_participant_crypto *participant_crypto = (remote_participant_crypto *)obj;
|
||||
|
||||
CHECK_CRYPTO_OBJECT_KIND (obj, CRYPTO_OBJECT_KIND_REMOTE_CRYPTO);
|
||||
if (participant_crypto)
|
||||
{
|
||||
CRYPTO_OBJECT_RELEASE (participant_crypto->session);
|
||||
crypto_object_table_free (participant_crypto->key_material);
|
||||
crypto_object_deinit ((CryptoObject *)participant_crypto);
|
||||
ddsrt_free(participant_crypto);
|
||||
}
|
||||
}
|
||||
|
||||
remote_participant_crypto * crypto_remote_participant_crypto__new(DDS_Security_IdentityHandle participant_identity)
|
||||
{
|
||||
assert (participant_identity);
|
||||
remote_participant_crypto *participant_crypto = ddsrt_calloc (1, sizeof(*participant_crypto));
|
||||
crypto_object_init ((CryptoObject *)participant_crypto, CRYPTO_OBJECT_KIND_REMOTE_CRYPTO, remote_participant_crypto__free);
|
||||
participant_crypto->identity_handle = participant_identity;
|
||||
participant_crypto->key_material = crypto_object_table_new (participant_key_material_hash, participant_key_material_equal, participant_key_material_find);
|
||||
|
||||
return participant_crypto;
|
||||
}
|
||||
|
||||
|
||||
static void participant_key_material_free(CryptoObject *obj)
|
||||
{
|
||||
participant_key_material *keymaterial = (participant_key_material *)obj;
|
||||
CHECK_CRYPTO_OBJECT_KIND(obj, CRYPTO_OBJECT_KIND_PARTICIPANT_KEY_MATERIAL);
|
||||
if (keymaterial)
|
||||
{
|
||||
CRYPTO_OBJECT_RELEASE(keymaterial->P2P_writer_session);
|
||||
CRYPTO_OBJECT_RELEASE(keymaterial->P2P_reader_session);
|
||||
CRYPTO_OBJECT_RELEASE(keymaterial->P2P_kx_key_material);
|
||||
CRYPTO_OBJECT_RELEASE(keymaterial->local_P2P_key_material);
|
||||
CRYPTO_OBJECT_RELEASE(keymaterial->remote_key_material);
|
||||
crypto_object_table_free(keymaterial->endpoint_relations);
|
||||
crypto_object_deinit((CryptoObject *)keymaterial);
|
||||
ddsrt_free(keymaterial);
|
||||
}
|
||||
}
|
||||
|
||||
participant_key_material * crypto_participant_key_material_new(const local_participant_crypto *pplocal)
|
||||
{
|
||||
participant_key_material *keymaterial = ddsrt_calloc(1, sizeof(*keymaterial));
|
||||
crypto_object_init((CryptoObject *)keymaterial, CRYPTO_OBJECT_KIND_PARTICIPANT_KEY_MATERIAL, participant_key_material_free);
|
||||
keymaterial->pp_local_handle = pplocal->_parent.handle;
|
||||
keymaterial->endpoint_relations = crypto_object_table_new(NULL, NULL, NULL);
|
||||
keymaterial->local_P2P_key_material = crypto_master_key_material_new(CRYPTO_TRANSFORMATION_KIND_NONE);
|
||||
keymaterial->P2P_kx_key_material = crypto_master_key_material_new(CRYPTO_TRANSFORMATION_KIND_AES256_GCM); /* as defined in table 67 of the DDS Security spec v1.1 */
|
||||
|
||||
return keymaterial;
|
||||
}
|
||||
|
||||
static void endpoint_relation_free(CryptoObject *obj)
|
||||
{
|
||||
endpoint_relation *relation = (endpoint_relation *)obj;
|
||||
if (relation)
|
||||
{
|
||||
CRYPTO_OBJECT_RELEASE(relation->local_crypto);
|
||||
CRYPTO_OBJECT_RELEASE(relation->remote_crypto);
|
||||
crypto_object_deinit((CryptoObject *)relation);
|
||||
ddsrt_free(relation);
|
||||
}
|
||||
}
|
||||
|
||||
endpoint_relation * crypto_endpoint_relation_new(DDS_Security_SecureSubmessageCategory_t kind,
|
||||
uint32_t key_id, CryptoObject *local_crypto, CryptoObject *remote_crypto)
|
||||
{
|
||||
endpoint_relation *relation = ddsrt_malloc(sizeof(*relation));
|
||||
crypto_object_init((CryptoObject *)relation, CRYPTO_OBJECT_KIND_ENDPOINT_RELATION, endpoint_relation_free);
|
||||
|
||||
relation->kind = kind;
|
||||
relation->key_id = key_id;
|
||||
relation->local_crypto = CRYPTO_OBJECT_KEEP(local_crypto);
|
||||
relation->remote_crypto = CRYPTO_OBJECT_KEEP(remote_crypto);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
static void local_datawriter_crypto__free(CryptoObject *obj)
|
||||
{
|
||||
local_datawriter_crypto *datawriter_crypto = (local_datawriter_crypto *)obj;
|
||||
|
||||
if (obj)
|
||||
{
|
||||
CHECK_CRYPTO_OBJECT_KIND(obj, CRYPTO_OBJECT_KIND_LOCAL_WRITER_CRYPTO);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->writer_session_message);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->writer_session_payload);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->writer_key_material_message);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->writer_key_material_payload);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->participant);
|
||||
crypto_object_deinit((CryptoObject *)datawriter_crypto);
|
||||
ddsrt_free(datawriter_crypto);
|
||||
}
|
||||
}
|
||||
|
||||
local_datawriter_crypto * crypto_local_datawriter_crypto__new(const local_participant_crypto *participant,
|
||||
DDS_Security_ProtectionKind meta_protection, DDS_Security_BasicProtectionKind data_protection)
|
||||
{
|
||||
local_datawriter_crypto *writer_crypto = ddsrt_calloc(1, sizeof(*writer_crypto));
|
||||
crypto_object_init((CryptoObject *)writer_crypto, CRYPTO_OBJECT_KIND_LOCAL_WRITER_CRYPTO, local_datawriter_crypto__free);
|
||||
writer_crypto->participant = (local_participant_crypto *)CRYPTO_OBJECT_KEEP(participant);
|
||||
writer_crypto->metadata_protectionKind = meta_protection;
|
||||
writer_crypto->data_protectionKind = data_protection;
|
||||
writer_crypto->is_builtin_participant_volatile_message_secure_writer = false;
|
||||
|
||||
return writer_crypto;
|
||||
}
|
||||
|
||||
|
||||
static void remote_datawriter_crypto__free(CryptoObject *obj)
|
||||
{
|
||||
remote_datawriter_crypto *datawriter_crypto = (remote_datawriter_crypto *)obj;
|
||||
if (datawriter_crypto)
|
||||
{
|
||||
CHECK_CRYPTO_OBJECT_KIND(obj, CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->reader_session);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->reader2writer_key_material);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->writer2reader_key_material[0]);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->writer2reader_key_material[1]);
|
||||
CRYPTO_OBJECT_RELEASE(datawriter_crypto->participant);
|
||||
crypto_object_deinit((CryptoObject *)datawriter_crypto);
|
||||
ddsrt_free(datawriter_crypto);
|
||||
}
|
||||
}
|
||||
|
||||
remote_datawriter_crypto * crypto_remote_datawriter_crypto__new(const remote_participant_crypto *participant,
|
||||
DDS_Security_ProtectionKind meta_protection, DDS_Security_BasicProtectionKind data_protection, DDS_Security_DatareaderCryptoHandle local_reader_handle)
|
||||
{
|
||||
remote_datawriter_crypto *writer_crypto = ddsrt_calloc(1, sizeof(*writer_crypto));
|
||||
crypto_object_init((CryptoObject *)writer_crypto, CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO, remote_datawriter_crypto__free);
|
||||
writer_crypto->participant = (remote_participant_crypto *)CRYPTO_OBJECT_KEEP(participant);
|
||||
writer_crypto->metadata_protectionKind = meta_protection;
|
||||
writer_crypto->data_protectionKind = data_protection;
|
||||
writer_crypto->local_reader_handle = local_reader_handle;
|
||||
writer_crypto->is_builtin_participant_volatile_message_secure_writer = false;
|
||||
|
||||
return writer_crypto;
|
||||
}
|
||||
|
||||
|
||||
static void local_datareader_crypto__free(CryptoObject *obj)
|
||||
{
|
||||
local_datareader_crypto *datareader_crypto = (local_datareader_crypto *)obj;
|
||||
if (datareader_crypto)
|
||||
{
|
||||
CHECK_CRYPTO_OBJECT_KIND(obj, CRYPTO_OBJECT_KIND_LOCAL_READER_CRYPTO);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->reader_session);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->reader_key_material);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->participant);
|
||||
crypto_object_deinit((CryptoObject *)datareader_crypto);
|
||||
ddsrt_free(datareader_crypto);
|
||||
}
|
||||
}
|
||||
|
||||
local_datareader_crypto * crypto_local_datareader_crypto__new(const local_participant_crypto *participant,
|
||||
DDS_Security_ProtectionKind meta_protection, DDS_Security_BasicProtectionKind data_protection)
|
||||
{
|
||||
local_datareader_crypto *reader_crypto = ddsrt_calloc(1, sizeof(*reader_crypto));
|
||||
crypto_object_init((CryptoObject *)reader_crypto, CRYPTO_OBJECT_KIND_LOCAL_READER_CRYPTO, local_datareader_crypto__free);
|
||||
reader_crypto->participant = (local_participant_crypto *)CRYPTO_OBJECT_KEEP(participant);
|
||||
reader_crypto->metadata_protectionKind = meta_protection;
|
||||
reader_crypto->data_protectionKind = data_protection;
|
||||
reader_crypto->is_builtin_participant_volatile_message_secure_reader = false;
|
||||
|
||||
return reader_crypto;
|
||||
}
|
||||
|
||||
|
||||
static void remote_datareader_crypto__free(CryptoObject *obj)
|
||||
{
|
||||
remote_datareader_crypto *datareader_crypto = (remote_datareader_crypto *)obj;
|
||||
if (datareader_crypto)
|
||||
{
|
||||
CHECK_CRYPTO_OBJECT_KIND(obj, CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->writer_session);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->reader2writer_key_material);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->writer2reader_key_material_message);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->writer2reader_key_material_payload);
|
||||
CRYPTO_OBJECT_RELEASE(datareader_crypto->participant);
|
||||
crypto_object_deinit((CryptoObject *)datareader_crypto);
|
||||
ddsrt_free(datareader_crypto);
|
||||
}
|
||||
}
|
||||
|
||||
remote_datareader_crypto *crypto_remote_datareader_crypto__new(const remote_participant_crypto *participant, DDS_Security_ProtectionKind metadata_protectionKind,
|
||||
DDS_Security_BasicProtectionKind data_protectionKind, DDS_Security_DatawriterCryptoHandle local_writer_handle)
|
||||
{
|
||||
remote_datareader_crypto *reader_crypto = ddsrt_calloc(1, sizeof(*reader_crypto));
|
||||
crypto_object_init((CryptoObject *)reader_crypto, CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO, remote_datareader_crypto__free);
|
||||
reader_crypto->participant = (remote_participant_crypto *)CRYPTO_OBJECT_KEEP(participant);
|
||||
reader_crypto->metadata_protectionKind = metadata_protectionKind;
|
||||
reader_crypto->data_protectionKind = data_protectionKind;
|
||||
reader_crypto->local_writer_handle = local_writer_handle;
|
||||
reader_crypto->is_builtin_participant_volatile_message_secure_reader = false;
|
||||
|
||||
return reader_crypto;
|
||||
}
|
||||
|
||||
|
||||
typedef struct endpoint_relation_find_arg
|
||||
{
|
||||
CryptoObject *found;
|
||||
CryptoObject *local_crypto;
|
||||
CryptoObject *remote_crypto;
|
||||
uint32_t key_id;
|
||||
} endpoint_relation_find_arg;
|
||||
|
||||
static int endpoint_relation_cmp_key(CryptoObject *obj, void *arg)
|
||||
{
|
||||
const endpoint_relation *rel = (const endpoint_relation *)obj;
|
||||
endpoint_relation_find_arg *find_arg = (endpoint_relation_find_arg *)arg;
|
||||
|
||||
if (rel->key_id == find_arg->key_id)
|
||||
{
|
||||
find_arg->found = crypto_object_keep(obj);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int endpoint_relation_cmp_crypto(CryptoObject *obj, void *arg)
|
||||
{
|
||||
const endpoint_relation *rel = (const endpoint_relation *)obj;
|
||||
endpoint_relation_find_arg *find_arg = (endpoint_relation_find_arg *)arg;
|
||||
|
||||
if ((rel->local_crypto == find_arg->local_crypto) &&
|
||||
(rel->remote_crypto == find_arg->remote_crypto))
|
||||
{
|
||||
find_arg->found = crypto_object_keep(obj);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
endpoint_relation * crypto_endpoint_relation_find_by_key(struct CryptoObjectTable *table, uint32_t key_id)
|
||||
{
|
||||
endpoint_relation_find_arg find_arg;
|
||||
find_arg.found = NULL;
|
||||
find_arg.key_id = key_id;
|
||||
find_arg.local_crypto = NULL;
|
||||
find_arg.remote_crypto = NULL;
|
||||
crypto_object_table_walk(table, endpoint_relation_cmp_key, &find_arg);
|
||||
return (endpoint_relation *)(find_arg.found);
|
||||
}
|
||||
|
||||
endpoint_relation * crypto_endpoint_relation_find_by_crypto(struct CryptoObjectTable *table, CryptoObject *local_crypto, CryptoObject *remote_crypto)
|
||||
{
|
||||
endpoint_relation_find_arg find_arg;
|
||||
find_arg.found = NULL;
|
||||
find_arg.key_id = 0;
|
||||
find_arg.local_crypto = local_crypto;
|
||||
find_arg.remote_crypto = remote_crypto;
|
||||
crypto_object_table_walk(table, endpoint_relation_cmp_crypto, &find_arg);
|
||||
return (endpoint_relation *)(find_arg.found);
|
||||
}
|
354
src/security/builtin_plugins/cryptographic/src/crypto_objects.h
Normal file
354
src/security/builtin_plugins/cryptographic/src/crypto_objects.h
Normal file
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTO_OBJECTS_H
|
||||
#define CRYPTO_OBJECTS_H
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include "dds/ddsrt/atomics.h"
|
||||
#include "dds/ddsrt/sync.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "crypto_defs.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define CHECK_CRYPTO_OBJECT_KIND(o, k) assert(crypto_object_valid((CryptoObject *)(o), k))
|
||||
#else
|
||||
#define CHECK_CRYPTO_OBJECT_KIND(o, k)
|
||||
#endif
|
||||
|
||||
#define CRYPTO_OBJECT(o) ((CryptoObject *)(o))
|
||||
#define CRYPTO_OBJECT_HANDLE(o) (CRYPTO_OBJECT(o)->handle)
|
||||
#define PARTICIPANT_CRYPTO_HANDLE(o) ((DDS_Security_ParticipantCryptoHandle)CRYPTO_OBJECT_HANDLE(o))
|
||||
#define DATAWRITER_CRYPTO_HANDLE(o) ((DDS_Security_DatawriterCryptoHandle)CRYPTO_OBJECT_HANDLE(o))
|
||||
#define DATAREADER_CRYPTO_HANDLE(o) ((DDS_Security_DatareaderCryptoHandle)CRYPTO_OBJECT_HANDLE(o))
|
||||
|
||||
#define CRYPTO_OBJECT_KEEP(o) crypto_object_keep((CryptoObject *)(o))
|
||||
#define CRYPTO_OBJECT_RELEASE(o) crypto_object_release((CryptoObject *)(o))
|
||||
#define CRYPTO_OBJECT_VALID(o, k) crypto_object_valid((CryptoObject *)(o), k)
|
||||
|
||||
#define CRYPTO_TRANSFORM_HAS_KEYS(k) ((k) != CRYPTO_TRANSFORMATION_KIND_NONE && (k) != CRYPTO_TRANSFORMATION_KIND_INVALID)
|
||||
|
||||
typedef DDS_Security_ParticipantCryptoHandle DDS_Security_LocalParticipantCryptoHandle;
|
||||
typedef DDS_Security_ParticipantCryptoHandle DDS_Security_RemoteParticipantCryptoHandle;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CRYPTO_OBJECT_KIND_UNKNOWN,
|
||||
CRYPTO_OBJECT_KIND_LOCAL_CRYPTO,
|
||||
CRYPTO_OBJECT_KIND_REMOTE_CRYPTO,
|
||||
CRYPTO_OBJECT_KIND_LOCAL_WRITER_CRYPTO,
|
||||
CRYPTO_OBJECT_KIND_REMOTE_WRITER_CRYPTO,
|
||||
CRYPTO_OBJECT_KIND_LOCAL_READER_CRYPTO,
|
||||
CRYPTO_OBJECT_KIND_REMOTE_READER_CRYPTO,
|
||||
CRYPTO_OBJECT_KIND_KEY_MATERIAL,
|
||||
CRYPTO_OBJECT_KIND_SESSION_KEY_MATERIAL,
|
||||
CRYPTO_OBJECT_KIND_PARTICIPANT_KEY_MATERIAL,
|
||||
CRYPTO_OBJECT_KIND_ENDPOINT_RELATION
|
||||
} CryptoObjectKind_t;
|
||||
|
||||
typedef struct CryptoObject CryptoObject;
|
||||
typedef void (*CryptoObjectDestructor)(CryptoObject *obj);
|
||||
|
||||
struct CryptoObject
|
||||
{
|
||||
int64_t handle;
|
||||
ddsrt_atomic_uint32_t refcount;
|
||||
CryptoObjectKind_t kind;
|
||||
CryptoObjectDestructor destructor;
|
||||
};
|
||||
|
||||
struct local_datawriter_crypto;
|
||||
struct local_datareader_crypto;
|
||||
struct remote_datawriter_crypto;
|
||||
struct remote_datareader_crypto;
|
||||
|
||||
typedef struct master_key_material
|
||||
{
|
||||
CryptoObject _parent;
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind;
|
||||
unsigned char *master_salt;
|
||||
uint32_t sender_key_id;
|
||||
unsigned char *master_sender_key;
|
||||
uint32_t receiver_specific_key_id;
|
||||
unsigned char *master_receiver_specific_key;
|
||||
} master_key_material;
|
||||
|
||||
typedef struct session_key_material
|
||||
{
|
||||
CryptoObject _parent;
|
||||
uint32_t id;
|
||||
crypto_session_key_t key;
|
||||
uint32_t key_size;
|
||||
uint32_t block_size;
|
||||
uint64_t block_counter;
|
||||
uint64_t max_blocks_per_session;
|
||||
uint64_t init_vector_suffix;
|
||||
master_key_material *master_key_material;
|
||||
} session_key_material;
|
||||
|
||||
typedef struct remote_session_info
|
||||
{
|
||||
uint32_t key_size;
|
||||
uint32_t id;
|
||||
crypto_session_key_t key;
|
||||
} remote_session_info;
|
||||
|
||||
typedef struct endpoint_relation
|
||||
{
|
||||
CryptoObject _parent;
|
||||
DDS_Security_SecureSubmessageCategory_t kind;
|
||||
uint32_t key_id;
|
||||
CryptoObject *local_crypto;
|
||||
CryptoObject *remote_crypto;
|
||||
} endpoint_relation;
|
||||
|
||||
typedef struct local_participant_crypto
|
||||
{
|
||||
CryptoObject _parent;
|
||||
master_key_material *key_material;
|
||||
DDS_Security_IdentityHandle identity_handle;
|
||||
session_key_material *session;
|
||||
DDS_Security_ProtectionKind rtps_protection_kind;
|
||||
} local_participant_crypto;
|
||||
|
||||
typedef struct participant_key_material
|
||||
{
|
||||
CryptoObject _parent;
|
||||
DDS_Security_ParticipantCryptoHandle pp_local_handle;
|
||||
master_key_material *remote_key_material;
|
||||
master_key_material *local_P2P_key_material;
|
||||
master_key_material *P2P_kx_key_material;
|
||||
session_key_material *P2P_writer_session;
|
||||
session_key_material *P2P_reader_session;
|
||||
struct CryptoObjectTable *endpoint_relations;
|
||||
} participant_key_material;
|
||||
|
||||
typedef struct remote_participant_crypto
|
||||
{
|
||||
CryptoObject _parent;
|
||||
DDS_Security_GUID_t remoteGuid;
|
||||
DDS_Security_IdentityHandle identity_handle;
|
||||
struct CryptoObjectTable *key_material;
|
||||
session_key_material *session;
|
||||
DDS_Security_ProtectionKind rtps_protection_kind;
|
||||
} remote_participant_crypto;
|
||||
|
||||
typedef struct local_datawriter_crypto
|
||||
{
|
||||
CryptoObject _parent;
|
||||
local_participant_crypto *participant;
|
||||
master_key_material *writer_key_material_message;
|
||||
master_key_material *writer_key_material_payload;
|
||||
session_key_material *writer_session_message;
|
||||
session_key_material *writer_session_payload;
|
||||
DDS_Security_ProtectionKind metadata_protectionKind;
|
||||
DDS_Security_BasicProtectionKind data_protectionKind;
|
||||
bool is_builtin_participant_volatile_message_secure_writer;
|
||||
} local_datawriter_crypto;
|
||||
|
||||
typedef struct remote_datawriter_crypto
|
||||
{
|
||||
CryptoObject _parent;
|
||||
remote_participant_crypto *participant;
|
||||
DDS_Security_ProtectionKind metadata_protectionKind;
|
||||
DDS_Security_BasicProtectionKind data_protectionKind;
|
||||
master_key_material *reader2writer_key_material;
|
||||
master_key_material *writer2reader_key_material[2];
|
||||
session_key_material *reader_session; /* reference to the session key used by the reader */
|
||||
DDS_Security_DatareaderCryptoHandle local_reader_handle;
|
||||
bool is_builtin_participant_volatile_message_secure_writer;
|
||||
} remote_datawriter_crypto;
|
||||
|
||||
typedef struct local_datareader_crypto
|
||||
{
|
||||
CryptoObject _parent;
|
||||
local_participant_crypto *participant;
|
||||
master_key_material *reader_key_material;
|
||||
session_key_material *reader_session;
|
||||
DDS_Security_ProtectionKind metadata_protectionKind;
|
||||
DDS_Security_BasicProtectionKind data_protectionKind;
|
||||
bool is_builtin_participant_volatile_message_secure_reader;
|
||||
} local_datareader_crypto;
|
||||
|
||||
typedef struct remote_datareader_crypto
|
||||
{
|
||||
CryptoObject _parent;
|
||||
remote_participant_crypto *participant;
|
||||
DDS_Security_ProtectionKind metadata_protectionKind;
|
||||
DDS_Security_BasicProtectionKind data_protectionKind;
|
||||
master_key_material *reader2writer_key_material;
|
||||
master_key_material *writer2reader_key_material_message;
|
||||
master_key_material *writer2reader_key_material_payload;
|
||||
session_key_material *writer_session; /* reference to the session key used by the writer */
|
||||
DDS_Security_DatawriterCryptoHandle local_writer_handle;
|
||||
bool is_builtin_participant_volatile_message_secure_reader;
|
||||
} remote_datareader_crypto;
|
||||
|
||||
master_key_material *
|
||||
crypto_master_key_material_new(DDS_Security_CryptoTransformKind_Enum transform_kind);
|
||||
|
||||
void crypto_master_key_material_set(
|
||||
master_key_material *dst,
|
||||
const master_key_material *src);
|
||||
|
||||
session_key_material *
|
||||
crypto_session_key_material_new(
|
||||
master_key_material *master_key);
|
||||
|
||||
bool crypto_session_key_material_update(
|
||||
session_key_material *session,
|
||||
uint32_t size,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
local_participant_crypto *
|
||||
crypto_local_participant_crypto__new(
|
||||
DDS_Security_IdentityHandle participant_identity);
|
||||
|
||||
remote_participant_crypto *
|
||||
crypto_remote_participant_crypto__new(
|
||||
DDS_Security_IdentityHandle participant_identity);
|
||||
|
||||
void crypto_object_init(
|
||||
CryptoObject *obj,
|
||||
CryptoObjectKind_t kind,
|
||||
CryptoObjectDestructor destructor);
|
||||
|
||||
endpoint_relation *
|
||||
crypto_endpoint_relation_new(
|
||||
DDS_Security_SecureSubmessageCategory_t kind,
|
||||
uint32_t key_id,
|
||||
CryptoObject *local_crypto,
|
||||
CryptoObject *remote_crypto);
|
||||
|
||||
endpoint_relation *
|
||||
crypto_endpoint_relation_find_by_key(
|
||||
struct CryptoObjectTable *table,
|
||||
uint32_t key_id);
|
||||
|
||||
endpoint_relation *
|
||||
crypto_endpoint_relation_find_by_crypto(
|
||||
struct CryptoObjectTable *table,
|
||||
CryptoObject *local_crypto,
|
||||
CryptoObject *remote_crypto);
|
||||
|
||||
bool endpoint_relation_get_locals(
|
||||
const endpoint_relation *relation,
|
||||
const local_participant_crypto *participant,
|
||||
DDS_Security_HandleSeq *list);
|
||||
|
||||
local_datawriter_crypto *
|
||||
crypto_local_datawriter_crypto__new(
|
||||
const local_participant_crypto *participant,
|
||||
DDS_Security_ProtectionKind meta_protection,
|
||||
DDS_Security_BasicProtectionKind data_protection);
|
||||
|
||||
remote_datareader_crypto *
|
||||
crypto_remote_datareader_crypto__new(
|
||||
const remote_participant_crypto *participant,
|
||||
DDS_Security_ProtectionKind metadata_protectionKind,
|
||||
DDS_Security_BasicProtectionKind data_protectionKind,
|
||||
DDS_Security_DatawriterCryptoHandle local_writer_handle);
|
||||
|
||||
local_datareader_crypto *
|
||||
crypto_local_datareader_crypto__new(
|
||||
const local_participant_crypto *participant,
|
||||
DDS_Security_ProtectionKind meta_protection,
|
||||
DDS_Security_BasicProtectionKind data_protection);
|
||||
|
||||
remote_datawriter_crypto *
|
||||
crypto_remote_datawriter_crypto__new(
|
||||
const remote_participant_crypto *participant,
|
||||
DDS_Security_ProtectionKind meta_protection,
|
||||
DDS_Security_BasicProtectionKind data_protection,
|
||||
DDS_Security_DatareaderCryptoHandle local_reader_handle);
|
||||
|
||||
CryptoObject *
|
||||
crypto_object_keep(
|
||||
CryptoObject *obj);
|
||||
|
||||
void crypto_object_release(
|
||||
CryptoObject *obj);
|
||||
|
||||
bool crypto_object_valid(
|
||||
CryptoObject *obj,
|
||||
CryptoObjectKind_t kind);
|
||||
|
||||
void crypto_object_free(
|
||||
CryptoObject *obj);
|
||||
|
||||
local_participant_crypto *
|
||||
crypto_local_participant_crypto__new(
|
||||
DDS_Security_IdentityHandle participant_identity);
|
||||
|
||||
remote_participant_crypto *
|
||||
crypto_remote_participant_crypto__new(
|
||||
DDS_Security_IdentityHandle participant_identity);
|
||||
|
||||
participant_key_material *
|
||||
crypto_participant_key_material_new(
|
||||
const local_participant_crypto *pplocal);
|
||||
|
||||
struct CryptoObjectTable;
|
||||
|
||||
typedef uint32_t (*CryptoObjectHashFunction)(const void *obj);
|
||||
typedef int (*CryptoObjectEqualFunction)(const void *ha, const void *hb);
|
||||
typedef CryptoObject *(*CryptoObjectFindFunction)(const struct CryptoObjectTable *table, const void *arg);
|
||||
|
||||
struct CryptoObjectTable *
|
||||
crypto_object_table_new(
|
||||
CryptoObjectHashFunction hashfnc,
|
||||
CryptoObjectEqualFunction equalfnc,
|
||||
CryptoObjectFindFunction findfnc);
|
||||
|
||||
void crypto_object_table_free(
|
||||
struct CryptoObjectTable *table);
|
||||
|
||||
CryptoObject *
|
||||
crypto_object_table_insert(
|
||||
struct CryptoObjectTable *table,
|
||||
CryptoObject *object);
|
||||
|
||||
void crypto_object_table_remove_object(
|
||||
struct CryptoObjectTable *table,
|
||||
CryptoObject *object);
|
||||
|
||||
CryptoObject *
|
||||
crypto_object_table_remove(
|
||||
struct CryptoObjectTable *table,
|
||||
int64_t handle);
|
||||
|
||||
CryptoObject *
|
||||
crypto_object_table_find_by_template(
|
||||
const struct CryptoObjectTable *table,
|
||||
const void *template);
|
||||
|
||||
CryptoObject *
|
||||
crypto_object_table_find(
|
||||
struct CryptoObjectTable *table,
|
||||
int64_t handle);
|
||||
|
||||
typedef int (*CryptoObjectTableCallback)(CryptoObject *obj, void *arg);
|
||||
|
||||
struct CryptoObjectTable
|
||||
{
|
||||
struct ddsrt_hh *htab;
|
||||
ddsrt_mutex_t lock;
|
||||
CryptoObjectFindFunction findfnc;
|
||||
};
|
||||
|
||||
void crypto_object_table_walk(
|
||||
struct CryptoObjectTable *table,
|
||||
CryptoObjectTableCallback callback,
|
||||
void *arg);
|
||||
|
||||
#endif /* CRYPTO_OBJECTS_H */
|
2469
src/security/builtin_plugins/cryptographic/src/crypto_transform.c
Normal file
2469
src/security/builtin_plugins/cryptographic/src/crypto_transform.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTO_TRANSFORM_H
|
||||
#define CRYPTO_TRANSFORM_H
|
||||
|
||||
#include "dds/security/dds_security_api.h"
|
||||
|
||||
/**
|
||||
* @brief Allocation function for implementer structure (with internal variables) transparently.
|
||||
*/
|
||||
dds_security_crypto_transform *
|
||||
dds_security_crypto_transform__alloc(
|
||||
const dds_security_cryptography *crypto);
|
||||
|
||||
void
|
||||
dds_security_crypto_transform__dealloc(
|
||||
dds_security_crypto_transform *instance);
|
||||
|
||||
#endif /* CRYPTO_TRANSFORM_H */
|
153
src/security/builtin_plugins/cryptographic/src/crypto_utils.c
Normal file
153
src/security/builtin_plugins/cryptographic/src/crypto_utils.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "crypto_defs.h"
|
||||
#include "crypto_utils.h"
|
||||
|
||||
char *crypto_openssl_error_message(void)
|
||||
{
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
char *msg;
|
||||
char *buf = NULL;
|
||||
size_t len;
|
||||
|
||||
if (!bio)
|
||||
return ddsrt_strdup ("BIO_new failed");
|
||||
|
||||
ERR_print_errors(bio);
|
||||
len = (size_t) BIO_get_mem_data(bio, &buf);
|
||||
msg = ddsrt_malloc(len + 1);
|
||||
memset(msg, 0, len + 1);
|
||||
memcpy(msg, buf, len);
|
||||
BIO_free(bio);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static bool
|
||||
crypto_calculate_key_impl(
|
||||
const char *prefix,
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(transformation_kind);
|
||||
uint32_t id = ddsrt_toBE4u(session_id);
|
||||
size_t sz = strlen(prefix) + key_bytes + sizeof(id);
|
||||
unsigned char *buffer = ddsrt_malloc (sz);
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
|
||||
memcpy(buffer, prefix, strlen(prefix));
|
||||
memcpy(&buffer[strlen(prefix)], master_salt, key_bytes);
|
||||
memcpy(&buffer[strlen(prefix) + key_bytes], &id, sizeof(id));
|
||||
if (HMAC(EVP_sha256(), master_key, (int)key_bytes, buffer, sz, md, NULL) == NULL)
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_CIPHER_ERROR, 0, "HMAC failed: ");
|
||||
ddsrt_free (buffer);
|
||||
return false;
|
||||
}
|
||||
memcpy (session_key->data, md, key_bytes);
|
||||
ddsrt_free (buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
crypto_calculate_session_key(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
return crypto_calculate_key_impl("SessionKey", session_key, session_id, master_salt, master_key, transformation_kind, ex);
|
||||
}
|
||||
|
||||
bool
|
||||
crypto_calculate_receiver_specific_key(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
return crypto_calculate_key_impl("SessionReceiverKey", session_key, session_id, master_salt, master_key, transformation_kind, ex);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
crypto_get_key_size(
|
||||
DDS_Security_CryptoTransformKind_Enum kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case CRYPTO_TRANSFORMATION_KIND_AES128_GMAC:
|
||||
case CRYPTO_TRANSFORMATION_KIND_AES128_GCM:
|
||||
return 128;
|
||||
case CRYPTO_TRANSFORMATION_KIND_AES256_GMAC:
|
||||
case CRYPTO_TRANSFORMATION_KIND_AES256_GCM:
|
||||
return 256;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
crypto_get_random_uint32(void)
|
||||
{
|
||||
uint32_t val;
|
||||
RAND_bytes((unsigned char *)&val, sizeof(uint32_t));
|
||||
return val;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
crypto_get_random_uint64(void)
|
||||
{
|
||||
uint64_t val;
|
||||
RAND_bytes((unsigned char *)&val, sizeof(uint64_t));
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
crypto_hmac256(
|
||||
const unsigned char *key,
|
||||
uint32_t key_size,
|
||||
const unsigned char *data,
|
||||
uint32_t data_size,
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned char *result;
|
||||
|
||||
assert (key_size <= INT32_MAX);
|
||||
if (HMAC(EVP_sha256(), key, (int) key_size, data, data_size, md, NULL) == NULL)
|
||||
{
|
||||
DDS_Security_Exception_set_with_openssl_error(ex, DDS_CRYPTO_PLUGIN_CONTEXT, DDS_SECURITY_ERR_UNDEFINED_CODE, 0, "Failed to init hashing context: ");
|
||||
return NULL;
|
||||
}
|
||||
result = ddsrt_malloc(key_size);
|
||||
memcpy (result, md, key_size);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTO_UTILS_H
|
||||
#define CRYPTO_UTILS_H
|
||||
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/endian.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/security/export.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_types.h"
|
||||
#include "crypto_defs.h"
|
||||
|
||||
#define CRYPTO_TRANSFORM_KIND(k) ddsrt_fromBE4u((*(uint32_t *)&((k)[0])))
|
||||
#define CRYPTO_TRANSFORM_ID(k) ddsrt_fromBE4u((*(uint32_t *)&((k)[0])))
|
||||
#define CRYPTO_KEY_SIZE_BYTES(kind) (crypto_get_key_size(kind) >> 3)
|
||||
|
||||
#define ALIGN4(x) (((x) + 3) & (uint32_t)(-4))
|
||||
|
||||
struct init_vector_suffix
|
||||
{
|
||||
uint32_t high;
|
||||
uint32_t low;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 *crypto_openssl_error_message(void);
|
||||
|
||||
/**
|
||||
* @param[in,out] session_key Session key
|
||||
* @param[in] session_id Session Id
|
||||
* @param[in] master_salt Master salt
|
||||
* @param[in] master_key Master key
|
||||
* @param[in] transformation_kind Transformation kind
|
||||
* @param[in,out] ex Security exception
|
||||
*/
|
||||
SECURITY_EXPORT bool crypto_calculate_session_key(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
/**
|
||||
* @param[in,out] session_key Session key
|
||||
* @param[in] session_id Session Id
|
||||
* @param[in] master_salt Master salt
|
||||
* @param[in] master_key Master key
|
||||
* @param[in] transformation_kind Transformation kind
|
||||
* @param[in,out] ex Security exception
|
||||
*/
|
||||
SECURITY_EXPORT bool crypto_calculate_receiver_specific_key(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
SECURITY_EXPORT uint32_t crypto_get_key_size(DDS_Security_CryptoTransformKind_Enum kind);
|
||||
SECURITY_EXPORT uint32_t crypto_get_random_uint32(void);
|
||||
SECURITY_EXPORT uint64_t crypto_get_random_uint64(void);
|
||||
|
||||
/**
|
||||
* @brief Compute a HMAC256 on the provided data.
|
||||
*
|
||||
* @param[in] key The key used to compute the HMAC256 result
|
||||
* @param[in] key_size The size of the key (128 or 256 bits)
|
||||
* @param[in] data The data on which the HMAC is computed
|
||||
* @param[in] data_size The size of the data
|
||||
* @param[in,out] ex Security exception
|
||||
*/
|
||||
SECURITY_EXPORT unsigned char *crypto_hmac256(
|
||||
const unsigned char *key,
|
||||
uint32_t key_size,
|
||||
const unsigned char *data,
|
||||
uint32_t data_size,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
#endif /* CRYPTO_UTILS_H */
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "cryptography.h"
|
||||
#include "crypto_key_exchange.h"
|
||||
#include "crypto_key_factory.h"
|
||||
#include "crypto_transform.h"
|
||||
|
||||
/**
|
||||
* Implementation structure for storing encapsulated members of the instance
|
||||
* while giving only the interface definition to user
|
||||
*/
|
||||
|
||||
typedef struct dds_security_cryptography_impl {
|
||||
dds_security_cryptography base;
|
||||
} dds_security_cryptography_impl;
|
||||
|
||||
dds_security_crypto_key_factory *cryptography_get_crypto_key_factory (const struct dds_security_cryptography *crypto)
|
||||
{
|
||||
const dds_security_cryptography_impl *instance = (dds_security_cryptography_impl *) crypto;
|
||||
return instance->base.crypto_key_factory;
|
||||
}
|
||||
|
||||
dds_security_crypto_key_exchange *cryptography_get_crypto_key_exchange (const struct dds_security_cryptography *crypto)
|
||||
{
|
||||
const dds_security_cryptography_impl *instance = (dds_security_cryptography_impl *) crypto;
|
||||
return instance->base.crypto_key_exchange;
|
||||
}
|
||||
|
||||
dds_security_crypto_transform *cryptography_get_crypto_transform (const struct dds_security_cryptography *crypto)
|
||||
{
|
||||
const dds_security_cryptography_impl *instance = (dds_security_cryptography_impl *) crypto;
|
||||
return instance->base.crypto_transform;
|
||||
}
|
||||
|
||||
|
||||
int init_crypto (const char *argument, void **context)
|
||||
{
|
||||
dds_security_cryptography_impl *cryptography;
|
||||
dds_security_crypto_key_exchange *crypto_key_exchange;
|
||||
dds_security_crypto_key_factory *crypto_key_factory;
|
||||
dds_security_crypto_transform *crypto_transform;
|
||||
|
||||
DDSRT_UNUSED_ARG (argument);
|
||||
|
||||
/* allocate new instance */
|
||||
cryptography = ddsrt_malloc (sizeof(*cryptography));
|
||||
|
||||
/* assign the sub components */
|
||||
crypto_key_exchange = dds_security_crypto_key_exchange__alloc ((dds_security_cryptography *)cryptography);
|
||||
if (!crypto_key_exchange) goto err_exchange;
|
||||
|
||||
crypto_key_factory = dds_security_crypto_key_factory__alloc ((dds_security_cryptography *)cryptography);
|
||||
if (!crypto_key_factory) goto err_factory;
|
||||
|
||||
crypto_transform = dds_security_crypto_transform__alloc ((dds_security_cryptography *)cryptography);
|
||||
if (!crypto_transform) goto err_transform;
|
||||
|
||||
cryptography->base.crypto_key_exchange = crypto_key_exchange;
|
||||
cryptography->base.crypto_key_factory = crypto_key_factory;
|
||||
cryptography->base.crypto_transform = crypto_transform;
|
||||
|
||||
/* return the instance */
|
||||
*context = cryptography;
|
||||
return DDS_SECURITY_SUCCESS;
|
||||
|
||||
err_transform:
|
||||
dds_security_crypto_key_factory__dealloc (crypto_key_factory);
|
||||
err_factory:
|
||||
dds_security_crypto_key_exchange__dealloc (crypto_key_exchange);
|
||||
err_exchange:
|
||||
ddsrt_free (cryptography);
|
||||
*context = NULL;
|
||||
return DDS_SECURITY_FAILED;
|
||||
}
|
||||
|
||||
int finalize_crypto (void *instance)
|
||||
{
|
||||
dds_security_cryptography_impl* instance_impl = (dds_security_cryptography_impl*) instance;
|
||||
/* deallocate components */
|
||||
dds_security_crypto_key_exchange__dealloc (instance_impl->base.crypto_key_exchange);
|
||||
dds_security_crypto_key_factory__dealloc (instance_impl->base.crypto_key_factory);
|
||||
dds_security_crypto_transform__dealloc (instance_impl->base.crypto_transform);
|
||||
/* deallocate cryptography */
|
||||
ddsrt_free (instance_impl);
|
||||
return DDS_SECURITY_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef CRYPTOGRAPHY_H
|
||||
#define CRYPTOGRAPHY_H
|
||||
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/export.h"
|
||||
|
||||
SECURITY_EXPORT int init_crypto(const char *argument, void **context);
|
||||
SECURITY_EXPORT int finalize_crypto(void *instance);
|
||||
|
||||
dds_security_crypto_key_factory *
|
||||
cryptography_get_crypto_key_factory(
|
||||
const dds_security_cryptography *crypto);
|
||||
|
||||
dds_security_crypto_key_exchange *
|
||||
cryptography_get_crypto_key_exchange(
|
||||
const dds_security_cryptography *crypto);
|
||||
|
||||
dds_security_crypto_transform *
|
||||
cryptography_get_crypto_transform(
|
||||
const dds_security_cryptography *crypto);
|
||||
|
||||
#endif /* CRYPTOGRAPHY_H */
|
|
@ -10,42 +10,63 @@
|
|||
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
#
|
||||
include(CUnit)
|
||||
find_package(OpenSSL)
|
||||
|
||||
set(security_auth_test_sources
|
||||
"validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c"
|
||||
"common/src/loader.c"
|
||||
"common/src/handshake_helper.c"
|
||||
"get_authenticated_peer_credential_token/src/get_authenticated_peer_credential_token_utests.c"
|
||||
"process_handshake/src/process_handshake_utests.c"
|
||||
"validate_begin_handshake_reply/src/validate_begin_handshake_reply_utests.c"
|
||||
"validate_begin_handshake_request/src/validate_begin_handshake_request_utests.c"
|
||||
"validate_local_identity/src/validate_local_identity_utests.c"
|
||||
"validate_remote_identity/src/validate_remote_identity_utests.c"
|
||||
"validate_begin_handshake_request/src/validate_begin_handshake_request_utests.c"
|
||||
"process_handshake/src/process_handshake_utests.c"
|
||||
"common/src/handshake_helper.c"
|
||||
"common/src/loader.c")
|
||||
)
|
||||
|
||||
set(security_crypto_test_sources
|
||||
"common/src/crypto_helper.c"
|
||||
"create_local_datareader_crypto_tokens/src/create_local_datareader_crypto_tokens_utests.c"
|
||||
"create_local_datawriter_crypto_tokens/src/create_local_datawriter_crypto_tokens_utests.c"
|
||||
"create_local_participant_crypto_tokens/src/create_local_participant_crypto_tokens_utests.c"
|
||||
"decode_datareader_submessage/src/decode_datareader_submessage_utests.c"
|
||||
"decode_datawriter_submessage/src/decode_datawriter_submessage_utests.c"
|
||||
"decode_rtps_message/src/decode_rtps_message_utests.c"
|
||||
"decode_serialized_payload/src/decode_serialized_payload_utests.c"
|
||||
"encode_datareader_submessage/src/encode_datareader_submessage_utests.c"
|
||||
"encode_datawriter_submessage/src/encode_datawriter_submessage_utests.c"
|
||||
"encode_rtps_message/src/encode_rtps_message_utests.c"
|
||||
"encode_serialized_payload/src/encode_serialized_payload_utests.c"
|
||||
"preprocess_secure_submsg/src/preprocess_secure_submsg_utests.c"
|
||||
"register_local_datareader/src/register_local_datareader_utests.c"
|
||||
"register_local_datawriter/src/register_local_datawriter_utests.c"
|
||||
"register_local_participant/src/register_local_participant_utests.c"
|
||||
"register_matched_remote_datareader/src/register_matched_remote_datareader_utests.c"
|
||||
"register_matched_remote_datawriter/src/register_matched_remote_datawriter_utests.c"
|
||||
"register_matched_remote_participant/src/register_matched_remote_participant_utests.c"
|
||||
"set_remote_datareader_crypto_tokens/src/set_remote_datareader_crypto_tokens_utests.c"
|
||||
"set_remote_datawriter_crypto_tokens/src/set_remote_datawriter_crypto_tokens_utests.c"
|
||||
"set_remote_participant_crypto_tokens/src/set_remote_participant_crypto_tokens_utests.c"
|
||||
)
|
||||
|
||||
add_cunit_executable(cunit_security_plugins ${security_auth_test_sources} ${security_crypto_test_sources})
|
||||
if(OPENSSL_FOUND)
|
||||
target_link_libraries(cunit_security_plugins PRIVATE OpenSSL::SSL)
|
||||
else()
|
||||
message(FATAL_ERROR "To build without openssl support, set DDSC_ENABLE_OPENSSL to OFF")
|
||||
endif()
|
||||
|
||||
add_cunit_executable(cunit_security_plugins ${security_auth_test_sources})
|
||||
target_include_directories(
|
||||
cunit_security_plugins PRIVATE
|
||||
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src/include/>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../cryptographic/src/>"
|
||||
"$<BUILD_INTERFACE:$<TARGET_PROPERTY:security_api,INTERFACE_INCLUDE_DIRECTORIES>>"
|
||||
"$<BUILD_INTERFACE:$<TARGET_PROPERTY:security_core,INTERFACE_INCLUDE_DIRECTORIES>>"
|
||||
"$<BUILD_INTERFACE:$<TARGET_PROPERTY:ddsrt,INTERFACE_INCLUDE_DIRECTORIES>>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(cunit_security_plugins PRIVATE ddsc security_api)
|
||||
|
||||
|
||||
find_package(OpenSSL )
|
||||
if(OPENSSL_FOUND)
|
||||
target_link_libraries(cunit_security_plugins PRIVATE OpenSSL::SSL)
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "To build without openssl support, set DDSC_ENABLE_OPENSSL to OFF")
|
||||
endif()
|
||||
target_link_libraries(cunit_security_plugins PRIVATE ddsc security_api dds_security_crypto)
|
||||
|
||||
set(CUnit_builtin_plugins_tests_dir "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
configure_file("config_env.h.in" "config_env.h")
|
||||
|
||||
|
||||
|
|
112
src/security/builtin_plugins/tests/common/src/crypto_helper.c
Normal file
112
src/security/builtin_plugins/tests/common/src/crypto_helper.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/endian.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "crypto_helper.h"
|
||||
#include "crypto_utils.h"
|
||||
|
||||
|
||||
static bool
|
||||
crypto_calculate_session_key_impl_test(
|
||||
const char *prefix,
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind)
|
||||
{
|
||||
bool result = true;
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(transformation_kind);
|
||||
uint32_t id = ddsrt_toBE4u(session_id);
|
||||
size_t sz = strlen(prefix) + key_bytes + sizeof(id);
|
||||
unsigned char *buffer = ddsrt_malloc (sz);
|
||||
memcpy(buffer, prefix, strlen(prefix));
|
||||
memcpy(&buffer[strlen(prefix)], master_salt, key_bytes);
|
||||
memcpy(&buffer[strlen(prefix) + key_bytes], &id, sizeof(id));
|
||||
if (HMAC(EVP_sha256(), master_key, (int)key_bytes, buffer, sz, session_key->data, NULL) == NULL)
|
||||
{
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
ddsrt_free (buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
crypto_calculate_session_key_test(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind)
|
||||
{
|
||||
return crypto_calculate_session_key_impl_test ("SessionKey", session_key, session_id, master_salt, master_key, transformation_kind);
|
||||
}
|
||||
|
||||
bool calculate_receiver_specific_key_test(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind)
|
||||
{
|
||||
return crypto_calculate_session_key_impl_test ("SessionReceiverKey", session_key, session_id, master_salt, master_key, transformation_kind);
|
||||
}
|
||||
|
||||
int master_salt_not_empty(master_key_material *keymat)
|
||||
{
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(keymat->transformation_kind);
|
||||
for (uint32_t i = 0; i < key_bytes; i++)
|
||||
{
|
||||
if (keymat->master_salt[i])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int master_key_not_empty(master_key_material *keymat)
|
||||
{
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(keymat->transformation_kind);
|
||||
for (uint32_t i = 0; i < key_bytes; i++)
|
||||
{
|
||||
if (keymat->master_sender_key[i])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int master_receiver_specific_key_not_empty(master_key_material *keymat)
|
||||
{
|
||||
uint32_t key_bytes = CRYPTO_KEY_SIZE_BYTES(keymat->transformation_kind);
|
||||
for (uint32_t i = 0; i < key_bytes; i++)
|
||||
{
|
||||
if (keymat->master_receiver_specific_key[i])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef DDS_SECURITY_BUITIN_TEST_CRYPTO_HELPER_H
|
||||
#define DDS_SECURITY_BUITIN_TEST_CRYPTO_HELPER_H
|
||||
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
bool
|
||||
crypto_calculate_session_key_test(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind);
|
||||
|
||||
bool calculate_receiver_specific_key_test(
|
||||
crypto_session_key_t *session_key,
|
||||
uint32_t session_id,
|
||||
const unsigned char *master_salt,
|
||||
const unsigned char *master_key,
|
||||
DDS_Security_CryptoTransformKind_Enum transformation_kind);
|
||||
|
||||
int master_salt_not_empty(master_key_material *keymat);
|
||||
int master_key_not_empty(master_key_material *keymat);
|
||||
int master_receiver_specific_key_not_empty(master_key_material *keymat);
|
||||
|
||||
#endif /* DDS_SECURITY_BUITIN_TEST_CRYPTO_HELPER_H */
|
|
@ -0,0 +1,501 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
#define CRYPTO_TRANSFORM_KIND(k) (*(uint32_t *)&((k)[0]))
|
||||
#define CRYPTO_TRANSFORM_ID(k) (*(uint32_t *)&((k)[0]))
|
||||
|
||||
static const char *CRYPTO_TOKEN_CLASS_ID = "DDS:Crypto:AES_GCM_GMAC";
|
||||
static const char *CRYPTO_TOKEN_PROPERTY_NAME = "dds.cryp.keymat";
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static DDS_Security_IdentityHandle local_participant_identity = 1;
|
||||
static DDS_Security_IdentityHandle remote_participant_identity = 2;
|
||||
|
||||
static DDS_Security_ParticipantCryptoHandle local_particpant_crypto = 0;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_particpant_crypto = 0;
|
||||
static DDS_Security_DatawriterCryptoHandle local_reader_crypto = 0;
|
||||
static DDS_Security_DatareaderCryptoHandle remote_writer_crypto = 0;
|
||||
|
||||
static DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle;
|
||||
|
||||
static void allocate_shared_secret(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(unsigned char));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
|
||||
for (i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
}
|
||||
|
||||
static void deallocate_shared_secret(void)
|
||||
{
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
attributes->is_discovery_protected = true;
|
||||
attributes->is_submessage_protected = true;
|
||||
|
||||
attributes->plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int register_local_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
local_particpant_crypto =
|
||||
crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_particpant_crypto == 0)
|
||||
{
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return local_particpant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5;
|
||||
|
||||
remote_particpant_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_particpant_crypto,
|
||||
remote_participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (remote_particpant_crypto == 0)
|
||||
{
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return remote_particpant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_local_datareader(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
|
||||
memset(&datareader_properties, 0, sizeof(datareader_properties));
|
||||
|
||||
prepare_endpoint_security_attributes(&datareader_security_attributes);
|
||||
|
||||
local_reader_crypto =
|
||||
crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_particpant_crypto,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_reader_crypto == 0)
|
||||
{
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return local_reader_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_datawriter(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
remote_writer_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_reader_crypto,
|
||||
remote_particpant_crypto,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (remote_writer_crypto == 0)
|
||||
{
|
||||
printf("register_matched_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return remote_writer_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void suite_create_local_datareader_crypto_tokens_init(void)
|
||||
{
|
||||
allocate_shared_secret();
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_datareader(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_datawriter(), 0);
|
||||
}
|
||||
|
||||
static void suite_create_local_datareader_crypto_tokens_fini(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
if (remote_writer_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, remote_writer_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_reader_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_reader_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (remote_particpant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_particpant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_particpant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_particpant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
deallocate_shared_secret();
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static bool data_not_empty(unsigned char *data, uint32_t length)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (data[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_key_material(DDS_Security_OctetSeq *data)
|
||||
{
|
||||
bool status = true;
|
||||
DDS_Security_Deserializer deserializer;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC key_mat;
|
||||
|
||||
deserializer = DDS_Security_Deserializer_new(data->_buffer, data->_length);
|
||||
if (DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(deserializer, &key_mat))
|
||||
{
|
||||
if (CRYPTO_TRANSFORM_KIND(key_mat.transformation_kind) == CRYPTO_TRANSFORMATION_KIND_AES256_GCM)
|
||||
{
|
||||
printf("check_key_material: incorrect transformation_kind\n");
|
||||
status = false;
|
||||
}
|
||||
else if (CRYPTO_TRANSFORM_ID(key_mat.sender_key_id) == 0)
|
||||
{
|
||||
printf("check_key_material: incorrect sender_key_id\n");
|
||||
status = false;
|
||||
}
|
||||
else if (key_mat.master_salt._length != DDS_SECURITY_MASTER_SALT_SIZE_256)
|
||||
{
|
||||
printf("check_key_material: incorrect master_salt\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!key_mat.master_salt._buffer)
|
||||
{
|
||||
printf("check_key_material: incorrect master_salt\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!data_not_empty(key_mat.master_salt._buffer, key_mat.master_salt._length))
|
||||
{
|
||||
printf("check_key_material: incorrect master_salt\n");
|
||||
status = false;
|
||||
}
|
||||
else if (key_mat.master_sender_key._length != DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256)
|
||||
{
|
||||
printf("check_key_material: incorrect master_sender_key\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!key_mat.master_salt._buffer)
|
||||
{
|
||||
printf("check_key_material: incorrect master_sender_key\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!data_not_empty(key_mat.master_sender_key._buffer, key_mat.master_sender_key._length))
|
||||
{
|
||||
printf("check_key_material: incorrect master_sender_key\n");
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
|
||||
DDS_Security_Deserializer_free(deserializer);
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&key_mat);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool check_token_validity(const DDS_Security_DatawriterCryptoTokenSeq *tokens)
|
||||
{
|
||||
bool status = true;
|
||||
uint32_t i;
|
||||
|
||||
if (tokens->_length != 1 || tokens->_buffer == NULL)
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
|
||||
for (i = 0; status && (i < tokens->_length); i++)
|
||||
{
|
||||
status = (tokens->_buffer[i].class_id != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_CLASS_ID, tokens->_buffer[i].class_id) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._length == 1) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer != NULL) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].name != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_PROPERTY_NAME, tokens->_buffer[i].binary_properties._buffer[0].name) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._length > 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._buffer != NULL);
|
||||
|
||||
if (status)
|
||||
{
|
||||
status = check_key_material(&tokens->_buffer[i].binary_properties._buffer[0].value);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_create_local_datareader_crypto_tokens, happy_day, .init = suite_create_local_datareader_crypto_tokens_init, .fini = suite_create_local_datareader_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_datareader_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->create_local_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_reader_crypto,
|
||||
remote_writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
CU_ASSERT(check_token_validity(&tokens));
|
||||
|
||||
result = crypto->crypto_key_exchange->return_crypto_tokens(crypto->crypto_key_exchange, &tokens, &exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("return_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_create_local_datareader_crypto_tokens, invalid_args, .init = suite_create_local_datareader_crypto_tokens_init, .fini = suite_create_local_datareader_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_datareader_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* invalid token seq = NULL */
|
||||
result = crypto->crypto_key_exchange->create_local_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
NULL,
|
||||
local_reader_crypto,
|
||||
remote_writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
0,
|
||||
remote_writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->create_local_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_reader_crypto,
|
||||
0,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->create_local_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
1,
|
||||
remote_writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->create_local_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_reader_crypto,
|
||||
1,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
|
@ -0,0 +1,505 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
#define CRYPTO_TRANSFORM_KIND(k) (*(uint32_t *)&((k)[0]))
|
||||
#define CRYPTO_TRANSFORM_ID(k) (*(uint32_t *)&((k)[0]))
|
||||
|
||||
static const char *CRYPTO_TOKEN_CLASS_ID = "DDS:Crypto:AES_GCM_GMAC";
|
||||
static const char *CRYPTO_TOKEN_PROPERTY_NAME = "dds.cryp.keymat";
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static DDS_Security_IdentityHandle local_participant_identity = 1;
|
||||
static DDS_Security_IdentityHandle remote_participant_identity = 2;
|
||||
|
||||
static DDS_Security_ParticipantCryptoHandle local_particpant_crypto = 0;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_particpant_crypto = 0;
|
||||
static DDS_Security_DatawriterCryptoHandle local_writer_crypto = 0;
|
||||
static DDS_Security_DatareaderCryptoHandle remote_reader_crypto = 0;
|
||||
|
||||
static DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle;
|
||||
|
||||
static void allocate_shared_secret(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(unsigned char));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
|
||||
for (i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
}
|
||||
|
||||
static void deallocate_shared_secret(void)
|
||||
{
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int register_local_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
local_particpant_crypto =
|
||||
crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_particpant_crypto == 0)
|
||||
{
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return local_particpant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5;
|
||||
|
||||
remote_particpant_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_particpant_crypto,
|
||||
remote_participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (remote_particpant_crypto == 0)
|
||||
{
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return remote_particpant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
attributes->is_discovery_protected = true;
|
||||
attributes->is_submessage_protected = true;
|
||||
|
||||
attributes->plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int register_local_datawriter(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
prepare_endpoint_security_attributes(&datawriter_security_attributes);
|
||||
datawriter_security_attributes.is_payload_protected = true;
|
||||
datawriter_security_attributes.plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED;
|
||||
|
||||
local_writer_crypto =
|
||||
crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_particpant_crypto,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_writer_crypto == 0)
|
||||
{
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return local_writer_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_datareader(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
remote_reader_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_writer_crypto,
|
||||
remote_particpant_crypto,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
if (remote_reader_crypto == 0)
|
||||
{
|
||||
printf("register_matched_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return remote_reader_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void suite_create_local_datawriter_crypto_tokens_init(void)
|
||||
{
|
||||
allocate_shared_secret();
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_datawriter(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_datareader(), 0);
|
||||
}
|
||||
|
||||
static void suite_create_local_datawriter_crypto_tokens_fini(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
if (remote_reader_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, remote_reader_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_writer_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, local_writer_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (remote_particpant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_particpant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_particpant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_particpant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
deallocate_shared_secret();
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static bool data_not_empty(unsigned char *data, uint32_t length)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (data[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_key_material(DDS_Security_OctetSeq *data)
|
||||
{
|
||||
bool status = true;
|
||||
DDS_Security_Deserializer deserializer;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC key_mat;
|
||||
|
||||
deserializer = DDS_Security_Deserializer_new(data->_buffer, data->_length);
|
||||
if (DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(deserializer, &key_mat))
|
||||
{
|
||||
if (CRYPTO_TRANSFORM_KIND(key_mat.transformation_kind) == CRYPTO_TRANSFORMATION_KIND_AES256_GCM)
|
||||
{
|
||||
printf("check_key_material: incorrect transformation_kind\n");
|
||||
status = false;
|
||||
}
|
||||
else if (CRYPTO_TRANSFORM_ID(key_mat.sender_key_id) == 0)
|
||||
{
|
||||
printf("check_key_material: incorrect sender_key_id\n");
|
||||
status = false;
|
||||
}
|
||||
else if (key_mat.master_salt._length != DDS_SECURITY_MASTER_SALT_SIZE_256)
|
||||
{
|
||||
printf("check_key_material: incorrect master_salt\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!key_mat.master_salt._buffer)
|
||||
{
|
||||
printf("check_key_material: incorrect master_salt\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!data_not_empty(key_mat.master_salt._buffer, key_mat.master_salt._length))
|
||||
{
|
||||
printf("check_key_material: incorrect master_salt\n");
|
||||
status = false;
|
||||
}
|
||||
else if (key_mat.master_sender_key._length != DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256)
|
||||
{
|
||||
printf("check_key_material: incorrect master_sender_key\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!key_mat.master_salt._buffer)
|
||||
{
|
||||
printf("check_key_material: incorrect master_sender_key\n");
|
||||
status = false;
|
||||
}
|
||||
else if (!data_not_empty(key_mat.master_sender_key._buffer, key_mat.master_sender_key._length))
|
||||
{
|
||||
printf("check_key_material: incorrect master_sender_key\n");
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
|
||||
DDS_Security_Deserializer_free(deserializer);
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&key_mat);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool check_token_validity(const DDS_Security_DatawriterCryptoTokenSeq *tokens)
|
||||
{
|
||||
bool status = true;
|
||||
uint32_t i;
|
||||
|
||||
if (tokens->_length != 2 || tokens->_buffer == NULL)
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
|
||||
for (i = 0; status && (i < tokens->_length); i++)
|
||||
{
|
||||
status = (tokens->_buffer[i].class_id != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_CLASS_ID, tokens->_buffer[i].class_id) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._length == 1) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer != NULL) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].name != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_PROPERTY_NAME, tokens->_buffer[i].binary_properties._buffer[0].name) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._length > 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._buffer != NULL);
|
||||
|
||||
if (status)
|
||||
{
|
||||
status = check_key_material(&tokens->_buffer[i].binary_properties._buffer[0].value);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_create_local_datawriter_crypto_tokens, happy_day, .init = suite_create_local_datawriter_crypto_tokens_init, .fini = suite_create_local_datawriter_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
CU_ASSERT(check_token_validity(&tokens));
|
||||
|
||||
result = crypto->crypto_key_exchange->return_crypto_tokens(crypto->crypto_key_exchange, &tokens, &exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("return_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_create_local_datawriter_crypto_tokens, invalid_args, .init = suite_create_local_datawriter_crypto_tokens_init, .fini = suite_create_local_datawriter_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* invalid token seq = NULL */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
NULL,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
0,
|
||||
remote_reader_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_writer_crypto,
|
||||
0,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
1,
|
||||
remote_reader_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_writer_crypto,
|
||||
1,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static const char *CRYPTO_TOKEN_CLASS_ID = "DDS:Crypto:AES_GCM_GMAC";
|
||||
static const char *CRYPTO_TOKEN_PROPERTY_NAME = "dds.cryp.keymat";
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static DDS_Security_ParticipantCryptoHandle local_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static void allocate_shared_secret(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(DDS_Security_octet));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
|
||||
for (i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
}
|
||||
|
||||
static void deallocate_shared_secret(void)
|
||||
{
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int register_participants(void)
|
||||
{
|
||||
int r = 0;
|
||||
DDS_Security_IdentityHandle participant_identity = 5; /* valid dummy value */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; /* valid but dummy value */
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5; /*valid dummy value */
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
local_crypto_handle =
|
||||
crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_crypto_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
{
|
||||
r = -1;
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
remote_crypto_handle =
|
||||
crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_crypto_handle,
|
||||
participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
if (remote_crypto_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
{
|
||||
r = -1;
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void unregister_participants(void)
|
||||
{
|
||||
DDS_Security_boolean status;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
if (local_crypto_handle)
|
||||
{
|
||||
status = crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, local_crypto_handle, &exception);
|
||||
if (!status)
|
||||
{
|
||||
printf("unregister_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
}
|
||||
|
||||
if (remote_crypto_handle)
|
||||
{
|
||||
status = crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_crypto_handle, &exception);
|
||||
if (!status)
|
||||
{
|
||||
printf("unregister_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void suite_create_local_participant_crypto_tokens_init(void)
|
||||
{
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
allocate_shared_secret();
|
||||
CU_ASSERT_EQUAL_FATAL (register_participants(), 0);
|
||||
}
|
||||
|
||||
static void suite_create_local_participant_crypto_tokens_fini(void)
|
||||
{
|
||||
unregister_participants();
|
||||
deallocate_shared_secret();
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean check_token_validity(const DDS_Security_ParticipantCryptoTokenSeq *tokens)
|
||||
{
|
||||
DDS_Security_boolean status = true;
|
||||
uint32_t i;
|
||||
|
||||
if (tokens->_length == 0 || tokens->_buffer == NULL)
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
|
||||
for (i = 0; status && (i < tokens->_length); i++)
|
||||
{
|
||||
status = (tokens->_buffer[i].class_id != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_CLASS_ID, tokens->_buffer[i].class_id) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._length == 1) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer != NULL) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].name != NULL) &&
|
||||
(strcmp(CRYPTO_TOKEN_PROPERTY_NAME, tokens->_buffer[i].binary_properties._buffer[0].name) == 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._length > 0) &&
|
||||
(tokens->_buffer[i].binary_properties._buffer[0].value._buffer != NULL);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_create_local_participant_crypto_tokens, happy_day, .init = suite_create_local_participant_crypto_tokens_init, .fini = suite_create_local_participant_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_ParticipantCryptoTokenSeq tokens;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_participant_crypto_tokens != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->create_local_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&exception);
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
CU_ASSERT(check_token_validity(&tokens));
|
||||
|
||||
result = crypto->crypto_key_exchange->return_crypto_tokens(crypto->crypto_key_exchange, &tokens, &exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("return_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_create_local_participant_crypto_tokens, invalid_args, .init = suite_create_local_participant_crypto_tokens_init, .fini = suite_create_local_participant_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_ParticipantCryptoTokenSeq tokens;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_participant_crypto_tokens != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* invalid token seq = NULL */
|
||||
result = crypto->crypto_key_exchange->create_local_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
NULL,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&exception);
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->create_local_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
0,
|
||||
remote_crypto_handle,
|
||||
&exception);
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->create_local_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_crypto_handle,
|
||||
0,
|
||||
&exception);
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->create_local_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
1,
|
||||
remote_crypto_handle,
|
||||
&exception);
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->create_local_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_crypto_handle,
|
||||
1,
|
||||
&exception);
|
||||
if (!result)
|
||||
{
|
||||
printf("create_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,786 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "common/src/crypto_helper.h"
|
||||
#include "crypto_objects.h"
|
||||
#include "crypto_utils.h"
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static DDS_Security_IdentityHandle g_local_participant_identity = 1;
|
||||
static DDS_Security_IdentityHandle g_remote_participant_identity = 2;
|
||||
|
||||
static DDS_Security_ParticipantCryptoHandle g_local_participant_crypto = 0;
|
||||
static DDS_Security_ParticipantCryptoHandle g_remote_participant_crypto = 0;
|
||||
|
||||
static DDS_Security_SharedSecretHandle g_shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static const char *SAMPLE_TEST_DATA =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxy";
|
||||
|
||||
struct crypto_header
|
||||
{
|
||||
struct CryptoTransformIdentifier transform_identifier;
|
||||
unsigned char session_id[4];
|
||||
unsigned char init_vector_suffix[8];
|
||||
};
|
||||
|
||||
struct crypto_footer
|
||||
{
|
||||
unsigned char common_mac[16];
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void allocate_shared_secret(void)
|
||||
{
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl;
|
||||
int32_t i;
|
||||
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(unsigned char));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
|
||||
for (i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
|
||||
g_shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
}
|
||||
|
||||
static void deallocate_shared_secret(void)
|
||||
{
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = (DDS_Security_SharedSecretHandleImpl *)g_shared_secret_handle;
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int register_local_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
g_local_participant_crypto =
|
||||
crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
g_local_participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (g_local_participant_crypto == 0)
|
||||
{
|
||||
printf("[ERROR] register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return g_local_participant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static void unregister_local_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
if (g_local_participant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, g_local_participant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
}
|
||||
|
||||
static int register_remote_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5;
|
||||
|
||||
g_remote_participant_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
g_local_participant_crypto,
|
||||
g_remote_participant_identity,
|
||||
remote_participant_permissions,
|
||||
g_shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (g_remote_participant_crypto == 0)
|
||||
{
|
||||
printf("[ERROR] register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return g_remote_participant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static void unregister_remote_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
if (g_remote_participant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, g_remote_participant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
}
|
||||
|
||||
static DDS_Security_DatawriterCryptoHandle register_local_datawriter(bool encrypted)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
memset(&datawriter_security_attributes, 0, sizeof(datawriter_security_attributes));
|
||||
datawriter_security_attributes.is_payload_protected = true;
|
||||
if (encrypted)
|
||||
{
|
||||
datawriter_security_attributes.plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED;
|
||||
}
|
||||
|
||||
writer_crypto =
|
||||
crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
g_local_participant_crypto,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (writer_crypto == 0)
|
||||
{
|
||||
printf("[ERROR] register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return writer_crypto;
|
||||
}
|
||||
|
||||
static void unregister_local_datawriter(DDS_Security_DatawriterCryptoHandle writer_crypto)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
if (writer_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, writer_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
}
|
||||
|
||||
static DDS_Security_DatareaderCryptoHandle register_remote_datareader(DDS_Security_DatawriterCryptoHandle writer_crypto)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle reader_crypto;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
|
||||
reader_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
writer_crypto,
|
||||
g_remote_participant_crypto,
|
||||
g_shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
if (reader_crypto == 0)
|
||||
{
|
||||
printf("[ERROR] register_matched_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return reader_crypto;
|
||||
}
|
||||
|
||||
static void unregister_remote_datareader(DDS_Security_DatareaderCryptoHandle reader_crypto)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
if (reader_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, reader_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
}
|
||||
|
||||
static bool split_encoded_data(unsigned char *data, uint32_t size, struct crypto_header **header, DDS_Security_OctetSeq *payload, struct crypto_footer **footer, bool encrypted)
|
||||
{
|
||||
/* The length is the length of the encrypted data and the common_mac of the footer
|
||||
* For the serialized payload the footer consists of the common_mac and the length
|
||||
* of the receiver_specific_mac which is set to 0 */
|
||||
static const uint32_t FOOTER_SIZE = 20;
|
||||
unsigned char *header_ptr;
|
||||
unsigned char *payload_ptr;
|
||||
unsigned char *footer_ptr;
|
||||
uint32_t payload_size;
|
||||
|
||||
if (size < (sizeof(struct crypto_header) + FOOTER_SIZE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
header_ptr = data;
|
||||
payload_ptr = data + sizeof(struct crypto_header);
|
||||
footer_ptr = data + size - FOOTER_SIZE;
|
||||
|
||||
/* Get header. */
|
||||
*header = (struct crypto_header *)header_ptr;
|
||||
|
||||
/* Get payload */
|
||||
payload_size = (uint32_t)(footer_ptr - payload_ptr);
|
||||
if (encrypted)
|
||||
{
|
||||
/* CryptoContent starts with 4 bytes length. */
|
||||
if (payload_size < 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
payload->_length = ddsrt_fromBE4u(*(uint32_t *)payload_ptr);
|
||||
payload->_buffer = payload_ptr + 4;
|
||||
if ((payload_size - 4) != payload->_length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just the clear payload */
|
||||
payload->_length = payload_size;
|
||||
payload->_buffer = payload_ptr;
|
||||
}
|
||||
payload->_maximum = payload->_length;
|
||||
|
||||
/* Get footer. */
|
||||
*footer = (struct crypto_footer *)footer_ptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool crypto_decrypt_data(uint32_t session_id, unsigned char *iv, DDS_Security_CryptoTransformKind transformation_kind, master_key_material *key_material, DDS_Security_OctetSeq *encrypted, DDS_Security_OctetSeq *decoded, unsigned char *tag)
|
||||
{
|
||||
bool result = true;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
crypto_session_key_t session_key;
|
||||
uint32_t key_size = crypto_get_key_size(CRYPTO_TRANSFORM_KIND(transformation_kind));
|
||||
int len = 0;
|
||||
|
||||
if (!crypto_calculate_session_key_test(&session_key, session_id, key_material->master_salt, key_material->master_sender_key, key_material->transformation_kind))
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not calculate session key!\n", __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create the cipher context */
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx)
|
||||
{
|
||||
if (key_size == 128)
|
||||
{
|
||||
if (!EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL))
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not get init CIPHER_CTX (128)\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (key_size == 256)
|
||||
{
|
||||
if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not get init CIPHER_CTX (256)\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not determine keysize\n", __LINE__);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not get new CIPHER_CTX\n", __LINE__);
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (!EVP_DecryptInit_ex(ctx, NULL, NULL, session_key.data, iv))
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not init Decrypt\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (decoded)
|
||||
{
|
||||
if (EVP_DecryptUpdate(ctx, decoded->_buffer, &len, encrypted->_buffer, (int) encrypted->_length))
|
||||
{
|
||||
decoded->_length = (uint32_t) len;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not update Decrypt (decoded)\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!EVP_DecryptUpdate(ctx, NULL, &len, encrypted->_buffer, (int) encrypted->_length))
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not update Decrypt (!decoded)\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, CRYPTO_HMAC_SIZE, tag))
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not ctrl CIPHER_CTX\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (decoded)
|
||||
{
|
||||
if (EVP_DecryptFinal_ex(ctx, decoded->_buffer + len, &len))
|
||||
{
|
||||
decoded->_length += (uint32_t) len;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not finalize Decrypt (decoded)\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char temp[32];
|
||||
if (!EVP_DecryptFinal_ex(ctx, temp, &len))
|
||||
{
|
||||
printf("[ERROR] (%d) crypto_decrypt_data: could not finalize Decrypt (!decoded)\n", __LINE__);
|
||||
ERR_print_errors_fp(stderr);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx)
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static session_key_material * get_datawriter_session(DDS_Security_DatawriterCryptoHandle writer_crypto)
|
||||
{
|
||||
local_datawriter_crypto *writer_crypto_impl = (local_datawriter_crypto *)writer_crypto;
|
||||
return writer_crypto_impl->writer_session_payload;
|
||||
}
|
||||
|
||||
static bool check_protection_kind(DDS_Security_DatawriterCryptoHandle writer_crypto, DDS_Security_BasicProtectionKind protection_kind)
|
||||
{
|
||||
local_datawriter_crypto *writer_crypto_impl = (local_datawriter_crypto *)writer_crypto;
|
||||
return (writer_crypto_impl->data_protectionKind == protection_kind);
|
||||
}
|
||||
|
||||
static void suite_encode_serialized_payload_init(void)
|
||||
{
|
||||
allocate_shared_secret();
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_participant(), 0);
|
||||
}
|
||||
|
||||
static void suite_encode_serialized_payload_fini(void)
|
||||
{
|
||||
unregister_remote_participant();
|
||||
unregister_local_participant();
|
||||
unload_plugins(plugins);
|
||||
deallocate_shared_secret();
|
||||
}
|
||||
|
||||
static uint32_t get_transformation_kind(uint32_t key_size, bool encrypted)
|
||||
{
|
||||
uint32_t kind = CRYPTO_TRANSFORMATION_KIND_INVALID;
|
||||
if (key_size == 128)
|
||||
{
|
||||
kind = encrypted ? CRYPTO_TRANSFORMATION_KIND_AES128_GCM : CRYPTO_TRANSFORMATION_KIND_AES128_GMAC;
|
||||
}
|
||||
else if (key_size == 256)
|
||||
{
|
||||
kind = encrypted ? CRYPTO_TRANSFORMATION_KIND_AES256_GCM : CRYPTO_TRANSFORMATION_KIND_AES256_GMAC;
|
||||
}
|
||||
CU_ASSERT_FATAL(kind != CRYPTO_TRANSFORMATION_KIND_INVALID);
|
||||
return kind;
|
||||
}
|
||||
|
||||
static bool seq_equal(DDS_Security_OctetSeq *seq1, DDS_Security_OctetSeq *seq2)
|
||||
{
|
||||
bool ok = false;
|
||||
if (seq1->_length == seq2->_length)
|
||||
{
|
||||
if (memcmp(seq1->_buffer, seq2->_buffer, seq1->_length) == 0)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool check_payload_signed(DDS_Security_OctetSeq *payload, DDS_Security_OctetSeq *plain_buffer)
|
||||
{
|
||||
/* When only signed, the payload should not have changed. */
|
||||
return seq_equal(payload, plain_buffer);
|
||||
}
|
||||
|
||||
static bool check_payload_encrypted(DDS_Security_OctetSeq *payload, DDS_Security_OctetSeq *plain_buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
/* When encrypted, the payload should differ from the original data. */
|
||||
if (payload->_length >= plain_buffer->_length)
|
||||
{
|
||||
if (memcmp(payload->_buffer, plain_buffer->_buffer, plain_buffer->_length) != 0)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool check_payload_encoded(DDS_Security_OctetSeq *payload, DDS_Security_OctetSeq *plain_buffer, bool encrypted)
|
||||
{
|
||||
bool ok;
|
||||
if (encrypted)
|
||||
{
|
||||
ok = check_payload_encrypted(payload, plain_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = check_payload_signed(payload, plain_buffer);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool check_payload_decoded(DDS_Security_OctetSeq *payload, DDS_Security_OctetSeq *plain_buffer)
|
||||
{
|
||||
/* After decoding, the payload should match the orignal. */
|
||||
return seq_equal(payload, plain_buffer);
|
||||
}
|
||||
|
||||
static void encode_serialized_payload_check(uint32_t key_size, bool encrypted)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_OctetSeq encoded_buffer = {0, 0, NULL};
|
||||
DDS_Security_OctetSeq extra_inline_qos;
|
||||
DDS_Security_OctetSeq encoded_payload;
|
||||
DDS_Security_OctetSeq plain_buffer;
|
||||
session_key_material *session_keys;
|
||||
struct crypto_header *header = NULL;
|
||||
struct crypto_footer *footer = NULL;
|
||||
uint32_t session_id;
|
||||
size_t length;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_transform != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_transform->encode_serialized_payload != NULL);
|
||||
|
||||
memset(&extra_inline_qos, 0, sizeof(extra_inline_qos));
|
||||
|
||||
length = strlen(SAMPLE_TEST_DATA) + 1;
|
||||
plain_buffer._length = plain_buffer._maximum = (uint32_t) length;
|
||||
plain_buffer._buffer = DDS_Security_OctetSeq_allocbuf((uint32_t) length);
|
||||
memcpy((char *)plain_buffer._buffer, SAMPLE_TEST_DATA, length);
|
||||
|
||||
writer_crypto = register_local_datawriter(encrypted);
|
||||
CU_ASSERT_FATAL(writer_crypto != 0);
|
||||
CU_ASSERT(check_protection_kind(writer_crypto, encrypted ? DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT : DDS_SECURITY_BASICPROTECTION_KIND_SIGN));
|
||||
|
||||
session_keys = get_datawriter_session(writer_crypto);
|
||||
session_keys->master_key_material->transformation_kind = get_transformation_kind(key_size, encrypted);
|
||||
session_keys->key_size = key_size;
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_transform->encode_serialized_payload(
|
||||
crypto->crypto_transform,
|
||||
&encoded_buffer,
|
||||
&extra_inline_qos,
|
||||
&plain_buffer,
|
||||
writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("[ERROR] encode_serialized_payload: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
result = split_encoded_data(encoded_buffer._buffer, encoded_buffer._length, &header, &encoded_payload, &footer, encrypted);
|
||||
CU_ASSERT_FATAL(result == true);
|
||||
CU_ASSERT(check_payload_encoded(&encoded_payload, &plain_buffer, encrypted));
|
||||
|
||||
session_id = ddsrt_fromBE4u(*(uint32_t *)header->session_id);
|
||||
|
||||
if (encrypted)
|
||||
{
|
||||
DDS_Security_OctetSeq decoded_buffer;
|
||||
decoded_buffer._buffer = ddsrt_malloc(length);
|
||||
decoded_buffer._length = (uint32_t) length;
|
||||
decoded_buffer._maximum = (uint32_t) length;
|
||||
result = crypto_decrypt_data(session_id, &header->session_id[0], header->transform_identifier.transformation_kind, session_keys->master_key_material, &encoded_payload, &decoded_buffer, footer->common_mac);
|
||||
if (!result)
|
||||
{
|
||||
printf("[ERROR] Decryption failed\n");
|
||||
}
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(check_payload_decoded(&decoded_buffer, &plain_buffer));
|
||||
DDS_Security_OctetSeq_deinit(&decoded_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = crypto_decrypt_data(session_id, &header->session_id[0], header->transform_identifier.transformation_kind, session_keys->master_key_material, &encoded_payload, NULL, footer->common_mac);
|
||||
if (!result)
|
||||
{
|
||||
printf("[ERROR] Signature check failed\n");
|
||||
}
|
||||
CU_ASSERT_FATAL(result);
|
||||
}
|
||||
|
||||
DDS_Security_OctetSeq_deinit(&encoded_buffer);
|
||||
DDS_Security_OctetSeq_deinit(&plain_buffer);
|
||||
|
||||
unregister_local_datawriter(writer_crypto);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_encode_serialized_payload, encrypt_128, .init = suite_encode_serialized_payload_init, .fini = suite_encode_serialized_payload_fini)
|
||||
{
|
||||
encode_serialized_payload_check(128, true);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_encode_serialized_payload, encrypt_256, .init = suite_encode_serialized_payload_init, .fini = suite_encode_serialized_payload_fini)
|
||||
{
|
||||
encode_serialized_payload_check(256, true);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_encode_serialized_payload, sign_128, .init = suite_encode_serialized_payload_init, .fini = suite_encode_serialized_payload_fini)
|
||||
{
|
||||
encode_serialized_payload_check(128, false);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_encode_serialized_payload, sign_256, .init = suite_encode_serialized_payload_init, .fini = suite_encode_serialized_payload_fini)
|
||||
{
|
||||
encode_serialized_payload_check(256, false);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_encode_serialized_payload, invalid_args, .init = suite_encode_serialized_payload_init, .fini = suite_encode_serialized_payload_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_DatareaderCryptoHandle reader_crypto;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_OctetSeq encoded_buffer = {0, 0, NULL};
|
||||
DDS_Security_OctetSeq extra_inline_qos;
|
||||
DDS_Security_OctetSeq plain_buffer;
|
||||
DDS_Security_OctetSeq empty_buffer;
|
||||
size_t length;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_transform != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_transform->encode_serialized_payload != NULL);
|
||||
|
||||
writer_crypto = register_local_datawriter(true);
|
||||
CU_ASSERT_FATAL(writer_crypto != 0);
|
||||
|
||||
reader_crypto = register_remote_datareader(writer_crypto);
|
||||
CU_ASSERT_FATAL(reader_crypto != 0);
|
||||
|
||||
memset(&extra_inline_qos, 0, sizeof(extra_inline_qos));
|
||||
memset(&empty_buffer, 0, sizeof(empty_buffer));
|
||||
|
||||
length = strlen(SAMPLE_TEST_DATA) + 1;
|
||||
plain_buffer._length = plain_buffer._maximum = (uint32_t) length;
|
||||
plain_buffer._buffer = DDS_Security_OctetSeq_allocbuf((uint32_t) length);
|
||||
memcpy((char *)plain_buffer._buffer, SAMPLE_TEST_DATA, length);
|
||||
|
||||
/* no encoded data specified */
|
||||
result = crypto->crypto_transform->encode_serialized_payload(
|
||||
crypto->crypto_transform,
|
||||
NULL,
|
||||
&extra_inline_qos,
|
||||
&plain_buffer,
|
||||
writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("encode_serialized_payload: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* no plain data specified */
|
||||
result = crypto->crypto_transform->encode_serialized_payload(
|
||||
crypto->crypto_transform,
|
||||
&encoded_buffer,
|
||||
&extra_inline_qos,
|
||||
NULL,
|
||||
writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("encode_serialized_payload: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
unregister_local_datawriter(writer_crypto);
|
||||
|
||||
/* empty plain data specified */
|
||||
result = crypto->crypto_transform->encode_serialized_payload(
|
||||
crypto->crypto_transform,
|
||||
&encoded_buffer,
|
||||
&extra_inline_qos,
|
||||
&empty_buffer,
|
||||
writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("encode_serialized_payload: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* unknown writer crypto handle specified */
|
||||
result = crypto->crypto_transform->encode_serialized_payload(
|
||||
crypto->crypto_transform,
|
||||
&encoded_buffer,
|
||||
&extra_inline_qos,
|
||||
&plain_buffer,
|
||||
0,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("encode_serialized_payload: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* incorrect writer crypto handle specified */
|
||||
result = crypto->crypto_transform->encode_serialized_payload(
|
||||
crypto->crypto_transform,
|
||||
&encoded_buffer,
|
||||
&extra_inline_qos,
|
||||
&plain_buffer,
|
||||
reader_crypto,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("encode_serialized_payload: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
unregister_remote_datareader(reader_crypto);
|
||||
unregister_local_datawriter(writer_crypto);
|
||||
|
||||
DDS_Security_OctetSeq_deinit(&plain_buffer);
|
||||
}
|
||||
|
|
@ -31,27 +31,14 @@
|
|||
#include <string.h>
|
||||
#include "dds/ddsrt/environ.h"
|
||||
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/misc.h"
|
||||
#include "dds/ddsrt/endian.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
|
||||
#define HANDSHAKE_SIGNATURE_SIZE 6
|
||||
|
||||
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
|
||||
static unsigned bswap4u (unsigned x)
|
||||
{
|
||||
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
|
||||
}
|
||||
#define toBE4u(x) bswap4u (x)
|
||||
#define fromBE4u(x) bswap4u (x)
|
||||
#else
|
||||
#define toBE4u(x) (x)
|
||||
#define fromBE4u(x) (x)
|
||||
#endif
|
||||
|
||||
|
||||
static const char * AUTH_PROTOCOL_CLASS_ID = "DDS:Auth:PKI-DH:1.0";
|
||||
static const char * PERM_ACCESS_CLASS_ID = "DDS:Access:Permissions:1.0";
|
||||
|
||||
|
@ -483,9 +470,9 @@ validate_local_identity(void)
|
|||
g_local_participant_data = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&g_local_participant_data->key[0], &local_participant_guid, 12);
|
||||
/* convert from big-endian format to native format */
|
||||
g_local_participant_data->key[0] = fromBE4u(g_local_participant_data->key[0]);
|
||||
g_local_participant_data->key[1] = fromBE4u(g_local_participant_data->key[1]);
|
||||
g_local_participant_data->key[2] = fromBE4u(g_local_participant_data->key[2]);
|
||||
g_local_participant_data->key[0] = ddsrt_fromBE4u(g_local_participant_data->key[0]);
|
||||
g_local_participant_data->key[1] = ddsrt_fromBE4u(g_local_participant_data->key[1]);
|
||||
g_local_participant_data->key[2] = ddsrt_fromBE4u(g_local_participant_data->key[2]);
|
||||
|
||||
initialize_identity_token(&g_local_participant_data->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&g_local_participant_data->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -843,9 +830,9 @@ validate_remote_identities (const char *remote_id_certificate)
|
|||
|
||||
g_remote_participant_data1 = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&g_remote_participant_data1->key[0], &g_remote_participant_guid1, 12);
|
||||
g_remote_participant_data1->key[0] = fromBE4u(g_remote_participant_data1->key[0]);
|
||||
g_remote_participant_data1->key[1] = fromBE4u(g_remote_participant_data1->key[1]);
|
||||
g_remote_participant_data1->key[2] = fromBE4u(g_remote_participant_data1->key[2]);
|
||||
g_remote_participant_data1->key[0] = ddsrt_fromBE4u(g_remote_participant_data1->key[0]);
|
||||
g_remote_participant_data1->key[1] = ddsrt_fromBE4u(g_remote_participant_data1->key[1]);
|
||||
g_remote_participant_data1->key[2] = ddsrt_fromBE4u(g_remote_participant_data1->key[2]);
|
||||
|
||||
initialize_identity_token(&g_remote_participant_data1->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&g_remote_participant_data1->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -855,9 +842,9 @@ validate_remote_identities (const char *remote_id_certificate)
|
|||
|
||||
g_remote_participant_data2 = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&g_remote_participant_data2->key[0], &g_remote_participant_guid2, 12);
|
||||
g_remote_participant_data2->key[0] = fromBE4u(g_remote_participant_data2->key[0]);
|
||||
g_remote_participant_data2->key[1] = fromBE4u(g_remote_participant_data2->key[1]);
|
||||
g_remote_participant_data2->key[2] = fromBE4u(g_remote_participant_data2->key[2]);
|
||||
g_remote_participant_data2->key[0] = ddsrt_fromBE4u(g_remote_participant_data2->key[0]);
|
||||
g_remote_participant_data2->key[1] = ddsrt_fromBE4u(g_remote_participant_data2->key[1]);
|
||||
g_remote_participant_data2->key[2] = ddsrt_fromBE4u(g_remote_participant_data2->key[2]);
|
||||
|
||||
initialize_identity_token(&g_remote_participant_data2->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&g_remote_participant_data2->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -952,7 +939,7 @@ serializer_participant_data(
|
|||
DDS_Security_Serializer serializer;
|
||||
serializer = DDS_Security_Serializer_new(1024, 1024);
|
||||
|
||||
DDD_Security_Serialize_ParticipantBuiltinTopicData(serializer, pdata);
|
||||
DDS_Security_Serialize_ParticipantBuiltinTopicData(serializer, pdata);
|
||||
DDS_Security_Serializer_buffer(serializer, buffer, size);
|
||||
DDS_Security_Serializer_free(serializer);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,930 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
#define VALID_SMID_SEC_PREFIX 0x31
|
||||
#define INVALID_SMID_SEC_PREFIX 0x15
|
||||
|
||||
|
||||
typedef struct SubMessageHeader {
|
||||
unsigned char kind;
|
||||
unsigned char flags;
|
||||
uint16_t octetsToNextSubMsg;
|
||||
} SubMessageHeader;
|
||||
|
||||
typedef struct CryptoHeader {
|
||||
DDS_Security_CryptoTransformKind transform_id;
|
||||
DDS_Security_CryptoTransformKeyId key_id;
|
||||
unsigned char session_id[4];
|
||||
unsigned char initVectorSuffix[8];
|
||||
} CryptoHeader;
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static DDS_Security_IdentityHandle local_participant_identity = 1;
|
||||
static DDS_Security_IdentityHandle remote_participant_identity = 2;
|
||||
|
||||
static DDS_Security_ParticipantCryptoHandle local_participant_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_participant_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static DDS_Security_DatawriterCryptoHandle local_writer_crypto = 0;
|
||||
static DDS_Security_DatawriterCryptoHandle remote_writer_crypto = 0;
|
||||
static DDS_Security_DatareaderCryptoHandle local_reader_crypto = 0;
|
||||
static DDS_Security_DatareaderCryptoHandle remote_reader_crypto = 0;
|
||||
|
||||
static DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle;
|
||||
|
||||
static DDS_Security_KeyMaterial_AES_GCM_GMAC writer_key_message;
|
||||
static DDS_Security_KeyMaterial_AES_GCM_GMAC writer_key_payload;
|
||||
static DDS_Security_KeyMaterial_AES_GCM_GMAC reader_key_message;
|
||||
|
||||
static void allocate_shared_secret(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
shared_secret_handle_impl = ddsrt_malloc (sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc (TEST_SHARED_SECRET_SIZE * sizeof(unsigned char));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
|
||||
for (i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle) shared_secret_handle_impl;
|
||||
}
|
||||
|
||||
static void deallocate_shared_secret(void)
|
||||
{
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static int register_local_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
memset(&participant_security_attributes, 0, sizeof(participant_security_attributes));
|
||||
|
||||
local_participant_handle =
|
||||
crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_participant_handle == DDS_SECURITY_HANDLE_NIL) {
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return local_participant_handle ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5;
|
||||
|
||||
remote_participant_handle =
|
||||
crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_handle,
|
||||
remote_participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (remote_participant_handle == DDS_SECURITY_HANDLE_NIL) {
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return remote_participant_handle ? 0 : -1;
|
||||
}
|
||||
|
||||
static void prepare_endpoint_security_attributes( DDS_Security_EndpointSecurityAttributes *attributes){
|
||||
memset( attributes, 0 , sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
attributes->is_discovery_protected = true;
|
||||
attributes->is_submessage_protected = true;
|
||||
|
||||
attributes->plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
|
||||
|
||||
}
|
||||
|
||||
static int register_local_datareader(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
|
||||
memset(&datareader_properties, 0, sizeof(datareader_properties));
|
||||
prepare_endpoint_security_attributes( &datareader_security_attributes );
|
||||
|
||||
local_reader_crypto =
|
||||
crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_handle,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
|
||||
|
||||
if (local_reader_crypto == 0)
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
return local_reader_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_datareader(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
|
||||
memset (&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
remote_reader_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_writer_crypto,
|
||||
remote_participant_handle,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
if (remote_reader_crypto == 0)
|
||||
printf("register_matched_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
return remote_reader_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_local_datawriter(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
prepare_endpoint_security_attributes( &datawriter_security_attributes );
|
||||
|
||||
local_writer_crypto =
|
||||
crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_handle,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
|
||||
if (local_writer_crypto == 0)
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
return local_writer_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_datawriter(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
remote_writer_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_reader_crypto,
|
||||
remote_participant_handle,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (remote_writer_crypto == 0)
|
||||
printf("register_matched_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
return remote_writer_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean retrieve_datawriter_keys(DDS_Security_DatawriterCryptoTokenSeq *tokens)
|
||||
{
|
||||
DDS_Security_boolean result = true;
|
||||
DDS_Security_Deserializer deserializer;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC *key_mat = &writer_key_message;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; result && (i < tokens->_length); i++) {
|
||||
const DDS_Security_OctetSeq *tdata = &tokens->_buffer[i].binary_properties._buffer[0].value;
|
||||
|
||||
deserializer = DDS_Security_Deserializer_new(tdata->_buffer, tdata->_length);
|
||||
|
||||
if (!deserializer)
|
||||
result = false;
|
||||
else if (!DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(deserializer, key_mat))
|
||||
result = false;
|
||||
|
||||
DDS_Security_Deserializer_free(deserializer);
|
||||
key_mat = &writer_key_payload;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DDS_Security_boolean retrieve_datareader_keys(DDS_Security_DatareaderCryptoTokenSeq *tokens)
|
||||
{
|
||||
DDS_Security_boolean result = true;
|
||||
const DDS_Security_OctetSeq *tdata = &tokens->_buffer[0].binary_properties._buffer[0].value;
|
||||
DDS_Security_Deserializer deserializer;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC *key_mat = &reader_key_message;
|
||||
|
||||
deserializer = DDS_Security_Deserializer_new(tdata->_buffer, tdata->_length);
|
||||
|
||||
if (!deserializer)
|
||||
result = false;
|
||||
else if (!DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(deserializer, key_mat))
|
||||
result = false;
|
||||
DDS_Security_Deserializer_free(deserializer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int set_remote_datawriter_tokens(void)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->create_local_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&exception);
|
||||
|
||||
if (result)
|
||||
result = retrieve_datawriter_keys(&tokens);
|
||||
|
||||
if (result) {
|
||||
result = crypto->crypto_key_exchange->set_remote_datawriter_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_reader_crypto,
|
||||
remote_writer_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
}
|
||||
|
||||
DDS_Security_DataHolderSeq_deinit((DDS_Security_DataHolderSeq*)&tokens);
|
||||
|
||||
return result ? 0 : -1;
|
||||
}
|
||||
|
||||
static int set_remote_datareader_tokens(void)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatareaderCryptoTokenSeq tokens;
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->create_local_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_reader_crypto,
|
||||
remote_writer_crypto,
|
||||
&exception);
|
||||
|
||||
if (result)
|
||||
result = retrieve_datareader_keys(&tokens);
|
||||
if (result) {
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
}
|
||||
|
||||
DDS_Security_DataHolderSeq_deinit((DDS_Security_DataHolderSeq*)&tokens);
|
||||
|
||||
return result ? 0 : -1;
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void suite_preprocess_secure_submsg_init (void)
|
||||
{
|
||||
allocate_shared_secret();
|
||||
memset(&writer_key_message, 0, sizeof(DDS_Security_KeyMaterial_AES_GCM_GMAC));
|
||||
memset(&writer_key_payload, 0, sizeof(DDS_Security_KeyMaterial_AES_GCM_GMAC));
|
||||
memset(&reader_key_message, 0, sizeof(DDS_Security_KeyMaterial_AES_GCM_GMAC));
|
||||
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptography */)) != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_datawriter(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_datareader(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_datareader(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_datawriter(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (set_remote_datawriter_tokens(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (set_remote_datareader_tokens(), 0);
|
||||
}
|
||||
|
||||
static void suite_preprocess_secure_submsg_fini (void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
if (remote_writer_crypto) {
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, remote_writer_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (remote_reader_crypto) {
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, remote_reader_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_reader_crypto) {
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_reader_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_writer_crypto) {
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, local_writer_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (remote_participant_handle) {
|
||||
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_participant_handle, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_participant_handle) {
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_participant_handle, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&reader_key_message);
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&writer_key_message);
|
||||
deallocate_shared_secret();
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static void create_encoded_submsg(DDS_Security_OctetSeq *msg, DDS_Security_CryptoTransformKeyId key_id, DDS_Security_CryptoTransformKind transform_kind, unsigned char msg_id, bool be)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
uint32_t length = sizeof(SubMessageHeader) + sizeof(CryptoHeader) + 200;
|
||||
SubMessageHeader *submsg;
|
||||
CryptoHeader *crpthdr;
|
||||
int swap = be ? (DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN) : (DDSRT_ENDIAN != DDSRT_LITTLE_ENDIAN);
|
||||
|
||||
buffer = ddsrt_malloc(length);
|
||||
submsg = (SubMessageHeader *) buffer;
|
||||
crpthdr = (CryptoHeader *) (submsg + 1);
|
||||
|
||||
submsg->kind = msg_id;
|
||||
submsg->flags = be ? 0 : 1;
|
||||
submsg->octetsToNextSubMsg = swap ? ddsrt_bswap2u((uint16_t)(length - 24)) : (uint16_t)(length - 24);
|
||||
|
||||
memcpy(crpthdr->key_id, key_id, 4);
|
||||
memcpy(crpthdr->transform_id, transform_kind, 4);
|
||||
|
||||
msg->_buffer = buffer;
|
||||
msg->_length = msg->_maximum = length;
|
||||
}
|
||||
|
||||
static void clear_encoded_submsg(DDS_Security_OctetSeq *msg)
|
||||
{
|
||||
if (msg) {
|
||||
ddsrt_free(msg->_buffer);
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CU_Test(ddssec_builtin_preprocess_secure_submsg, writer_happy_day, .init = suite_preprocess_secure_submsg_init, .fini = suite_preprocess_secure_submsg_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_DatareaderCryptoHandle reader_crypto;
|
||||
DDS_Security_SecureSubmessageCategory_t category;
|
||||
DDS_Security_OctetSeq message;
|
||||
|
||||
CU_ASSERT_FATAL (crypto != NULL);
|
||||
CU_ASSERT_FATAL (crypto->crypto_transform != NULL);
|
||||
CU_ASSERT_FATAL (crypto->crypto_transform->preprocess_secure_submsg != NULL);
|
||||
|
||||
create_encoded_submsg(&message, writer_key_message.sender_key_id, writer_key_message.transformation_kind, VALID_SMID_SEC_PREFIX, false);
|
||||
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
CU_ASSERT(writer_crypto == remote_writer_crypto);
|
||||
CU_ASSERT(reader_crypto == local_reader_crypto);
|
||||
CU_ASSERT(category == DDS_SECURITY_DATAWRITER_SUBMESSAGE);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
clear_encoded_submsg(&message);
|
||||
|
||||
create_encoded_submsg(&message, writer_key_message.sender_key_id, writer_key_message.transformation_kind, VALID_SMID_SEC_PREFIX, true);
|
||||
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
CU_ASSERT(writer_crypto == remote_writer_crypto);
|
||||
CU_ASSERT(reader_crypto == local_reader_crypto);
|
||||
CU_ASSERT(category == DDS_SECURITY_DATAWRITER_SUBMESSAGE);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
clear_encoded_submsg(&message);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_preprocess_secure_submsg, reader_happy_day, .init = suite_preprocess_secure_submsg_init, .fini = suite_preprocess_secure_submsg_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_DatareaderCryptoHandle reader_crypto;
|
||||
DDS_Security_SecureSubmessageCategory_t category;
|
||||
DDS_Security_OctetSeq message;
|
||||
|
||||
CU_ASSERT_FATAL (crypto != NULL);
|
||||
CU_ASSERT_FATAL (crypto ->crypto_transform!= NULL);
|
||||
CU_ASSERT_FATAL (crypto ->crypto_transform->preprocess_secure_submsg != NULL);
|
||||
|
||||
create_encoded_submsg(&message, reader_key_message.sender_key_id, reader_key_message.transformation_kind, VALID_SMID_SEC_PREFIX, false);
|
||||
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
CU_ASSERT(writer_crypto == local_writer_crypto);
|
||||
CU_ASSERT(reader_crypto == remote_reader_crypto);
|
||||
CU_ASSERT(category == DDS_SECURITY_DATAREADER_SUBMESSAGE);
|
||||
|
||||
reset_exception(&exception);
|
||||
clear_encoded_submsg(&message);
|
||||
create_encoded_submsg(&message, reader_key_message.sender_key_id, reader_key_message.transformation_kind, VALID_SMID_SEC_PREFIX, true);
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
CU_ASSERT(writer_crypto == local_writer_crypto);
|
||||
CU_ASSERT(reader_crypto == remote_reader_crypto);
|
||||
CU_ASSERT(category == DDS_SECURITY_DATAREADER_SUBMESSAGE);
|
||||
|
||||
reset_exception(&exception);
|
||||
clear_encoded_submsg(&message);
|
||||
}
|
||||
|
||||
|
||||
CU_Test(ddssec_builtin_preprocess_secure_submsg, invalid_args, .init = suite_preprocess_secure_submsg_init, .fini = suite_preprocess_secure_submsg_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_DatareaderCryptoHandle reader_crypto;
|
||||
DDS_Security_SecureSubmessageCategory_t category;
|
||||
DDS_Security_OctetSeq message;
|
||||
|
||||
CU_ASSERT_FATAL (crypto != NULL);
|
||||
CU_ASSERT_FATAL (crypto ->crypto_transform!= NULL);
|
||||
CU_ASSERT_FATAL (crypto ->crypto_transform->preprocess_secure_submsg != NULL);
|
||||
|
||||
create_encoded_submsg(&message, writer_key_message.sender_key_id, reader_key_message.transformation_kind, VALID_SMID_SEC_PREFIX, false);
|
||||
|
||||
/* writer handle = NULL. */
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
NULL,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* reader handle = NULL. */
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
NULL,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* category = NULL */
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
NULL,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* message = NULL */
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
NULL,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* unknown local_participant_handle */
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
1,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* remote_participant_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
0,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* unknown remote_participant_handle */
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
1,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
clear_encoded_submsg(&message);
|
||||
}
|
||||
|
||||
|
||||
CU_Test(ddssec_builtin_preprocess_secure_submsg, invalid_message, .init = suite_preprocess_secure_submsg_init, .fini = suite_preprocess_secure_submsg_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_DatareaderCryptoHandle reader_crypto;
|
||||
DDS_Security_SecureSubmessageCategory_t category;
|
||||
DDS_Security_OctetSeq message;
|
||||
|
||||
CU_ASSERT_FATAL (crypto != NULL);
|
||||
CU_ASSERT_FATAL (crypto ->crypto_transform!= NULL);
|
||||
CU_ASSERT_FATAL (crypto ->crypto_transform->preprocess_secure_submsg != NULL);
|
||||
|
||||
/* unknown key id */
|
||||
create_encoded_submsg(&message, writer_key_payload.sender_key_id, writer_key_payload.transformation_kind, VALID_SMID_SEC_PREFIX, false);
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
clear_encoded_submsg(&message);
|
||||
|
||||
/* invalid transformation kind */
|
||||
{
|
||||
DDS_Security_CryptoTransformKind kind = {5, 1, 3, 6};
|
||||
|
||||
create_encoded_submsg(&message, writer_key_message.sender_key_id, kind, VALID_SMID_SEC_PREFIX, false);
|
||||
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
clear_encoded_submsg(&message);
|
||||
}
|
||||
|
||||
/* not expected submessage id */
|
||||
{
|
||||
DDS_Security_CryptoTransformKind kind = {5, 1, 3, 6};
|
||||
create_encoded_submsg(&message, writer_key_message.sender_key_id, kind, INVALID_SMID_SEC_PREFIX, false);
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
clear_encoded_submsg(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CU_Test(ddssec_builtin_preprocess_secure_submsg, volatile_secure, .init = suite_preprocess_secure_submsg_init, .fini = suite_preprocess_secure_submsg_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatareaderCryptoHandle local_reader_crypto_vol;
|
||||
DDS_Security_DatawriterCryptoHandle local_writer_crypto_vol;
|
||||
DDS_Security_DatareaderCryptoHandle remote_reader_crypto_vol;
|
||||
DDS_Security_DatawriterCryptoHandle remote_writer_crypto_vol;
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
DDS_Security_DatawriterCryptoHandle writer_crypto;
|
||||
DDS_Security_DatareaderCryptoHandle reader_crypto;
|
||||
DDS_Security_SecureSubmessageCategory_t category;
|
||||
DDS_Security_CryptoTransformKeyId key_id = {0, 0, 0, 0};
|
||||
DDS_Security_OctetSeq message;
|
||||
|
||||
CU_ASSERT_FATAL (crypto != NULL);
|
||||
CU_ASSERT_FATAL (crypto->crypto_transform != NULL);
|
||||
CU_ASSERT_FATAL (crypto->crypto_transform->preprocess_secure_submsg != NULL);
|
||||
|
||||
datareader_properties._length = datareader_properties._maximum = 1;
|
||||
datareader_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datareader_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datareader_properties._buffer[0].value = ddsrt_strdup("BuiltinParticipantVolatileMessageSecureReader");
|
||||
datareader_properties._buffer[0].propagate = false;
|
||||
|
||||
prepare_endpoint_security_attributes( &datareader_security_attributes );
|
||||
prepare_endpoint_security_attributes( &datawriter_security_attributes );
|
||||
|
||||
datawriter_properties._length = datawriter_properties._maximum = 1;
|
||||
datawriter_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datawriter_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datawriter_properties._buffer[0].value = ddsrt_strdup("BuiltinParticipantVolatileMessageSecureWriter");
|
||||
datawriter_properties._buffer[0].propagate = false;
|
||||
|
||||
local_writer_crypto_vol =
|
||||
crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_handle,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
CU_ASSERT_FATAL(local_writer_crypto_vol != 0);
|
||||
|
||||
local_reader_crypto_vol =
|
||||
crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_handle,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
CU_ASSERT_FATAL(local_reader_crypto_vol != 0);
|
||||
|
||||
remote_writer_crypto_vol =
|
||||
crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_reader_crypto_vol,
|
||||
remote_participant_handle,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
CU_ASSERT_FATAL(remote_writer_crypto_vol != 0);
|
||||
|
||||
remote_reader_crypto_vol =
|
||||
crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_writer_crypto_vol,
|
||||
remote_participant_handle,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
CU_ASSERT_FATAL(remote_reader_crypto_vol != 0);
|
||||
|
||||
create_encoded_submsg(&message, key_id, reader_key_message.transformation_kind, VALID_SMID_SEC_PREFIX, false);
|
||||
|
||||
result = crypto->crypto_transform->preprocess_secure_submsg(
|
||||
crypto->crypto_transform,
|
||||
&writer_crypto,
|
||||
&reader_crypto,
|
||||
&category,
|
||||
&message,
|
||||
local_participant_handle,
|
||||
remote_participant_handle,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("preprocess_secure_submsg: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
CU_ASSERT(((remote_datawriter_crypto *)writer_crypto)->is_builtin_participant_volatile_message_secure_writer);
|
||||
CU_ASSERT(((local_datareader_crypto *)reader_crypto)->is_builtin_participant_volatile_message_secure_reader);
|
||||
CU_ASSERT(category == DDS_SECURITY_DATAWRITER_SUBMESSAGE);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
if (remote_writer_crypto_vol) {
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, remote_writer_crypto_vol, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (remote_reader_crypto_vol) {
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, remote_reader_crypto_vol, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_reader_crypto_vol) {
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_reader_crypto_vol, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_writer_crypto_vol) {
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, local_writer_crypto_vol, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
clear_encoded_submsg(&message);
|
||||
DDS_Security_PropertySeq_deinit(&datareader_properties);
|
||||
DDS_Security_PropertySeq_deinit(&datawriter_properties);
|
||||
}
|
|
@ -11,9 +11,9 @@
|
|||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/endian.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "dds/ddsrt/environ.h"
|
||||
|
@ -34,19 +34,6 @@
|
|||
|
||||
#define HANDSHAKE_SIGNATURE_SIZE 6
|
||||
|
||||
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
|
||||
static unsigned bswap4u (unsigned x)
|
||||
{
|
||||
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
|
||||
}
|
||||
#define toBE4u(x) bswap4u (x)
|
||||
#define fromBE4u(x) bswap4u (x)
|
||||
#else
|
||||
#define toBE4u(x) (x)
|
||||
#define fromBE4u(x) (x)
|
||||
#endif
|
||||
|
||||
|
||||
static const char * AUTH_PROTOCOL_CLASS_ID = "DDS:Auth:PKI-DH:1.0";
|
||||
static const char * PERM_ACCESS_CLASS_ID = "DDS:Access:Permissions:1.0";
|
||||
|
||||
|
@ -574,9 +561,9 @@ validate_local_identity(const char* trusted_ca_dir)
|
|||
local_participant_data = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&local_participant_data->key[0], &local_participant_guid, 12);
|
||||
/* convert from big-endian format to native format */
|
||||
local_participant_data->key[0] = fromBE4u(local_participant_data->key[0]);
|
||||
local_participant_data->key[1] = fromBE4u(local_participant_data->key[1]);
|
||||
local_participant_data->key[2] = fromBE4u(local_participant_data->key[2]);
|
||||
local_participant_data->key[0] = ddsrt_fromBE4u(local_participant_data->key[0]);
|
||||
local_participant_data->key[1] = ddsrt_fromBE4u(local_participant_data->key[1]);
|
||||
local_participant_data->key[2] = ddsrt_fromBE4u(local_participant_data->key[2]);
|
||||
|
||||
initialize_identity_token(&local_participant_data->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&local_participant_data->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -947,9 +934,9 @@ validate_remote_identities (const char *remote_id_certificate)
|
|||
|
||||
remote_participant_data1 = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&remote_participant_data1->key[0], &remote_participant_guid1, 12);
|
||||
remote_participant_data1->key[0] = fromBE4u(remote_participant_data1->key[0]);
|
||||
remote_participant_data1->key[1] = fromBE4u(remote_participant_data1->key[1]);
|
||||
remote_participant_data1->key[2] = fromBE4u(remote_participant_data1->key[2]);
|
||||
remote_participant_data1->key[0] = ddsrt_fromBE4u(remote_participant_data1->key[0]);
|
||||
remote_participant_data1->key[1] = ddsrt_fromBE4u(remote_participant_data1->key[1]);
|
||||
remote_participant_data1->key[2] = ddsrt_fromBE4u(remote_participant_data1->key[2]);
|
||||
|
||||
initialize_identity_token(&remote_participant_data1->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&remote_participant_data1->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -959,9 +946,9 @@ validate_remote_identities (const char *remote_id_certificate)
|
|||
|
||||
remote_participant_data2 = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&remote_participant_data2->key[0], &remote_participant_guid2, 12);
|
||||
remote_participant_data2->key[0] = fromBE4u(remote_participant_data2->key[0]);
|
||||
remote_participant_data2->key[1] = fromBE4u(remote_participant_data2->key[1]);
|
||||
remote_participant_data2->key[2] = fromBE4u(remote_participant_data2->key[2]);
|
||||
remote_participant_data2->key[0] = ddsrt_fromBE4u(remote_participant_data2->key[0]);
|
||||
remote_participant_data2->key[1] = ddsrt_fromBE4u(remote_participant_data2->key[1]);
|
||||
remote_participant_data2->key[2] = ddsrt_fromBE4u(remote_participant_data2->key[2]);
|
||||
|
||||
initialize_identity_token(&remote_participant_data2->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&remote_participant_data2->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -1095,7 +1082,7 @@ serializer_participant_data(
|
|||
DDS_Security_Serializer serializer;
|
||||
serializer = DDS_Security_Serializer_new(1024, 1024);
|
||||
|
||||
DDD_Security_Serialize_ParticipantBuiltinTopicData(serializer, pdata);
|
||||
DDS_Security_Serialize_ParticipantBuiltinTopicData(serializer, pdata);
|
||||
DDS_Security_Serializer_buffer(serializer, buffer, size);
|
||||
DDS_Security_Serializer_free(serializer);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "common/src/crypto_helper.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#if OPENSLL_VERSION_NUMBER >= 0x10002000L
|
||||
#define AUTH_INCLUDE_EC
|
||||
#endif
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
static DDS_Security_ParticipantCryptoHandle local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static void suite_register_local_datareader_init(void)
|
||||
{
|
||||
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5; //valid dummy value
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl;
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
/* Only need the crypto plugin. */
|
||||
CU_ASSERT_FATAL((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
|
||||
/* prepare test shared secret handle */
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(DDS_Security_octet));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL && crypto->crypto_key_factory != NULL && crypto->crypto_key_factory->register_local_participant != NULL);
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
CU_ASSERT_FATAL((local_participant_crypto_handle = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception)) != DDS_SECURITY_HANDLE_NIL)
|
||||
|
||||
/* Now call the function. */
|
||||
remote_participant_crypto_handle = crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
}
|
||||
|
||||
static void suite_register_local_datareader_fini(void)
|
||||
{
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = (DDS_Security_SharedSecretHandleImpl *)shared_secret_handle;
|
||||
unload_plugins(plugins);
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
crypto = NULL;
|
||||
local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
attributes->is_discovery_protected = true;
|
||||
attributes->is_submessage_protected = true;
|
||||
|
||||
attributes->plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datareader, happy_day, .init = suite_register_local_datareader_init, .fini = suite_register_local_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
local_datareader_crypto *reader_crypto;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datareader != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datareader_properties, 0, sizeof(datareader_properties));
|
||||
|
||||
prepare_endpoint_security_attributes(&datareader_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
|
||||
result = crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
reader_crypto = (local_datareader_crypto *)result;
|
||||
|
||||
CU_ASSERT_FATAL(reader_crypto->reader_key_material != NULL);
|
||||
CU_ASSERT(master_salt_not_empty(reader_crypto->reader_key_material));
|
||||
CU_ASSERT(master_key_not_empty(reader_crypto->reader_key_material));
|
||||
CU_ASSERT(reader_crypto->metadata_protectionKind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datareader, builtin_endpoint, .init = suite_register_local_datareader_init, .fini = suite_register_local_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
local_datareader_crypto *reader_crypto;
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datareader_properties, 0, sizeof(datareader_properties));
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datareader != NULL);
|
||||
|
||||
datareader_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datareader_properties._length = datareader_properties._maximum = 1;
|
||||
|
||||
datareader_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datareader_properties._buffer[0].value = ddsrt_strdup("BuiltinSecureEndpointName");
|
||||
|
||||
prepare_endpoint_security_attributes(&datareader_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_local_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
reader_crypto = (local_datareader_crypto *)result;
|
||||
CU_ASSERT_FATAL(reader_crypto->reader_key_material != NULL);
|
||||
CU_ASSERT(master_salt_not_empty(reader_crypto->reader_key_material));
|
||||
CU_ASSERT(master_key_not_empty(reader_crypto->reader_key_material));
|
||||
CU_ASSERT(reader_crypto->metadata_protectionKind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT);
|
||||
CU_ASSERT(reader_crypto->is_builtin_participant_volatile_message_secure_reader == false);
|
||||
|
||||
DDS_Security_PropertySeq_deinit(&datareader_properties);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datareader, special_endpoint_name, .init = suite_register_local_datareader_init, .fini = suite_register_local_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datareader_properties, 0, sizeof(datareader_properties));
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datareader != NULL);
|
||||
|
||||
/*set special endpoint name*/
|
||||
datareader_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datareader_properties._length = datareader_properties._maximum = 1;
|
||||
datareader_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datareader_properties._buffer[0].value = ddsrt_strdup("BuiltinParticipantVolatileMessageSecureReader");
|
||||
|
||||
prepare_endpoint_security_attributes(&datareader_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_local_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
CU_ASSERT_FATAL(((local_datareader_crypto *)result)->is_builtin_participant_volatile_message_secure_reader);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_PropertySeq_deinit(&datareader_properties);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datareader, invalid_participant, .init = suite_register_local_datareader_init, .fini = suite_register_local_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datareader != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datareader_properties, 0, sizeof(datareader_properties));
|
||||
|
||||
prepare_endpoint_security_attributes(&datareader_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
8, /*non existing handle*/
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
|
||||
/* Invalid handle should be returned */
|
||||
CU_ASSERT(result == 0);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE);
|
||||
CU_ASSERT_NSTRING_EQUAL_FATAL(exception.message, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE, sizeof(DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE));
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "common/src/crypto_helper.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#if OPENSLL_VERSION_NUMBER >= 0x10002000L
|
||||
#define AUTH_INCLUDE_EC
|
||||
#endif
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
static DDS_Security_ParticipantCryptoHandle local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static void suite_register_local_datawriter_init(void)
|
||||
{
|
||||
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5; //valid dummy value
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl;
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
|
||||
/* prepare test shared secret handle */
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(DDS_Security_octet));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL (crypto != NULL && crypto->crypto_key_factory != NULL && crypto->crypto_key_factory->register_local_participant != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
local_participant_crypto_handle = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
CU_ASSERT_FATAL (local_participant_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
|
||||
/* Now call the function. */
|
||||
remote_participant_crypto_handle = crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
CU_ASSERT_FATAL (remote_participant_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void suite_register_local_datawriter_fini(void)
|
||||
{
|
||||
unload_plugins(plugins);
|
||||
shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
crypto = NULL;
|
||||
local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
attributes->is_discovery_protected = true;
|
||||
attributes->is_submessage_protected = true;
|
||||
|
||||
attributes->plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datawriter, happy_day, .init = suite_register_local_datawriter_init, .fini = suite_register_local_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
local_datawriter_crypto *writer_crypto;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datawriter != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
prepare_endpoint_security_attributes(&datawriter_security_attributes);
|
||||
|
||||
datawriter_security_attributes.is_payload_protected = true;
|
||||
datawriter_security_attributes.plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED;
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
writer_crypto = (local_datawriter_crypto *)result;
|
||||
|
||||
CU_ASSERT_FATAL(writer_crypto->writer_key_material_message != NULL);
|
||||
CU_ASSERT_FATAL(writer_crypto->writer_key_material_payload != NULL);
|
||||
|
||||
CU_ASSERT(master_salt_not_empty(writer_crypto->writer_key_material_message));
|
||||
CU_ASSERT(master_key_not_empty(writer_crypto->writer_key_material_message));
|
||||
|
||||
CU_ASSERT(master_salt_not_empty(writer_crypto->writer_key_material_payload));
|
||||
CU_ASSERT(master_key_not_empty(writer_crypto->writer_key_material_payload));
|
||||
|
||||
CU_ASSERT(writer_crypto->metadata_protectionKind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT);
|
||||
CU_ASSERT(writer_crypto->data_protectionKind == DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datawriter, builtin_endpoint, .init = suite_register_local_datawriter_init, .fini = suite_register_local_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
local_datawriter_crypto *writer_crypto;
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
|
||||
prepare_endpoint_security_attributes(&datawriter_security_attributes);
|
||||
datawriter_security_attributes.is_payload_protected = true;
|
||||
datawriter_security_attributes.plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datawriter != NULL);
|
||||
|
||||
datawriter_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datawriter_properties._length = datawriter_properties._maximum = 1;
|
||||
datawriter_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datawriter_properties._buffer[0].value = ddsrt_strdup("BuiltinSecureEndpointName");
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
writer_crypto = (local_datawriter_crypto *)result;
|
||||
|
||||
CU_ASSERT_FATAL(writer_crypto->writer_key_material_message != NULL);
|
||||
CU_ASSERT_FATAL(writer_crypto->writer_key_material_payload != NULL);
|
||||
|
||||
CU_ASSERT(master_salt_not_empty(writer_crypto->writer_key_material_message));
|
||||
CU_ASSERT(master_key_not_empty(writer_crypto->writer_key_material_message));
|
||||
|
||||
CU_ASSERT(master_salt_not_empty(writer_crypto->writer_key_material_payload));
|
||||
CU_ASSERT(master_key_not_empty(writer_crypto->writer_key_material_payload));
|
||||
|
||||
CU_ASSERT_FATAL(writer_crypto->metadata_protectionKind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT);
|
||||
CU_ASSERT_FATAL(writer_crypto->data_protectionKind == DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT);
|
||||
CU_ASSERT_FATAL(writer_crypto->is_builtin_participant_volatile_message_secure_writer == false);
|
||||
|
||||
reset_exception(&exception);
|
||||
DDS_Security_PropertySeq_deinit(&datawriter_properties);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datawriter, special_endpoint_name, .init = suite_register_local_datawriter_init, .fini = suite_register_local_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
memset(&datawriter_security_attributes, 0, sizeof(datawriter_security_attributes));
|
||||
prepare_endpoint_security_attributes(&datawriter_security_attributes);
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datawriter != NULL);
|
||||
|
||||
/*set special endpoint name*/
|
||||
datawriter_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datawriter_properties._length = datawriter_properties._maximum = 1;
|
||||
datawriter_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datawriter_properties._buffer[0].value = ddsrt_strdup("BuiltinParticipantVolatileMessageSecureWriter");
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
CU_ASSERT_FATAL(((local_datawriter_crypto *)result)->is_builtin_participant_volatile_message_secure_writer);
|
||||
|
||||
reset_exception(&exception);
|
||||
DDS_Security_PropertySeq_deinit(&datawriter_properties);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_datawriter, invalid_participant, .init = suite_register_local_datawriter_init, .fini = suite_register_local_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datawriter != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
prepare_endpoint_security_attributes(&datawriter_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
8, /*non existing handle*/
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
/* Invalid handle should be returned */
|
||||
CU_ASSERT(result == 0);
|
||||
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE);
|
||||
CU_ASSERT_NSTRING_EQUAL_FATAL(exception.message, DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE, sizeof(DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_MESSAGE));
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#if OPENSLL_VERSION_NUMBER >= 0x10002000L
|
||||
#define AUTH_INCLUDE_EC
|
||||
#endif
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static void suite_register_local_participant_init(void)
|
||||
{
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
}
|
||||
|
||||
static void suite_register_local_participant_fini(void)
|
||||
{
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_participant, happy_day, .init = suite_register_local_participant_init, .fini = suite_register_local_participant_fini)
|
||||
{
|
||||
DDS_Security_ParticipantCryptoHandle hdl;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 2; /*dummy but valid */
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_participant != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
hdl = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(hdl != DDS_SECURITY_HANDLE_NIL);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
(void)crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
hdl,
|
||||
&exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_local_participant, empty_identity, .init = suite_register_local_participant_init, .fini = suite_register_local_participant_fini)
|
||||
{
|
||||
DDS_Security_ParticipantCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_IdentityHandle participant_identity = 0; //empty identity
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
DDS_Security_PermissionsHandle participant_permissions = 2; /*dummy but valid */
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_participant != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
if (exception.code != 0)
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_IDENTITY_EMPTY_CODE);
|
||||
CU_ASSERT(!strcmp(exception.message, DDS_SECURITY_ERR_IDENTITY_EMPTY_MESSAGE));
|
||||
CU_ASSERT(result == 0);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "common/src/crypto_helper.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#if OPENSLL_VERSION_NUMBER >= 0x10002000L
|
||||
#define AUTH_INCLUDE_EC
|
||||
#endif
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
static DDS_Security_ParticipantCryptoHandle local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_DatawriterCryptoHandle local_writer_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
attributes->is_discovery_protected = true;
|
||||
attributes->is_submessage_protected = true;
|
||||
|
||||
attributes->plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
|
||||
}
|
||||
|
||||
static void register_local_regular()
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
|
||||
prepare_endpoint_security_attributes(&datawriter_security_attributes);
|
||||
datawriter_security_attributes.is_payload_protected = true;
|
||||
datawriter_security_attributes.plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_PAYLOAD_ENCRYPTED;
|
||||
|
||||
/* Now call the function. */
|
||||
|
||||
local_writer_handle = crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
}
|
||||
|
||||
static void suite_register_matched_remote_datareader_init(void)
|
||||
{
|
||||
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5; //valid dummy value
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl;
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
/* prepare test shared secret handle */
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(DDS_Security_octet));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL (crypto != NULL && crypto->crypto_key_factory != NULL && crypto->crypto_key_factory->register_local_participant != NULL);
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
local_participant_crypto_handle = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
CU_ASSERT_FATAL (local_participant_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
|
||||
/* Now call the function. */
|
||||
remote_participant_crypto_handle = crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
CU_ASSERT_FATAL (remote_participant_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void suite_register_matched_remote_datareader_fini(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
(void)crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
remote_participant_crypto_handle,
|
||||
&exception);
|
||||
(void)crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&exception);
|
||||
unload_plugins(plugins);
|
||||
shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
crypto = NULL;
|
||||
local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_remote_datareader, happy_day, .init = suite_register_matched_remote_datareader_init, .fini = suite_register_matched_remote_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
bool unregister_result = false;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
remote_datareader_crypto *reader_crypto;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datareader != NULL);
|
||||
|
||||
register_local_regular();
|
||||
|
||||
/* Now call the function. */
|
||||
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_writer_handle,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
reader_crypto = (remote_datareader_crypto *)result;
|
||||
CU_ASSERT_FATAL(reader_crypto->writer2reader_key_material_message != NULL);
|
||||
CU_ASSERT_FATAL(reader_crypto->writer2reader_key_material_payload != NULL);
|
||||
CU_ASSERT(master_salt_not_empty(reader_crypto->writer2reader_key_material_message));
|
||||
CU_ASSERT(master_key_not_empty(reader_crypto->writer2reader_key_material_message));
|
||||
CU_ASSERT(master_salt_not_empty(reader_crypto->writer2reader_key_material_payload));
|
||||
CU_ASSERT(master_key_not_empty(reader_crypto->writer2reader_key_material_payload));
|
||||
CU_ASSERT_FATAL(reader_crypto->metadata_protectionKind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT);
|
||||
reset_exception(&exception);
|
||||
|
||||
unregister_result = crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, result, &exception);
|
||||
CU_ASSERT_FATAL(unregister_result);
|
||||
}
|
||||
|
||||
/* test if function returns volatile secure reader crypto if the writer is volatile secure*/
|
||||
CU_Test(ddssec_builtin_register_remote_datareader, volatile_secure, .init = suite_register_matched_remote_datareader_init, .fini = suite_register_matched_remote_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
DDS_Security_DatawriterCryptoHandle local_volatile_secure_writer;
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
|
||||
prepare_endpoint_security_attributes(&datawriter_security_attributes);
|
||||
|
||||
datawriter_security_attributes.is_discovery_protected = true;
|
||||
datawriter_security_attributes.is_submessage_protected = true;
|
||||
|
||||
datawriter_properties._length = datawriter_properties._maximum = 1;
|
||||
datawriter_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datawriter_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datawriter_properties._buffer[0].value = ddsrt_strdup("BuiltinParticipantVolatileMessageSecureWriter");
|
||||
datawriter_properties._buffer[0].propagate = false;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_datawriter != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datareader != NULL);
|
||||
|
||||
local_volatile_secure_writer =
|
||||
crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_volatile_secure_writer,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT_FATAL(result != 0);
|
||||
CU_ASSERT_FATAL(((remote_datareader_crypto *)result)->is_builtin_participant_volatile_message_secure_reader);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
reset_exception(&exception);
|
||||
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, result, &exception);
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, local_volatile_secure_writer, &exception);
|
||||
DDS_Security_PropertySeq_deinit(&datawriter_properties);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_remote_datareader, with_origin_authentication, .init = suite_register_matched_remote_datareader_init, .fini = suite_register_matched_remote_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
bool unregister_result = false;
|
||||
local_datawriter_crypto *writer_crypto;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
remote_datareader_crypto *reader_crypto;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datareader != NULL);
|
||||
register_local_regular();
|
||||
|
||||
/*set writer protection kind */
|
||||
writer_crypto = (local_datawriter_crypto *)local_writer_handle;
|
||||
writer_crypto->metadata_protectionKind = DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION;
|
||||
writer_crypto = (local_datawriter_crypto *)local_writer_handle;
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_writer_handle,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
reader_crypto = (remote_datareader_crypto *)result;
|
||||
CU_ASSERT_FATAL(reader_crypto->writer2reader_key_material_message != NULL);
|
||||
CU_ASSERT_FATAL(reader_crypto->writer2reader_key_material_payload != NULL);
|
||||
CU_ASSERT(master_salt_not_empty(reader_crypto->writer2reader_key_material_message));
|
||||
CU_ASSERT(master_key_not_empty(reader_crypto->writer2reader_key_material_message));
|
||||
CU_ASSERT(master_salt_not_empty(reader_crypto->writer2reader_key_material_payload));
|
||||
CU_ASSERT(master_key_not_empty(reader_crypto->writer2reader_key_material_payload));
|
||||
CU_ASSERT_FATAL(reader_crypto->metadata_protectionKind == DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* test to unregister with local writer*/
|
||||
unregister_result = crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, local_writer_handle, &exception);
|
||||
CU_ASSERT_FATAL(unregister_result);
|
||||
|
||||
unregister_result = crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, result, &exception);
|
||||
CU_ASSERT_FATAL(!unregister_result);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
/* test invalid parameter*/
|
||||
CU_Test(ddssec_builtin_register_remote_datareader, invalid_participant, .init = suite_register_matched_remote_datareader_init, .fini = suite_register_matched_remote_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datareader != NULL);
|
||||
|
||||
register_local_regular();
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_writer_handle,
|
||||
0,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT_FATAL(result == 0);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
/* test invalid parameter*/
|
||||
CU_Test(ddssec_builtin_register_remote_datareader, invalid_writer_properties, .init = suite_register_matched_remote_datareader_init, .fini = suite_register_matched_remote_datareader_fini)
|
||||
{
|
||||
DDS_Security_DatawriterCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datareader != NULL);
|
||||
register_local_regular();
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
0,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT_FATAL(result == 0);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE);
|
||||
reset_exception(&exception);
|
||||
}
|
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "common/src/crypto_helper.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#if OPENSLL_VERSION_NUMBER >= 0x10002000L
|
||||
#define AUTH_INCLUDE_EC
|
||||
#endif
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
static DDS_Security_ParticipantCryptoHandle local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_DatareaderCryptoHandle local_reader_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static void prepare_endpoint_security_attributes(DDS_Security_EndpointSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
attributes->is_discovery_protected = true;
|
||||
attributes->is_submessage_protected = true;
|
||||
|
||||
attributes->plugin_endpoint_attributes |= DDS_SECURITY_PLUGIN_ENDPOINT_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ENCRYPTED;
|
||||
}
|
||||
|
||||
static void register_local_regular()
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
|
||||
memset(&datareader_properties, 0, sizeof(datareader_properties));
|
||||
|
||||
prepare_endpoint_security_attributes(&datareader_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
|
||||
local_reader_handle = crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
}
|
||||
|
||||
static void suite_register_matched_remote_datawriter_init(void)
|
||||
{
|
||||
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5; //valid dummy value
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl;
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
|
||||
/* prepare test shared secret handle */
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(DDS_Security_octet));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL (crypto != NULL && crypto->crypto_key_factory != NULL && crypto->crypto_key_factory->register_local_participant != NULL)
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
local_participant_crypto_handle = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
CU_ASSERT_FATAL (local_participant_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
|
||||
/* Now call the function. */
|
||||
remote_participant_crypto_handle = crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
CU_ASSERT_FATAL (remote_participant_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
}
|
||||
|
||||
static void suite_register_matched_remote_datawriter_fini(void)
|
||||
{
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = (DDS_Security_SharedSecretHandleImpl *)shared_secret_handle;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
CU_ASSERT_EQUAL_FATAL (crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
remote_participant_crypto_handle,
|
||||
&exception), true);
|
||||
|
||||
CU_ASSERT_EQUAL_FATAL (crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&exception), true);
|
||||
|
||||
unload_plugins(plugins);
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
crypto = NULL;
|
||||
local_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
remote_participant_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
|
||||
CU_Test(ddssec_builtin_register_remote_datawriter, happy_day, .init = suite_register_matched_remote_datawriter_init, .fini = suite_register_matched_remote_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
bool unregister_result = false;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
remote_datawriter_crypto *writer_crypto;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datawriter != NULL);
|
||||
register_local_regular();
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_reader_handle,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT_FATAL(result != 0);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
writer_crypto = (remote_datawriter_crypto *)result;
|
||||
CU_ASSERT_FATAL(writer_crypto->reader2writer_key_material != NULL);
|
||||
CU_ASSERT(master_salt_not_empty(writer_crypto->reader2writer_key_material));
|
||||
CU_ASSERT(master_key_not_empty(writer_crypto->reader2writer_key_material));
|
||||
CU_ASSERT_FATAL(writer_crypto->reader2writer_key_material->receiver_specific_key_id == 0);
|
||||
reset_exception(&exception);
|
||||
|
||||
unregister_result = crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, result, &exception);
|
||||
CU_ASSERT_FATAL(unregister_result);
|
||||
}
|
||||
|
||||
/* test if function returns volatile secure writer crypto if the reader is volatile secure*/
|
||||
CU_Test(ddssec_builtin_register_remote_datawriter, volatile_secure, .init = suite_register_matched_remote_datawriter_init, .fini = suite_register_matched_remote_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
DDS_Security_DatareaderCryptoHandle local_volatile_secure_reader;
|
||||
DDS_Security_PropertySeq datareader_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datareader_security_attributes;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datawriter != NULL);
|
||||
|
||||
datareader_properties._length = datareader_properties._maximum = 1;
|
||||
datareader_properties._buffer = DDS_Security_PropertySeq_allocbuf(1);
|
||||
datareader_properties._buffer[0].name = ddsrt_strdup("dds.sec.builtin_endpoint_name");
|
||||
datareader_properties._buffer[0].value = ddsrt_strdup("BuiltinParticipantVolatileMessageSecureReader");
|
||||
datareader_properties._buffer[0].propagate = false;
|
||||
memset(&datareader_security_attributes, 0, sizeof(datareader_security_attributes));
|
||||
|
||||
datareader_security_attributes.is_discovery_protected = true;
|
||||
datareader_security_attributes.is_submessage_protected = true;
|
||||
|
||||
local_volatile_secure_reader =
|
||||
crypto->crypto_key_factory->register_local_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_crypto_handle,
|
||||
&datareader_properties,
|
||||
&datareader_security_attributes,
|
||||
&exception);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_volatile_secure_reader,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT_FATAL(result != 0);
|
||||
CU_ASSERT_FATAL(((remote_datawriter_crypto *)result)->is_builtin_participant_volatile_message_secure_writer);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
reset_exception(&exception);
|
||||
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, result, &exception);
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_volatile_secure_reader, &exception);
|
||||
DDS_Security_PropertySeq_deinit(&datareader_properties);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_remote_datawriter, with_origin_authentication, .init = suite_register_matched_remote_datawriter_init, .fini = suite_register_matched_remote_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
bool unregister_result = false;
|
||||
local_datareader_crypto *reader_crypto;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
remote_datawriter_crypto *writer_crypto;
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datawriter != NULL);
|
||||
register_local_regular();
|
||||
|
||||
/*set reader protection kind */
|
||||
reader_crypto = (local_datareader_crypto *)local_reader_handle;
|
||||
reader_crypto->metadata_protectionKind = DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION;
|
||||
reader_crypto = (local_datareader_crypto *)local_reader_handle;
|
||||
/* Now call the function. */
|
||||
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_reader_handle,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_remote_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(result != 0);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
|
||||
/* NOTE: It would be better to check if the keys have been generated but there is no interface to get them from handle */
|
||||
writer_crypto = (remote_datawriter_crypto *)result;
|
||||
CU_ASSERT_FATAL(writer_crypto->reader2writer_key_material != NULL);
|
||||
CU_ASSERT(master_salt_not_empty(writer_crypto->reader2writer_key_material));
|
||||
CU_ASSERT(master_key_not_empty(writer_crypto->reader2writer_key_material));
|
||||
CU_ASSERT_FATAL(writer_crypto->reader2writer_key_material->receiver_specific_key_id != 0);
|
||||
CU_ASSERT(master_receiver_specific_key_not_empty(writer_crypto->reader2writer_key_material));
|
||||
reset_exception(&exception);
|
||||
|
||||
/*test unregister the local pair*/
|
||||
unregister_result = crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_reader_handle, &exception);
|
||||
CU_ASSERT_FATAL(unregister_result);
|
||||
|
||||
/* unregister remote should give error*/
|
||||
unregister_result = crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, result, &exception);
|
||||
CU_ASSERT_FATAL(!unregister_result);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
/* test invalid parameter*/
|
||||
CU_Test(ddssec_builtin_register_remote_datawriter, invalid_participant, .init = suite_register_matched_remote_datawriter_init, .fini = suite_register_matched_remote_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datawriter != NULL);
|
||||
register_local_regular();
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_reader_handle,
|
||||
0,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT_FATAL(result == 0);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
/* test invalid parameter */
|
||||
CU_Test(ddssec_builtin_register_remote_datawriter, invalid_writer_properties, .init = suite_register_matched_remote_datawriter_init, .fini = suite_register_matched_remote_datawriter_fini)
|
||||
{
|
||||
DDS_Security_DatareaderCryptoHandle result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
/* Check if we actually have the function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_matched_remote_datawriter != NULL);
|
||||
register_local_regular();
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_factory->register_matched_remote_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
0,
|
||||
remote_participant_crypto_handle,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT_FATAL(result == 0);
|
||||
CU_ASSERT_FATAL(exception.code == DDS_SECURITY_ERR_INVALID_CRYPTO_HANDLE_CODE);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#if OPENSLL_VERSION_NUMBER >= 0x10002000L
|
||||
#define AUTH_INCLUDE_EC
|
||||
#endif
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static void suite_register_matched_remote_participant_init(void)
|
||||
{
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
}
|
||||
|
||||
static void suite_register_matched_remote_participant_fini(void)
|
||||
{
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_remote_participant, happy_day, .init = suite_register_matched_remote_participant_init, .fini = suite_register_matched_remote_participant_fini)
|
||||
{
|
||||
DDS_Security_ParticipantCryptoHandle local_crypto_handle;
|
||||
DDS_Security_ParticipantCryptoHandle remote_crypto_handle;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_IdentityHandle participant_identity = 5; //valid dummy value
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5; /*valid dummy value */
|
||||
DDS_Security_SharedSecretHandle shared_secret_handle;
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl;
|
||||
DDS_Security_PermissionsHandle participant_permissions = 2; /*valid but dummy value */
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
/* prepare test shared secret handle */
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(DDS_Security_octet));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_participant != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
local_crypto_handle = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
CU_ASSERT_FATAL(local_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
|
||||
/* Now call the function. */
|
||||
remote_crypto_handle = crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_crypto_handle,
|
||||
participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
/* A valid handle to be returned */
|
||||
CU_ASSERT(remote_crypto_handle != DDS_SECURITY_HANDLE_NIL);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_OK_CODE);
|
||||
reset_exception(&exception);
|
||||
|
||||
(void)crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
remote_crypto_handle,
|
||||
&exception);
|
||||
reset_exception(&exception);
|
||||
|
||||
(void)crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_crypto_handle,
|
||||
&exception);
|
||||
reset_exception(&exception);
|
||||
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_register_remote_participant, empty_identity, .init = suite_register_matched_remote_participant_init, .fini = suite_register_matched_remote_participant_fini)
|
||||
{
|
||||
DDS_Security_ParticipantCryptoHandle local_crypto_handle;
|
||||
DDS_Security_ParticipantCryptoHandle remote_crypto_handle;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_IdentityHandle participant_identity = 5; //empty identity
|
||||
DDS_Security_IdentityHandle remote_participant_identity_empty = 0; //empty identity
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
DDS_Security_PermissionsHandle participant_permissions = 2; /*valid but dummy value */
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
DDS_Security_SharedSecretHandle shared_secret_handle;
|
||||
DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl;
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5; //valid dummy value
|
||||
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(DDS_Security_octet));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_factory->register_local_participant != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
/* Now call the function. */
|
||||
local_crypto_handle = crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
remote_crypto_handle = crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_crypto_handle,
|
||||
remote_participant_identity_empty,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (exception.code != 0)
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(remote_crypto_handle == DDS_SECURITY_HANDLE_NIL);
|
||||
CU_ASSERT(exception.code == DDS_SECURITY_ERR_IDENTITY_EMPTY_CODE);
|
||||
CU_ASSERT(!strcmp(exception.message, DDS_SECURITY_ERR_IDENTITY_EMPTY_MESSAGE));
|
||||
reset_exception(&exception);
|
||||
|
||||
(void)crypto->crypto_key_factory->unregister_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_crypto_handle,
|
||||
&exception);
|
||||
reset_exception(&exception);
|
||||
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
|
@ -0,0 +1,980 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
#define CRYPTO_TRANSFORM_KIND(k) (*(uint32_t *)&((k)[0]))
|
||||
#define CRYPTO_TRANSFORM_ID(k) (*(uint32_t *)&((k)[0]))
|
||||
|
||||
static const char *CRYPTO_TOKEN_CLASS_ID = "DDS:Crypto:AES_GCM_GMAC";
|
||||
static const char *CRYPTO_TOKEN_PROPERTY_NAME = "dds.cryp.keymat";
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static DDS_Security_IdentityHandle local_participant_identity = 1;
|
||||
static DDS_Security_IdentityHandle remote_participant_identity = 2;
|
||||
|
||||
static DDS_Security_ParticipantCryptoHandle local_particpant_crypto = 0;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_particpant_crypto = 0;
|
||||
static DDS_Security_DatawriterCryptoHandle remote_reader_crypto = 0;
|
||||
static DDS_Security_DatareaderCryptoHandle local_writer_crypto = 0;
|
||||
|
||||
static DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle;
|
||||
|
||||
static void allocate_shared_secret(void)
|
||||
{
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(unsigned char));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
}
|
||||
|
||||
static void
|
||||
deallocate_shared_secret(void)
|
||||
{
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int
|
||||
register_local_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
local_particpant_crypto =
|
||||
crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_particpant_crypto == 0)
|
||||
{
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return local_particpant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
register_remote_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5;
|
||||
|
||||
remote_particpant_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_particpant_crypto,
|
||||
remote_participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (remote_particpant_crypto == 0)
|
||||
{
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return remote_particpant_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
register_local_datawriter(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq datawriter_properties;
|
||||
DDS_Security_EndpointSecurityAttributes datawriter_security_attributes;
|
||||
|
||||
memset(&datawriter_properties, 0, sizeof(datawriter_properties));
|
||||
memset(&datawriter_security_attributes, 0, sizeof(DDS_Security_EndpointSecurityAttributes));
|
||||
|
||||
datawriter_security_attributes.is_discovery_protected = true;
|
||||
|
||||
local_writer_crypto =
|
||||
crypto->crypto_key_factory->register_local_datawriter(
|
||||
crypto->crypto_key_factory,
|
||||
local_particpant_crypto,
|
||||
&datawriter_properties,
|
||||
&datawriter_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_writer_crypto == 0)
|
||||
{
|
||||
printf("register_local_datawriter: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return local_writer_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
register_remote_datareader(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
remote_reader_crypto =
|
||||
crypto->crypto_key_factory->register_matched_remote_datareader(
|
||||
crypto->crypto_key_factory,
|
||||
local_writer_crypto,
|
||||
remote_particpant_crypto,
|
||||
shared_secret_handle,
|
||||
true,
|
||||
&exception);
|
||||
|
||||
if (remote_reader_crypto == 0)
|
||||
{
|
||||
printf("register_matched_remote_datareader: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
return remote_reader_crypto ? 0 : -1;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_exception(
|
||||
DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
static void suite_set_remote_datareader_crypto_tokens_init(void)
|
||||
{
|
||||
allocate_shared_secret();
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_datawriter(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_datareader(), 0);
|
||||
}
|
||||
|
||||
static void suite_set_remote_datareader_crypto_tokens_fini(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
if (remote_reader_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, remote_reader_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_writer_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datawriter(crypto->crypto_key_factory, local_writer_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (remote_particpant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_particpant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
if (local_particpant_crypto)
|
||||
{
|
||||
crypto->crypto_key_factory->unregister_datareader(crypto->crypto_key_factory, local_particpant_crypto, &exception);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
deallocate_shared_secret();
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static void create_key_material(DDS_Security_OctetSeq *seq, bool include_specific_key)
|
||||
{
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC keymat;
|
||||
DDS_Security_Serializer serializer;
|
||||
unsigned char *buffer;
|
||||
size_t length;
|
||||
|
||||
memset(&keymat, 0, sizeof(keymat));
|
||||
|
||||
keymat.transformation_kind[3] = CRYPTO_TRANSFORMATION_KIND_AES256_GCM;
|
||||
RAND_bytes(keymat.sender_key_id, 4);
|
||||
|
||||
keymat.master_salt._length = keymat.master_salt._maximum = DDS_SECURITY_MASTER_SALT_SIZE_256;
|
||||
keymat.master_salt._buffer = DDS_Security_OctetSeq_allocbuf(DDS_SECURITY_MASTER_SALT_SIZE_256);
|
||||
RAND_bytes(keymat.master_salt._buffer, DDS_SECURITY_MASTER_SALT_SIZE_256);
|
||||
|
||||
keymat.master_sender_key._length = keymat.master_sender_key._maximum = DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256;
|
||||
keymat.master_sender_key._buffer = DDS_Security_OctetSeq_allocbuf(DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256);
|
||||
RAND_bytes(keymat.master_sender_key._buffer, DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256);
|
||||
|
||||
if (include_specific_key)
|
||||
{
|
||||
RAND_bytes(keymat.receiver_specific_key_id, 4);
|
||||
keymat.master_receiver_specific_key._length = keymat.master_receiver_specific_key._maximum = DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_256;
|
||||
keymat.master_receiver_specific_key._buffer = DDS_Security_OctetSeq_allocbuf(DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_256);
|
||||
RAND_bytes(keymat.master_receiver_specific_key._buffer, DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_256);
|
||||
}
|
||||
|
||||
serializer = DDS_Security_Serializer_new(256, 256);
|
||||
DDS_Security_Serialize_KeyMaterial_AES_GCM_GMAC(serializer, &keymat);
|
||||
DDS_Security_Serializer_buffer(serializer, &buffer, &length);
|
||||
DDS_Security_Serializer_free(serializer);
|
||||
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(&keymat);
|
||||
|
||||
seq->_length = seq->_maximum = (uint32_t)length;
|
||||
seq->_buffer = buffer;
|
||||
}
|
||||
|
||||
static void init_key_material(DDS_Security_KeyMaterial_AES_GCM_GMAC *keymat, bool include_specific_key)
|
||||
{
|
||||
memset(keymat, 0, sizeof(*keymat));
|
||||
|
||||
keymat->transformation_kind[3] = CRYPTO_TRANSFORMATION_KIND_AES256_GCM;
|
||||
RAND_bytes(keymat->sender_key_id, 4);
|
||||
|
||||
keymat->master_salt._length = keymat->master_salt._maximum = DDS_SECURITY_MASTER_SALT_SIZE_256;
|
||||
keymat->master_salt._buffer = DDS_Security_OctetSeq_allocbuf(DDS_SECURITY_MASTER_SALT_SIZE_256);
|
||||
RAND_bytes(keymat->master_salt._buffer, DDS_SECURITY_MASTER_SALT_SIZE_256);
|
||||
|
||||
keymat->master_sender_key._length = keymat->master_sender_key._maximum = DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256;
|
||||
keymat->master_sender_key._buffer = DDS_Security_OctetSeq_allocbuf(DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256);
|
||||
RAND_bytes(keymat->master_sender_key._buffer, DDS_SECURITY_MASTER_SENDER_KEY_SIZE_256);
|
||||
|
||||
if (include_specific_key)
|
||||
{
|
||||
RAND_bytes(keymat->receiver_specific_key_id, 4);
|
||||
keymat->master_receiver_specific_key._length = keymat->master_receiver_specific_key._maximum = DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_256;
|
||||
keymat->master_receiver_specific_key._buffer = DDS_Security_OctetSeq_allocbuf(DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_256);
|
||||
RAND_bytes(keymat->master_receiver_specific_key._buffer, DDS_SECURITY_MASTER_RECEIVER_SPECIFIC_KEY_SIZE_256);
|
||||
}
|
||||
}
|
||||
|
||||
static void deinit_key_material(DDS_Security_KeyMaterial_AES_GCM_GMAC *keymat)
|
||||
{
|
||||
ddsrt_free(keymat->master_salt._buffer);
|
||||
ddsrt_free(keymat->master_sender_key._buffer);
|
||||
ddsrt_free(keymat->master_receiver_specific_key._buffer);
|
||||
}
|
||||
|
||||
static void create_reader_tokens(DDS_Security_DatawriterCryptoTokenSeq *tokens)
|
||||
{
|
||||
tokens->_length = tokens->_maximum = 1;
|
||||
tokens->_buffer = DDS_Security_DataHolderSeq_allocbuf(1);
|
||||
tokens->_buffer[0].class_id = ddsrt_strdup(CRYPTO_TOKEN_CLASS_ID);
|
||||
tokens->_buffer[0].binary_properties._length = 1;
|
||||
tokens->_buffer[0].binary_properties._maximum = 1;
|
||||
tokens->_buffer[0].binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1);
|
||||
tokens->_buffer[0].binary_properties._buffer[0].name = ddsrt_strdup(CRYPTO_TOKEN_PROPERTY_NAME);
|
||||
create_key_material(&tokens->_buffer[0].binary_properties._buffer[0].value, false);
|
||||
}
|
||||
|
||||
static void create_reader_tokens_no_key_material(DDS_Security_DatawriterCryptoTokenSeq *tokens)
|
||||
{
|
||||
tokens->_length = tokens->_maximum = 1;
|
||||
tokens->_buffer = DDS_Security_DataHolderSeq_allocbuf(1);
|
||||
tokens->_buffer[0].class_id = ddsrt_strdup(CRYPTO_TOKEN_CLASS_ID);
|
||||
tokens->_buffer[0].binary_properties._length = 1;
|
||||
tokens->_buffer[0].binary_properties._maximum = 1;
|
||||
tokens->_buffer[0].binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1);
|
||||
tokens->_buffer[0].binary_properties._buffer[0].name = ddsrt_strdup(CRYPTO_TOKEN_PROPERTY_NAME);
|
||||
}
|
||||
|
||||
static void serialize_key_material(DDS_Security_OctetSeq *seq, DDS_Security_KeyMaterial_AES_GCM_GMAC *keymat)
|
||||
{
|
||||
DDS_Security_Serializer serializer;
|
||||
unsigned char *buffer;
|
||||
size_t length;
|
||||
|
||||
serializer = DDS_Security_Serializer_new(256, 256);
|
||||
DDS_Security_Serialize_KeyMaterial_AES_GCM_GMAC(serializer, keymat);
|
||||
DDS_Security_Serializer_buffer(serializer, &buffer, &length);
|
||||
DDS_Security_Serializer_free(serializer);
|
||||
|
||||
seq->_length = seq->_maximum = (uint32_t) length;
|
||||
seq->_buffer = buffer;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_datareader_crypto_tokens, happy_day, .init = suite_set_remote_datareader_crypto_tokens_init, .fini = suite_set_remote_datareader_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
create_reader_tokens(&tokens);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
DDS_Security_DataHolderSeq_deinit(&tokens);
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_datareader_crypto_tokens, single_token, .init = suite_set_remote_datareader_crypto_tokens_init, .fini = suite_set_remote_datareader_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens != NULL);
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
create_reader_tokens(&tokens);
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
DDS_Security_DataHolderSeq_deinit(&tokens);
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_datareader_crypto_tokens, invalid_args, .init = suite_set_remote_datareader_crypto_tokens_init, .fini = suite_set_remote_datareader_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
create_reader_tokens(&tokens);
|
||||
|
||||
/* invalid token seq = NULL */
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
NULL,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
0,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
0,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
1,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datawriter_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
1,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
DDS_Security_DataHolderSeq_deinit(&tokens);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_datareader_crypto_tokens, invalid_tokens, .init = suite_set_remote_datareader_crypto_tokens_init, .fini = suite_set_remote_datareader_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
DDS_Security_DatawriterCryptoTokenSeq empty_tokens;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
memset(&empty_tokens, 0, sizeof(empty_tokens));
|
||||
create_reader_tokens(&tokens);
|
||||
|
||||
/* empty token sequence */
|
||||
{
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&empty_tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
/* DDS_Security_DatawriterCryptoTokenSeq with empty token */
|
||||
{
|
||||
empty_tokens._length = 1;
|
||||
empty_tokens._buffer = DDS_Security_DataHolderSeq_allocbuf(1);
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&empty_tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_DataHolderSeq_deinit(&empty_tokens);
|
||||
}
|
||||
|
||||
/* invalid token class id */
|
||||
{
|
||||
ddsrt_free(tokens._buffer[0].class_id);
|
||||
tokens._buffer[0].class_id = ddsrt_strdup("invalid class");
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
ddsrt_free(tokens._buffer[0].class_id);
|
||||
tokens._buffer[0].class_id = ddsrt_strdup(CRYPTO_TOKEN_CLASS_ID);
|
||||
}
|
||||
|
||||
/* no key material, binary_property missing */
|
||||
{
|
||||
tokens._buffer[0].binary_properties._length = 0;
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
tokens._buffer[0].binary_properties._length = 1;
|
||||
}
|
||||
|
||||
/* no key material, property is empty */
|
||||
{
|
||||
DDS_Security_BinaryProperty_t *saved_buffer = tokens._buffer[0].binary_properties._buffer;
|
||||
tokens._buffer[0].binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
ddsrt_free(tokens._buffer[0].binary_properties._buffer);
|
||||
tokens._buffer[0].binary_properties._buffer = saved_buffer;
|
||||
}
|
||||
|
||||
/* invalid property name */
|
||||
{
|
||||
ddsrt_free(tokens._buffer[0].binary_properties._buffer[0].name);
|
||||
tokens._buffer[0].binary_properties._buffer[0].name = ddsrt_strdup("invalid_key_mat_name");
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
ddsrt_free(tokens._buffer[0].binary_properties._buffer[0].name);
|
||||
tokens._buffer[0].binary_properties._buffer[0].name = ddsrt_strdup(CRYPTO_TOKEN_PROPERTY_NAME);
|
||||
}
|
||||
|
||||
DDS_Security_DataHolderSeq_deinit(&tokens);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_datareader_crypto_tokens, invalid_key_material, .init = suite_set_remote_datareader_crypto_tokens_init, .fini = suite_set_remote_datareader_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_DatawriterCryptoTokenSeq tokens;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC keymat;
|
||||
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens != NULL);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
create_reader_tokens_no_key_material(&tokens);
|
||||
|
||||
/* empty key material */
|
||||
{
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
/* invalid transform kind */
|
||||
{
|
||||
init_key_material(&keymat, false);
|
||||
keymat.transformation_kind[2] = 1;
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* no master salt */
|
||||
{
|
||||
init_key_material(&keymat, false);
|
||||
|
||||
DDS_Security_OctetSeq_deinit(&keymat.master_salt);
|
||||
keymat.master_salt._buffer = NULL;
|
||||
keymat.master_salt._length = keymat.master_salt._maximum = 0;
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* empty master salt */
|
||||
{
|
||||
init_key_material(&keymat, false);
|
||||
|
||||
memset(keymat.master_salt._buffer, 0, keymat.master_salt._length);
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* incorrect master salt */
|
||||
{
|
||||
init_key_material(&keymat, false);
|
||||
|
||||
keymat.master_salt._length = 16;
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* no master sender key */
|
||||
{
|
||||
init_key_material(&keymat, false);
|
||||
|
||||
DDS_Security_OctetSeq_deinit(&keymat.master_sender_key);
|
||||
|
||||
keymat.master_sender_key._buffer = NULL;
|
||||
keymat.master_sender_key._length = keymat.master_sender_key._maximum = 0;
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* empty master sender key */
|
||||
{
|
||||
init_key_material(&keymat, false);
|
||||
|
||||
memset(keymat.master_sender_key._buffer, 0, keymat.master_sender_key._length);
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* incorrect master sender key */
|
||||
{
|
||||
init_key_material(&keymat, false);
|
||||
|
||||
memset(keymat.master_sender_key._buffer, 0, keymat.master_sender_key._length);
|
||||
keymat.master_sender_key._length = 16;
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* no master receiver specific key */
|
||||
{
|
||||
init_key_material(&keymat, true);
|
||||
|
||||
DDS_Security_OctetSeq_deinit(&keymat.master_receiver_specific_key);
|
||||
|
||||
keymat.master_receiver_specific_key._buffer = NULL;
|
||||
keymat.master_receiver_specific_key._length = keymat.master_receiver_specific_key._maximum = 0;
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* nempty master receiver specific key */
|
||||
{
|
||||
init_key_material(&keymat, true);
|
||||
|
||||
memset(keymat.master_receiver_specific_key._buffer, 0, keymat.master_receiver_specific_key._length);
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* incorrect master receiver specific key */
|
||||
{
|
||||
init_key_material(&keymat, true);
|
||||
|
||||
memset(keymat.master_receiver_specific_key._buffer, 0, keymat.master_receiver_specific_key._length);
|
||||
keymat.master_receiver_specific_key._length = 16;
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
/* invalid key material */
|
||||
{
|
||||
init_key_material(&keymat, true);
|
||||
|
||||
memset(keymat.master_receiver_specific_key._buffer, 0, keymat.master_receiver_specific_key._length);
|
||||
serialize_key_material(&tokens._buffer[0].binary_properties._buffer[0].value, &keymat);
|
||||
|
||||
RAND_bytes(tokens._buffer[0].binary_properties._buffer[0].value._buffer, (int) tokens._buffer[0].binary_properties._buffer[0].value._length);
|
||||
|
||||
result = crypto->crypto_key_exchange->set_remote_datareader_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_writer_crypto,
|
||||
remote_reader_crypto,
|
||||
&tokens,
|
||||
&exception);
|
||||
|
||||
if (!result)
|
||||
printf("set_remote_datareader_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
DDS_Security_OctetSeq_deinit(&tokens._buffer[0].binary_properties._buffer[0].value);
|
||||
deinit_key_material(&keymat);
|
||||
}
|
||||
|
||||
DDS_Security_DataHolderSeq_deinit(&tokens);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,545 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
#include "dds/ddsrt/types.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
#include "dds/security/core/dds_security_serialize.h"
|
||||
#include "dds/security/core/dds_security_utils.h"
|
||||
#include "dds/security/core/shared_secret.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "common/src/loader.h"
|
||||
#include "crypto_objects.h"
|
||||
|
||||
#define TEST_SHARED_SECRET_SIZE 32
|
||||
|
||||
static const char *CRYPTO_TOKEN_CLASS_ID = "DDS:Crypto:AES_GCM_GMA";
|
||||
static const char *CRYPTO_TOKEN_PROPERTY_NAME = "dds.cryp.keymat";
|
||||
|
||||
static struct plugins_hdl *plugins = NULL;
|
||||
static dds_security_cryptography *crypto = NULL;
|
||||
|
||||
static DDS_Security_IdentityHandle local_participant_identity = 1;
|
||||
static DDS_Security_IdentityHandle remote_participant_identity = 2;
|
||||
|
||||
static DDS_Security_ParticipantCryptoHandle local_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoHandle remote_crypto_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
|
||||
static DDS_Security_SharedSecretHandleImpl *shared_secret_handle_impl = NULL;
|
||||
static DDS_Security_SharedSecretHandle shared_secret_handle = DDS_SECURITY_HANDLE_NIL;
|
||||
static DDS_Security_ParticipantCryptoTokenSeq tokens;
|
||||
|
||||
static void allocate_shared_secret(void)
|
||||
{
|
||||
shared_secret_handle_impl = ddsrt_malloc(sizeof(DDS_Security_SharedSecretHandleImpl));
|
||||
|
||||
shared_secret_handle_impl->shared_secret = ddsrt_malloc(TEST_SHARED_SECRET_SIZE * sizeof(unsigned char));
|
||||
shared_secret_handle_impl->shared_secret_size = TEST_SHARED_SECRET_SIZE;
|
||||
for (int i = 0; i < shared_secret_handle_impl->shared_secret_size; i++)
|
||||
{
|
||||
shared_secret_handle_impl->shared_secret[i] = (unsigned char)(i % 20);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
shared_secret_handle_impl->challenge1[i] = (unsigned char)(i % 15);
|
||||
shared_secret_handle_impl->challenge2[i] = (unsigned char)(i % 12);
|
||||
}
|
||||
shared_secret_handle = (DDS_Security_SharedSecretHandle)shared_secret_handle_impl;
|
||||
}
|
||||
|
||||
static void deallocate_shared_secret(void)
|
||||
{
|
||||
ddsrt_free(shared_secret_handle_impl->shared_secret);
|
||||
ddsrt_free(shared_secret_handle_impl);
|
||||
}
|
||||
|
||||
static void prepare_participant_security_attributes(DDS_Security_ParticipantSecurityAttributes *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(DDS_Security_ParticipantSecurityAttributes));
|
||||
attributes->allow_unauthenticated_participants = false;
|
||||
attributes->is_access_protected = false;
|
||||
attributes->is_discovery_protected = false;
|
||||
attributes->is_liveliness_protected = false;
|
||||
attributes->is_rtps_protected = true;
|
||||
attributes->plugin_participant_attributes = DDS_SECURITY_PARTICIPANT_ATTRIBUTES_FLAG_IS_VALID;
|
||||
attributes->plugin_participant_attributes |= DDS_SECURITY_PLUGIN_PARTICIPANT_ATTRIBUTES_FLAG_IS_RTPS_ENCRYPTED;
|
||||
}
|
||||
|
||||
static int register_local_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle participant_permissions = 3; //valid dummy value
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantSecurityAttributes participant_security_attributes;
|
||||
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
prepare_participant_security_attributes(&participant_security_attributes);
|
||||
|
||||
local_crypto_handle =
|
||||
crypto->crypto_key_factory->register_local_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_participant_identity,
|
||||
participant_permissions,
|
||||
&participant_properties,
|
||||
&participant_security_attributes,
|
||||
&exception);
|
||||
|
||||
if (local_crypto_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
printf("register_local_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
return local_crypto_handle ? 0 : -1;
|
||||
}
|
||||
|
||||
static int register_remote_participant(void)
|
||||
{
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PermissionsHandle remote_participant_permissions = 5;
|
||||
|
||||
remote_crypto_handle =
|
||||
crypto->crypto_key_factory->register_matched_remote_participant(
|
||||
crypto->crypto_key_factory,
|
||||
local_crypto_handle,
|
||||
remote_participant_identity,
|
||||
remote_participant_permissions,
|
||||
shared_secret_handle,
|
||||
&exception);
|
||||
|
||||
if (remote_crypto_handle == DDS_SECURITY_HANDLE_NIL)
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
return remote_crypto_handle ? 0 : -1;
|
||||
}
|
||||
|
||||
static int create_crypto_tokens(void)
|
||||
{
|
||||
DDS_Security_boolean status;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
status = crypto->crypto_key_exchange->create_local_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
&tokens,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&exception);
|
||||
if (!status)
|
||||
printf("register_matched_remote_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
return status ? 0 : -1;
|
||||
}
|
||||
|
||||
static void unregister_participants(void)
|
||||
{
|
||||
DDS_Security_boolean status;
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
if (tokens._length != 0)
|
||||
{
|
||||
status = crypto->crypto_key_exchange->return_crypto_tokens(crypto->crypto_key_exchange, &tokens, &exception);
|
||||
if (!status)
|
||||
printf("return_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
if (local_crypto_handle)
|
||||
{
|
||||
status = crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, local_crypto_handle, &exception);
|
||||
if (!status)
|
||||
printf("unregister_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
|
||||
if (remote_crypto_handle)
|
||||
{
|
||||
status = crypto->crypto_key_factory->unregister_participant(crypto->crypto_key_factory, remote_crypto_handle, &exception);
|
||||
if (!status)
|
||||
printf("unregister_participant: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
}
|
||||
}
|
||||
|
||||
static void suite_set_remote_participant_crypto_tokens_init(void)
|
||||
{
|
||||
allocate_shared_secret();
|
||||
|
||||
CU_ASSERT_FATAL ((plugins = load_plugins(
|
||||
NULL /* Access Control */,
|
||||
NULL /* Authentication */,
|
||||
&crypto /* Cryptograpy */)) != NULL);
|
||||
CU_ASSERT_EQUAL_FATAL (register_local_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (register_remote_participant(), 0);
|
||||
CU_ASSERT_EQUAL_FATAL (create_crypto_tokens(), 0);
|
||||
}
|
||||
|
||||
static void suite_set_remote_participant_crypto_tokens_fini(void)
|
||||
{
|
||||
unregister_participants();
|
||||
deallocate_shared_secret();
|
||||
unload_plugins(plugins);
|
||||
}
|
||||
|
||||
static void reset_exception(DDS_Security_SecurityException *ex)
|
||||
{
|
||||
ex->code = 0;
|
||||
ex->minor_code = 0;
|
||||
ddsrt_free(ex->message);
|
||||
ex->message = NULL;
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_participant_crypto_tokens, happy_day, .init = suite_set_remote_participant_crypto_tokens_init, .fini = suite_set_remote_participant_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->set_remote_participant_crypto_tokens != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
|
||||
/* Now call the function. */
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT_FATAL(result);
|
||||
CU_ASSERT(exception.code == 0);
|
||||
CU_ASSERT(exception.message == NULL);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_participant_crypto_tokens, invalid_args, .init = suite_set_remote_participant_crypto_tokens_init, .fini = suite_set_remote_participant_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_participant_crypto_tokens != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
|
||||
/* invalid token seq = NULL */
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
NULL,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
0,
|
||||
remote_crypto_handle,
|
||||
&tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_remote_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = DDS_SECURITY_HANDLE_NIL */
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
0,
|
||||
&tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_remote_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid local_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
1,
|
||||
remote_crypto_handle,
|
||||
&tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_remote_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid remote_crypto_handle = 1 */
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
1,
|
||||
&tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_remote_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
}
|
||||
|
||||
CU_Test(ddssec_builtin_set_remote_participant_crypto_tokens, invalid_tokens, .init = suite_set_remote_participant_crypto_tokens_init, .fini = suite_set_remote_participant_crypto_tokens_fini)
|
||||
{
|
||||
DDS_Security_boolean result;
|
||||
|
||||
/* Dummy (even un-initialized) data for now. */
|
||||
DDS_Security_SecurityException exception = {NULL, 0, 0};
|
||||
DDS_Security_PropertySeq participant_properties;
|
||||
DDS_Security_ParticipantCryptoTokenSeq invalid_tokens;
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC keymat;
|
||||
|
||||
/* Check if we actually have the validate_local_identity() function. */
|
||||
CU_ASSERT_FATAL(crypto != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange != NULL);
|
||||
CU_ASSERT_FATAL(crypto->crypto_key_exchange->create_local_participant_crypto_tokens != NULL);
|
||||
|
||||
memset(&exception, 0, sizeof(DDS_Security_SecurityException));
|
||||
memset(&participant_properties, 0, sizeof(participant_properties));
|
||||
memset(&keymat, 0, sizeof(keymat));
|
||||
|
||||
memset(&invalid_tokens, 0, sizeof(invalid_tokens));
|
||||
|
||||
/* empty token sequence */
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* DDS_Security_ParticipantCryptoTokenSeq with empty token */
|
||||
invalid_tokens._length = 1;
|
||||
invalid_tokens._buffer = DDS_Security_DataHolderSeq_allocbuf(1);
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid token class id */
|
||||
invalid_tokens._buffer[0].class_id = ddsrt_strdup("invalid class");
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
ddsrt_free(invalid_tokens._buffer[0].class_id);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* no key material, binary_property missing */
|
||||
invalid_tokens._buffer[0].class_id = ddsrt_strdup(CRYPTO_TOKEN_CLASS_ID);
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* no key material, property is empty */
|
||||
invalid_tokens._buffer[0].binary_properties._length = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer = DDS_Security_BinaryPropertySeq_allocbuf(1);
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid property name */
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].name = ddsrt_strdup("invalid_key_mat_name");
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
ddsrt_free(invalid_tokens._buffer[0].binary_properties._buffer[0].name);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* invalid property name */
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].name = ddsrt_strdup(CRYPTO_TOKEN_PROPERTY_NAME);
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
/* empty key material */
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._length = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._maximum = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._buffer = (unsigned char *)&keymat;
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
keymat.transformation_kind[3] = 5;
|
||||
|
||||
/* invalid CryptoTransformKind */
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._length = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._maximum = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._buffer = (unsigned char *)&keymat;
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
keymat.transformation_kind[3] = 2;
|
||||
keymat.master_salt._length = 16;
|
||||
keymat.master_salt._buffer = DDS_Security_OctetSeq_allocbuf(32);
|
||||
|
||||
/* invalid master salt */
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._length = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._maximum = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._buffer = (unsigned char *)&keymat;
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
keymat.master_salt._length = 32;
|
||||
|
||||
/* invalid master salt */
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._length = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._maximum = 1;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._buffer = (unsigned char *)&keymat;
|
||||
result = crypto->crypto_key_exchange->set_remote_participant_crypto_tokens(
|
||||
crypto->crypto_key_exchange,
|
||||
local_crypto_handle,
|
||||
remote_crypto_handle,
|
||||
&invalid_tokens,
|
||||
&exception);
|
||||
if (!result)
|
||||
printf("set_local_participant_crypto_tokens: %s\n", exception.message ? exception.message : "Error message missing");
|
||||
|
||||
CU_ASSERT(!result);
|
||||
CU_ASSERT(exception.code != 0);
|
||||
CU_ASSERT(exception.message != NULL);
|
||||
reset_exception(&exception);
|
||||
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._length = 0;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._maximum = 0;
|
||||
invalid_tokens._buffer[0].binary_properties._buffer[0].value._buffer = NULL;
|
||||
DDS_Security_ParticipantCryptoTokenSeq_deinit(&invalid_tokens);
|
||||
DDS_Security_OctetSeq_deinit(&keymat.master_salt);
|
||||
}
|
|
@ -25,27 +25,12 @@
|
|||
#include "dds/ddsrt/string.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/environ.h"
|
||||
#include "dds/ddsrt/endian.h"
|
||||
#include "CUnit/CUnit.h"
|
||||
#include "CUnit/Test.h"
|
||||
#include "assert.h"
|
||||
|
||||
|
||||
#if DDSRT_ENDIAN == DDSRT_LITTLE_ENDIAN
|
||||
unsigned bswap4u (unsigned x);
|
||||
unsigned bswap4u (unsigned x)
|
||||
{
|
||||
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
|
||||
}
|
||||
#define toBE4u(x) bswap4u (x)
|
||||
#define fromBE4u(x) bswap4u (x)
|
||||
#else
|
||||
#define toBE4u(x) (x)
|
||||
#define fromBE4u(x) (x)
|
||||
#endif
|
||||
|
||||
|
||||
static const char * AUTH_PROTOCOL_CLASS_ID = "DDS:Auth:PKI-DH:1.0";
|
||||
static const char * PERM_ACCESS_CLASS_ID = "DDS:Access:Permissions:1.0";
|
||||
|
||||
|
@ -582,9 +567,9 @@ validate_local_identity(const char* trusted_ca_dir)
|
|||
local_participant_data = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&local_participant_data->key[0], &local_participant_guid, 12);
|
||||
/* convert from big-endian format to native format */
|
||||
local_participant_data->key[0] = fromBE4u(local_participant_data->key[0]);
|
||||
local_participant_data->key[1] = fromBE4u(local_participant_data->key[1]);
|
||||
local_participant_data->key[2] = fromBE4u(local_participant_data->key[2]);
|
||||
local_participant_data->key[0] = ddsrt_fromBE4u(local_participant_data->key[0]);
|
||||
local_participant_data->key[1] = ddsrt_fromBE4u(local_participant_data->key[1]);
|
||||
local_participant_data->key[2] = ddsrt_fromBE4u(local_participant_data->key[2]);
|
||||
|
||||
initialize_identity_token(&local_participant_data->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&local_participant_data->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -853,9 +838,9 @@ validate_remote_identities (const char *remote_id_certificate)
|
|||
|
||||
remote_participant_data1 = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&remote_participant_data1->key[0], &remote_participant_guid1, 12);
|
||||
remote_participant_data1->key[0] = fromBE4u(remote_participant_data1->key[0]);
|
||||
remote_participant_data1->key[1] = fromBE4u(remote_participant_data1->key[1]);
|
||||
remote_participant_data1->key[2] = fromBE4u(remote_participant_data1->key[2]);
|
||||
remote_participant_data1->key[0] = ddsrt_fromBE4u(remote_participant_data1->key[0]);
|
||||
remote_participant_data1->key[1] = ddsrt_fromBE4u(remote_participant_data1->key[1]);
|
||||
remote_participant_data1->key[2] = ddsrt_fromBE4u(remote_participant_data1->key[2]);
|
||||
|
||||
|
||||
initialize_identity_token(&remote_participant_data1->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -866,9 +851,9 @@ validate_remote_identities (const char *remote_id_certificate)
|
|||
|
||||
remote_participant_data2 = DDS_Security_ParticipantBuiltinTopicData_alloc();
|
||||
memcpy(&remote_participant_data2->key[0], &remote_participant_guid2, 12);
|
||||
remote_participant_data2->key[0] = fromBE4u(remote_participant_data2->key[0]);
|
||||
remote_participant_data2->key[1] = fromBE4u(remote_participant_data2->key[1]);
|
||||
remote_participant_data2->key[2] = fromBE4u(remote_participant_data2->key[2]);
|
||||
remote_participant_data2->key[0] = ddsrt_fromBE4u(remote_participant_data2->key[0]);
|
||||
remote_participant_data2->key[1] = ddsrt_fromBE4u(remote_participant_data2->key[1]);
|
||||
remote_participant_data2->key[2] = ddsrt_fromBE4u(remote_participant_data2->key[2]);
|
||||
|
||||
initialize_identity_token(&remote_participant_data2->identity_token, RSA_2048_ALGORITHM_NAME, RSA_2048_ALGORITHM_NAME);
|
||||
initialize_permissions_token(&remote_participant_data2->permissions_token, RSA_2048_ALGORITHM_NAME);
|
||||
|
@ -1019,7 +1004,7 @@ serializer_participant_data(
|
|||
DDS_Security_Serializer serializer;
|
||||
serializer = DDS_Security_Serializer_new(1024, 1024);
|
||||
|
||||
DDD_Security_Serialize_ParticipantBuiltinTopicData(serializer, pdata);
|
||||
DDS_Security_Serialize_ParticipantBuiltinTopicData(serializer, pdata);
|
||||
DDS_Security_Serializer_buffer(serializer, buffer, size);
|
||||
DDS_Security_Serializer_free(serializer);
|
||||
}
|
||||
|
|
|
@ -65,12 +65,12 @@ DDS_Security_Serialize_DataHolderSeq(
|
|||
const DDS_Security_DataHolderSeq *seq);
|
||||
|
||||
DDS_EXPORT void
|
||||
DDD_Security_Serialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Serialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Serializer ser,
|
||||
DDS_Security_ParticipantBuiltinTopicData *pdata);
|
||||
|
||||
DDS_EXPORT void
|
||||
DDD_Security_Serialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Serialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Serializer ser,
|
||||
const DDS_Security_KeyMaterial_AES_GCM_GMAC *data);
|
||||
|
||||
|
@ -84,18 +84,18 @@ DDS_Security_Deserializer_free(
|
|||
DDS_Security_Deserializer deserializer);
|
||||
|
||||
DDS_EXPORT int
|
||||
DDD_Security_Deserialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Deserialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Deserializer deserializer,
|
||||
DDS_Security_ParticipantBuiltinTopicData *pdata,
|
||||
DDS_Security_SecurityException *ex);
|
||||
|
||||
DDS_EXPORT void
|
||||
DDD_Security_BuiltinTopicKeyBE(
|
||||
DDS_Security_BuiltinTopicKeyBE(
|
||||
DDS_Security_BuiltinTopicKey_t dst,
|
||||
const DDS_Security_BuiltinTopicKey_t src);
|
||||
|
||||
DDS_EXPORT int
|
||||
DDD_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Deserializer dser,
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC *data);
|
||||
|
||||
|
|
|
@ -50,11 +50,11 @@ typedef enum
|
|||
|
||||
typedef struct DDS_Security_KeyMaterial_AES_GCM_GMAC {
|
||||
DDS_Security_CryptoTransformKind transformation_kind;
|
||||
DDS_Security_OctetSeq master_salt; /*size shall be 32*/
|
||||
DDS_Security_OctetSeq master_salt; /*size shall be 16 or 32*/
|
||||
DDS_Security_CryptoTransformKeyId sender_key_id;
|
||||
DDS_Security_OctetSeq master_sender_key; /*size shall be 32*/
|
||||
DDS_Security_OctetSeq master_sender_key; /*size shall be 16 or 32*/
|
||||
DDS_Security_CryptoTransformKeyId receiver_specific_key_id;
|
||||
DDS_Security_OctetSeq master_receiver_specific_key; /*size shall be 32*/
|
||||
DDS_Security_OctetSeq master_receiver_specific_key; /*size shall be 0, 16 or 32*/
|
||||
} DDS_Security_KeyMaterial_AES_GCM_GMAC;
|
||||
|
||||
struct CryptoTransformIdentifier {
|
||||
|
|
|
@ -341,39 +341,39 @@ ddssec_strchrs (
|
|||
|
||||
|
||||
#define DDS_Security_ParticipantCryptoTokenSeq_alloc() \
|
||||
(DDS_Security_ParticipantCryptoTokenSeq *)DDS_Security_DataHolderSeq_alloc())
|
||||
DDS_Security_DataHolderSeq_alloc())
|
||||
#define DDS_Security_ParticipantCryptoTokenSeq_freebuf(s) \
|
||||
DDS_Security_DataHolderSeq_freebuf((DDS_Security_DataHolderSeq *)(s))
|
||||
DDS_Security_DataHolderSeq_freebuf(s)
|
||||
#define DDS_Security_ParticipantCryptoTokenSeq_free(s) \
|
||||
DDS_Security_DataHolderSeq_free((DDS_Security_DataHolderSeq *)(s))
|
||||
DDS_Security_DataHolderSeq_free(s)
|
||||
#define DDS_Security_ParticipantCryptoTokenSeq_deinit(s) \
|
||||
DDS_Security_DataHolderSeq_deinit((DDS_Security_DataHolderSeq *)(s))
|
||||
DDS_Security_DataHolderSeq_deinit(s)
|
||||
#define DDS_Security_ParticipantCryptoTokenSeq_copy(d,s) \
|
||||
DDS_Security_DataHolderSeq_copy((DDS_Security_DataHolderSeq *)(d), (const DDS_Security_DataHolderSeq *)(s))
|
||||
DDS_Security_DataHolderSeq_copy((d), (s))
|
||||
|
||||
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_alloc() (DDS_Security_ParticipantCryptoHandleSeq*)DDS_Security_HandleSeq_alloc()
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_alloc() DDS_Security_HandleSeq_alloc()
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_allocbuf(l) DDS_Security_HandleSeq_allocbuf(l)
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_freebuf(s) DDS_Security_HandleSeq_freebuf((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_free(s) DDS_Security_HandleSeq_free((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_deinit(s) DDS_Security_HandleSeq_deinit((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_freebuf(s) DDS_Security_HandleSeq_freebuf(s)
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_free(s) DDS_Security_HandleSeq_free(s)
|
||||
#define DDS_Security_ParticipantCryptoHandleSeq_deinit(s) DDS_Security_HandleSeq_deinit(s)
|
||||
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_alloc() (DDS_Security_DatawriterCryptoHandleSeq*)DDS_Security_HandleSeq_alloc()
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_alloc() DDS_Security_HandleSeq_alloc()
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_allocbuf(l) DDS_Security_HandleSeq_allocbuf(l)
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_freebuf(s) DDS_Security_HandleSeq_freebuf((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_free(s) DDS_Security_HandleSeq_free((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_deinit(s) DDS_Security_HandleSeq_deinit((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_freebuf(s) DDS_Security_HandleSeq_freebuf(s)
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_free(s) DDS_Security_HandleSeq_free(s)
|
||||
#define DDS_Security_DatawriterCryptoHandleSeq_deinit(s) DDS_Security_HandleSeq_deinit(s)
|
||||
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_alloc() (DDS_Security_DatareaderCryptoHandleSeq*)DDS_Security_HandleSeq_alloc()
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_alloc() DDS_Security_HandleSeq_alloc()
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_allocbuf(l) DDS_Security_HandleSeq_allocbuf(l)
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_freebuf(s) DDS_Security_HandleSeq_freebuf((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_free(s) DDS_Security_HandleSeq_free((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_deinit(s) DDS_Security_HandleSeq_deinit((DDS_Security_HandleSeq*)s)
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_freebuf(s) DDS_Security_HandleSeq_freebuf(s)
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_free(s) DDS_Security_HandleSeq_free(s)
|
||||
#define DDS_Security_DatareaderCryptoHandleSeq_deinit(s) DDS_Security_HandleSeq_deinit(s)
|
||||
|
||||
#define DDS_Security_CryptoTokenSeq_alloc() (DDS_Security_CryptoTokenSeq*)DDS_Security_DataHolderSeq_alloc()
|
||||
#define DDS_Security_CryptoTokenSeq_alloc() DDS_Security_DataHolderSeq_alloc()
|
||||
#define DDS_Security_CryptoTokenSeq_allocbuf(l) DDS_Security_DataHolderSeq_allocbuf(l)
|
||||
#define DDS_Security_CryptoTokenSeq_freebuf(s) DDS_Security_DataHolderSeq_freebuf((DDS_Security_CryptoTokenSeq*)s)
|
||||
#define DDS_Security_CryptoTokenSeq_free(s) DDS_Security_DataHolderSeq_free((DDS_Security_CryptoTokenSeq*)s)
|
||||
#define DDS_Security_CryptoTokenSeq_freebuf(s) DDS_Security_DataHolderSeq_freebuf(s)
|
||||
#define DDS_Security_CryptoTokenSeq_free(s) DDS_Security_DataHolderSeq_free(s)
|
||||
|
||||
|
||||
/* for DEBUG purposes */
|
||||
|
|
|
@ -9,32 +9,25 @@
|
|||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SRC_SECURITY_CORE_INCLUDE_SHARED_SECRET_HANDLE_H_
|
||||
#define SRC_SECURITY_CORE_INCLUDE_SHARED_SECRET_HANDLE_H_
|
||||
|
||||
#include "dds/export.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "dds/export.h"
|
||||
#include "dds/security/dds_security_api.h"
|
||||
|
||||
|
||||
typedef struct DDS_Security_SharedSecretHandleImpl {
|
||||
|
||||
DDS_Security_octet* shared_secret;
|
||||
DDS_Security_long shared_secret_size;
|
||||
DDS_Security_octet challenge1[DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE];
|
||||
DDS_Security_octet challenge2[DDS_SECURITY_AUTHENTICATION_CHALLENGE_SIZE];
|
||||
|
||||
} DDS_Security_SharedSecretHandleImpl;
|
||||
|
||||
DDS_EXPORT const DDS_Security_octet* get_challenge1_from_secret_handle( DDS_Security_SharedSecretHandle handle);
|
||||
|
||||
DDS_EXPORT const DDS_Security_octet* get_challenge2_from_secret_handle( DDS_Security_SharedSecretHandle handle );
|
||||
|
||||
DDS_EXPORT const DDS_Security_octet* get_secret_from_secret_handle( DDS_Security_SharedSecretHandle handle );
|
||||
|
||||
DDS_EXPORT int32_t get_secret_size_from_secret_handle( DDS_Security_SharedSecretHandle handle );
|
||||
DDS_EXPORT const DDS_Security_octet* get_challenge1_from_secret_handle (DDS_Security_SharedSecretHandle handle);
|
||||
DDS_EXPORT const DDS_Security_octet* get_challenge2_from_secret_handle (DDS_Security_SharedSecretHandle handle);
|
||||
DDS_EXPORT const DDS_Security_octet* get_secret_from_secret_handle (DDS_Security_SharedSecretHandle handle);
|
||||
DDS_EXPORT size_t get_secret_size_from_secret_handle (DDS_Security_SharedSecretHandle handle);
|
||||
|
||||
#endif /* SRC_SECURITY_CORE_INCLUDE_SHARED_SECRET_H_ */
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "dds/ddsrt/bswap.h"
|
||||
#include "dds/ddsrt/heap.h"
|
||||
#include "dds/ddsrt/atomics.h"
|
||||
#include "dds/ddsrt/string.h"
|
||||
|
@ -92,7 +93,6 @@
|
|||
#define PID_PARTICIPANT_SECURITY_INFO 0x1005u
|
||||
#define PID_IDENTITY_STATUS_TOKEN 0x1006u
|
||||
|
||||
|
||||
struct DDS_Security_Serializer {
|
||||
unsigned char *buffer;
|
||||
size_t size;
|
||||
|
@ -211,7 +211,7 @@ DDS_Security_Serialize_update_len(
|
|||
{
|
||||
unsigned short len;
|
||||
|
||||
len = (unsigned short)(ser->offset - ser->marker - sizeof(unsigned short));
|
||||
len = (unsigned short)(ser->offset - ser->marker - sizeof(len));
|
||||
*(unsigned short *)&(ser->buffer[ser->marker]) = ddsrt_toBE2u(len);
|
||||
}
|
||||
|
||||
|
@ -220,11 +220,11 @@ DDS_Security_Serialize_uint16(
|
|||
DDS_Security_Serializer ser,
|
||||
unsigned short value)
|
||||
{
|
||||
serbuffer_align(ser, sizeof(unsigned short));
|
||||
serbuffer_adjust_size(ser, sizeof(unsigned short));
|
||||
serbuffer_align(ser, sizeof(value));
|
||||
serbuffer_adjust_size(ser, sizeof(value));
|
||||
|
||||
*(unsigned short *)&(ser->buffer[ser->offset]) = ddsrt_toBE2u(value);
|
||||
ser->offset += sizeof(unsigned short);
|
||||
ser->offset += sizeof(value);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -232,11 +232,11 @@ DDS_Security_Serialize_uint32_t(
|
|||
DDS_Security_Serializer ser,
|
||||
uint32_t value)
|
||||
{
|
||||
serbuffer_align(ser, sizeof(uint32_t));
|
||||
serbuffer_adjust_size(ser, sizeof(uint32_t));
|
||||
serbuffer_align(ser, sizeof(value));
|
||||
serbuffer_adjust_size(ser, sizeof(value));
|
||||
|
||||
*(uint32_t *)&(ser->buffer[ser->offset]) = ddsrt_toBE4u(value);
|
||||
ser->offset += sizeof(uint32_t);
|
||||
ser->offset += sizeof(value);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -244,12 +244,10 @@ DDS_Security_Serialize_string(
|
|||
DDS_Security_Serializer ser,
|
||||
const char *str)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
size_t len = strlen(str) + 1;
|
||||
|
||||
DDS_Security_Serialize_uint32_t(ser, (uint32_t)len);
|
||||
serbuffer_adjust_size(ser, len );
|
||||
serbuffer_adjust_size(ser, len);
|
||||
|
||||
memcpy(&(ser->buffer[ser->offset]), str, len);
|
||||
ser->offset += len;
|
||||
|
@ -416,7 +414,7 @@ DDS_Security_Serialize_ParticipantSecurityInfo(
|
|||
|
||||
|
||||
void
|
||||
DDD_Security_Serialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Serialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Serializer ser,
|
||||
DDS_Security_ParticipantBuiltinTopicData *pdata)
|
||||
{
|
||||
|
@ -432,7 +430,7 @@ DDD_Security_Serialize_ParticipantBuiltinTopicData(
|
|||
}
|
||||
|
||||
static void
|
||||
DDD_Security_Serialize_OctetArray(
|
||||
DDS_Security_Serialize_OctetArray(
|
||||
DDS_Security_Serializer ser,
|
||||
const DDS_Security_octet *data,
|
||||
uint32_t length)
|
||||
|
@ -443,15 +441,15 @@ DDD_Security_Serialize_OctetArray(
|
|||
}
|
||||
|
||||
void
|
||||
DDD_Security_Serialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Serialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Serializer ser,
|
||||
const DDS_Security_KeyMaterial_AES_GCM_GMAC *data)
|
||||
{
|
||||
DDD_Security_Serialize_OctetArray(ser, data->transformation_kind, sizeof(data->transformation_kind));
|
||||
DDS_Security_Serialize_OctetArray(ser, data->transformation_kind, sizeof(data->transformation_kind));
|
||||
DDS_Security_Serialize_OctetSeq(ser, &data->master_salt);
|
||||
DDD_Security_Serialize_OctetArray(ser, data->sender_key_id, sizeof(data->sender_key_id));
|
||||
DDS_Security_Serialize_OctetArray(ser, data->sender_key_id, sizeof(data->sender_key_id));
|
||||
DDS_Security_Serialize_OctetSeq(ser, &data->master_sender_key);
|
||||
DDD_Security_Serialize_OctetArray(ser, data->receiver_specific_key_id, sizeof(data->receiver_specific_key_id));
|
||||
DDS_Security_Serialize_OctetArray(ser, data->receiver_specific_key_id, sizeof(data->receiver_specific_key_id));
|
||||
DDS_Security_Serialize_OctetSeq(ser, &data->master_receiver_specific_key);
|
||||
}
|
||||
|
||||
|
@ -500,7 +498,7 @@ DDS_Security_Deserialize_uint16(
|
|||
DDS_Security_Deserializer dser,
|
||||
unsigned short *value)
|
||||
{
|
||||
size_t l = sizeof(unsigned short);
|
||||
size_t l = sizeof(*value);
|
||||
|
||||
DDS_Security_Deserialize_align(dser, l);
|
||||
|
||||
|
@ -519,7 +517,7 @@ DDS_Security_Deserialize_uint32_t(
|
|||
DDS_Security_Deserializer dser,
|
||||
uint32_t *value)
|
||||
{
|
||||
size_t l = sizeof(uint32_t);
|
||||
size_t l = sizeof(*value);
|
||||
|
||||
DDS_Security_Deserialize_align(dser, l);
|
||||
|
||||
|
@ -692,9 +690,7 @@ DDS_Security_Deserialize_BuiltinTopicKey(
|
|||
DDS_Security_Deserializer dser,
|
||||
DDS_Security_BuiltinTopicKey_t key)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = DDS_Security_Deserialize_uint32_t(dser, (uint32_t *)&key[0]) &&
|
||||
int r = DDS_Security_Deserialize_uint32_t(dser, (uint32_t *)&key[0]) &&
|
||||
DDS_Security_Deserialize_uint32_t(dser, (uint32_t *)&key[1]) &&
|
||||
DDS_Security_Deserialize_uint32_t(dser, (uint32_t *)&key[2]);
|
||||
|
||||
|
@ -710,16 +706,12 @@ DDS_Security_Deserialize_ParticipantSecurityInfo(
|
|||
DDS_Security_Deserializer dser,
|
||||
DDS_Security_ParticipantSecurityInfo *info)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = DDS_Security_Deserialize_uint32_t(dser, &info->participant_security_attributes) &&
|
||||
return DDS_Security_Deserialize_uint32_t(dser, &info->participant_security_attributes) &&
|
||||
DDS_Security_Deserialize_uint32_t(dser, &info->plugin_participant_security_attributes);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
DDD_Security_Deserialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Deserialize_ParticipantBuiltinTopicData(
|
||||
DDS_Security_Deserializer dser,
|
||||
DDS_Security_ParticipantBuiltinTopicData *pdata,
|
||||
DDS_Security_SecurityException *ex)
|
||||
|
@ -786,7 +778,7 @@ DDD_Security_Deserialize_ParticipantBuiltinTopicData(
|
|||
}
|
||||
|
||||
void
|
||||
DDD_Security_BuiltinTopicKeyBE(
|
||||
DDS_Security_BuiltinTopicKeyBE(
|
||||
DDS_Security_BuiltinTopicKey_t dst,
|
||||
const DDS_Security_BuiltinTopicKey_t src)
|
||||
{
|
||||
|
@ -796,18 +788,16 @@ DDD_Security_BuiltinTopicKeyBE(
|
|||
}
|
||||
|
||||
int
|
||||
DDD_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Deserialize_KeyMaterial_AES_GCM_GMAC(
|
||||
DDS_Security_Deserializer dser,
|
||||
DDS_Security_KeyMaterial_AES_GCM_GMAC *data)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
r = DDS_Security_Deserialize_OctetArray(dser, data->transformation_kind, sizeof(data->transformation_kind)) &&
|
||||
memset(data, 0, sizeof(*data));
|
||||
return
|
||||
DDS_Security_Deserialize_OctetArray(dser, data->transformation_kind, sizeof(data->transformation_kind)) &&
|
||||
DDS_Security_Deserialize_OctetSeq(dser, &data->master_salt) &&
|
||||
DDS_Security_Deserialize_OctetArray(dser, data->sender_key_id, sizeof(data->sender_key_id)) &&
|
||||
DDS_Security_Deserialize_OctetSeq(dser, &data->master_sender_key) &&
|
||||
DDS_Security_Deserialize_OctetArray(dser, data->receiver_specific_key_id, sizeof(data->receiver_specific_key_id)) &&
|
||||
DDS_Security_Deserialize_OctetSeq(dser, &data->master_receiver_specific_key);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ DDS_Security_BinaryProperty_deinit(
|
|||
}
|
||||
|
||||
ddsrt_free(p->name);
|
||||
memset (p->value._buffer, 0, p->value._length); /* because key material can be stored in binary property */
|
||||
ddsrt_free(p->value._buffer);
|
||||
}
|
||||
|
||||
|
@ -906,51 +907,45 @@ DDS_Security_KeyMaterial_AES_GCM_GMAC_deinit(
|
|||
{
|
||||
if (key_material) {
|
||||
if (key_material->master_receiver_specific_key._buffer != NULL) {
|
||||
memset (key_material->master_receiver_specific_key._buffer, 0, key_material->master_receiver_specific_key._length);
|
||||
ddsrt_free(key_material->master_receiver_specific_key._buffer);
|
||||
}
|
||||
if( key_material->master_salt._buffer != NULL){
|
||||
memset (key_material->master_salt._buffer, 0, key_material->master_salt._length);
|
||||
ddsrt_free(key_material->master_salt._buffer);
|
||||
}
|
||||
if( key_material->master_sender_key._buffer != NULL){
|
||||
memset (key_material->master_sender_key._buffer, 0, key_material->master_sender_key._length);
|
||||
ddsrt_free(key_material->master_sender_key._buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t DDS_Security_getKeySize (const DDS_Security_PropertySeq *properties)
|
||||
{
|
||||
const DDS_Security_Property_t *key_size_property;
|
||||
if (properties != NULL)
|
||||
{
|
||||
key_size_property = DDS_Security_PropertySeq_find_property (properties, "dds.sec.crypto.keysize");
|
||||
if (key_size_property != NULL && !strcmp(key_size_property->value, "128"))
|
||||
return 128;
|
||||
}
|
||||
return 256;
|
||||
}
|
||||
|
||||
DDS_Security_CryptoTransformKind_Enum
|
||||
DDS_Security_basicprotectionkind2transformationkind(
|
||||
const DDS_Security_PropertySeq *properties,
|
||||
DDS_Security_BasicProtectionKind protection)
|
||||
{
|
||||
int keysize=256;
|
||||
const DDS_Security_Property_t *key_size_property = NULL;
|
||||
if( properties != NULL ){
|
||||
key_size_property = DDS_Security_PropertySeq_find_property(
|
||||
properties, "dds.sec.crypto.keysize");
|
||||
|
||||
if (key_size_property != NULL) {
|
||||
if (strcmp(key_size_property->value, "128") == 0) {
|
||||
keysize = 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t keysize = DDS_Security_getKeySize (properties);
|
||||
switch (protection) {
|
||||
case DDS_SECURITY_BASICPROTECTION_KIND_NONE:
|
||||
return CRYPTO_TRANSFORMATION_KIND_NONE;
|
||||
case DDS_SECURITY_BASICPROTECTION_KIND_SIGN:
|
||||
if( keysize == 128 ){
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES128_GMAC;
|
||||
} else{
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES256_GMAC;
|
||||
}
|
||||
return (keysize == 128) ? CRYPTO_TRANSFORMATION_KIND_AES128_GMAC : CRYPTO_TRANSFORMATION_KIND_AES256_GMAC;
|
||||
case DDS_SECURITY_BASICPROTECTION_KIND_ENCRYPT:
|
||||
if( keysize == 128 ){
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES128_GCM;
|
||||
} else{
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES256_GCM;
|
||||
}
|
||||
return (keysize == 128) ? CRYPTO_TRANSFORMATION_KIND_AES128_GCM : CRYPTO_TRANSFORMATION_KIND_AES256_GCM;
|
||||
default:
|
||||
return CRYPTO_TRANSFORMATION_KIND_INVALID;
|
||||
}
|
||||
|
@ -961,41 +956,22 @@ DDS_Security_protectionkind2transformationkind(
|
|||
const DDS_Security_PropertySeq *properties,
|
||||
DDS_Security_ProtectionKind protection)
|
||||
{
|
||||
int keysize=256;
|
||||
const DDS_Security_Property_t *key_size_property = NULL;
|
||||
if( properties != NULL ){
|
||||
key_size_property = DDS_Security_PropertySeq_find_property(
|
||||
properties, "dds.sec.crypto.keysize");
|
||||
if (key_size_property != NULL) {
|
||||
if (strcmp(key_size_property->value, "128") == 0) {
|
||||
keysize = 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t keysize = DDS_Security_getKeySize (properties);
|
||||
switch (protection) {
|
||||
case DDS_SECURITY_PROTECTION_KIND_NONE:
|
||||
return CRYPTO_TRANSFORMATION_KIND_NONE;
|
||||
case DDS_SECURITY_PROTECTION_KIND_SIGN_WITH_ORIGIN_AUTHENTICATION:
|
||||
case DDS_SECURITY_PROTECTION_KIND_SIGN:
|
||||
if( keysize == 128 ){
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES128_GMAC;
|
||||
} else{
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES256_GMAC;
|
||||
}
|
||||
return (keysize == 128) ? CRYPTO_TRANSFORMATION_KIND_AES128_GMAC : CRYPTO_TRANSFORMATION_KIND_AES256_GMAC;
|
||||
case DDS_SECURITY_PROTECTION_KIND_ENCRYPT_WITH_ORIGIN_AUTHENTICATION:
|
||||
case DDS_SECURITY_PROTECTION_KIND_ENCRYPT:
|
||||
if( keysize == 128 ){
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES128_GCM;
|
||||
} else {
|
||||
return CRYPTO_TRANSFORMATION_KIND_AES256_GCM;
|
||||
}
|
||||
return (keysize == 128) ? CRYPTO_TRANSFORMATION_KIND_AES128_GCM : CRYPTO_TRANSFORMATION_KIND_AES256_GCM;
|
||||
default:
|
||||
return CRYPTO_TRANSFORMATION_KIND_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/* for DEBUG purposes */
|
||||
#ifndef NDEBUG
|
||||
void
|
||||
print_binary_debug(
|
||||
char* name,
|
||||
|
@ -1021,8 +997,7 @@ print_binary_properties_debug(
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
DDS_Security_config_item_prefix_t
|
||||
|
|
|
@ -13,31 +13,29 @@
|
|||
#include "dds/security/core/shared_secret.h"
|
||||
|
||||
const DDS_Security_octet*
|
||||
get_challenge1_from_secret_handle(DDS_Security_SharedSecretHandle handle)
|
||||
get_challenge1_from_secret_handle (DDS_Security_SharedSecretHandle handle)
|
||||
{
|
||||
|
||||
DDS_Security_SharedSecretHandleImpl *secret = (DDS_Security_SharedSecretHandleImpl *)(uintptr_t)handle;
|
||||
return secret->challenge1;
|
||||
}
|
||||
|
||||
const DDS_Security_octet*
|
||||
get_challenge2_from_secret_handle(DDS_Security_SharedSecretHandle handle)
|
||||
get_challenge2_from_secret_handle (DDS_Security_SharedSecretHandle handle)
|
||||
{
|
||||
DDS_Security_SharedSecretHandleImpl *secret = (DDS_Security_SharedSecretHandleImpl *)(uintptr_t)handle;
|
||||
return secret->challenge2;
|
||||
}
|
||||
|
||||
const DDS_Security_octet*
|
||||
get_secret_from_secret_handle(DDS_Security_SharedSecretHandle handle)
|
||||
get_secret_from_secret_handle (DDS_Security_SharedSecretHandle handle)
|
||||
{
|
||||
DDS_Security_SharedSecretHandleImpl *secret = (DDS_Security_SharedSecretHandleImpl *)(uintptr_t)handle;
|
||||
return secret->shared_secret;
|
||||
}
|
||||
|
||||
|
||||
int32_t
|
||||
get_secret_size_from_secret_handle( DDS_Security_SharedSecretHandle handle ){
|
||||
size_t
|
||||
get_secret_size_from_secret_handle (DDS_Security_SharedSecretHandle handle)
|
||||
{
|
||||
DDS_Security_SharedSecretHandleImpl *secret = (DDS_Security_SharedSecretHandleImpl *)(uintptr_t)handle;
|
||||
return secret->shared_secret_size;
|
||||
|
||||
return (size_t) secret->shared_secret_size;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue