diff --git a/CMakeLists.txt b/CMakeLists.txt index 4514ff5971d..b2e92a1df75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,6 +165,7 @@ if(SECURITY) else() find_package(OpenSSL) endif() +find_package(LibP11) if(OPENSSL_FOUND) message(STATUS "OpenSSL library ${OPENSSL_VERSION} found...") diff --git a/README.md b/README.md index af7c2724a96..4e47ab248aa 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,22 @@ choco install -y -s <PATH\TO\DOWNLOADS\> asio tinyxml2 Please replace `<PATH\TO\DOWNLOADS>` with the folder you downloaded the packages to. +##### Libp11 library + +Libp11 provides PKCS#11 support for openSSL. This is an optional dependency, +that is needed only when *eprosima Fast DDS* is used with security and PKCS#11 URLs. + +On Linux, you can install libp11 using the package manager of your Linux distribution. +For example, on Ubuntu you can install them by using its package manager with the next command. + +```bash +sudo apt install libp11-dev libengine-pkcs11-openssl +``` + +On Windows, you can download and compile the library from this +[ROS2 Github repository](https://github.com/OpenSC/libp11). +Follow the instructions on the repository to compile it on your platform. + #### Colcon installation [colcon](https://colcon.readthedocs.io) is a command line tool to build sets of software packages. diff --git a/cmake/modules/FindLibP11.cmake b/cmake/modules/FindLibP11.cmake new file mode 100644 index 00000000000..ebaaa7289b2 --- /dev/null +++ b/cmake/modules/FindLibP11.cmake @@ -0,0 +1,43 @@ +# FindLibP11 +# +# Generates an imported target associated to an available pksc11 library: +# +# + On linux relies on the apt package libp11-dev +# +# + On Windows the library must be build from sources available at https://github.com/OpenSC/libp11.git +# Given that each user must build its own binaries the following environment variables must be set to hint +# where to locate headers and binaries (semicolon-separated list see https://cmake.org/cmake/help/v3.22/variable/PackageName_ROOT.html): +# + LibP11_ROOT_32 -> to reference sources and 32 bit binaries location +# + LibP11_ROOT_64 -> to reference sources and 64 bit binaries location + +if(TARGET eProsima_p11) + return() +endif() + +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(LibP11_ROOT "$ENV{LibP11_ROOT_32}") +else() + set(LibP11_ROOT "$ENV{LibP11_ROOT_64}") +endif() + +find_path(LIBP11_INCLUDE_DIR NAMES libp11.h HINTS ${LibP11_ROOT}) +find_library(LIBP11_LIBRARY NAMES libp11.a libp11.lib HINTS ${LibP11_ROOT}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibP11 DEFAULT_MSG LIBP11_LIBRARY LIBP11_INCLUDE_DIR) + +if(LibP11_FOUND) + # add the target + add_library(eProsima_p11 STATIC IMPORTED) + + # update the properties + set_target_properties(eProsima_p11 PROPERTIES + IMPORTED_LOCATION "${LIBP11_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBP11_INCLUDE_DIR}" + ) +endif() + +# clean local variables +unset(LIBP11_INCLUDE_DIR) +unset(LIBP11_LIBRARY) +unset(LibP11_ROOT) diff --git a/include/fastrtps/config.h.in b/include/fastrtps/config.h.in index 5c437832970..22ef7331cfc 100644 --- a/include/fastrtps/config.h.in +++ b/include/fastrtps/config.h.in @@ -25,69 +25,73 @@ // C++20 support defines #ifndef HAVE_CXX20 #define HAVE_CXX20 @HAVE_CXX20@ -#endif +#endif /* ifndef HAVE_CXX20 */ // C++17 support defines #ifndef HAVE_CXX17 #define HAVE_CXX17 @HAVE_CXX17@ -#endif +#endif /* ifndef HAVE_CXX17 */ // C++14 support defines #ifndef HAVE_CXX14 #define HAVE_CXX14 @HAVE_CXX14@ -#endif +#endif /* ifndef HAVE_CXX14 */ // C++1Y support defines #ifndef HAVE_CXX1Y #define HAVE_CXX1Y @HAVE_CXX1Y@ -#endif +#endif /* ifndef HAVE_CXX1Y */ // C++11 support defines #ifndef HAVE_CXX11 #define HAVE_CXX11 @HAVE_CXX11@ -#endif +#endif /* ifndef HAVE_CXX11 */ // C++0x support defines #ifndef HAVE_CXX0X #define HAVE_CXX0X @HAVE_CXX0X@ -#endif +#endif /* ifndef HAVE_CXX0X */ // C++ constexpr support #ifndef HAVE_CXX_CONSTEXPR #define HAVE_CXX_CONSTEXPR @HAVE_CXX_CONSTEXPR@ -#endif +#endif /* ifndef HAVE_CXX_CONSTEXPR */ #if HAVE_CXX_CONSTEXPR #define CONSTEXPR constexpr #else #define CONSTEXPR const -#endif +#endif /* if HAVE_CXX_CONSTEXPR */ // Endianness defines #ifndef FASTDDS_IS_BIG_ENDIAN_TARGET #define FASTDDS_IS_BIG_ENDIAN_TARGET @FASTDDS_IS_BIG_ENDIAN_TARGET@ -#endif +#endif /* ifndef FASTDDS_IS_BIG_ENDIAN_TARGET */ // Security #ifndef HAVE_SECURITY #define HAVE_SECURITY @HAVE_SECURITY@ -#endif +#endif /* ifndef HAVE_SECURITY */ + +#ifndef HAVE_LIBP11 +#define HAVE_LIBP11 @HAVE_LIBP11@ +#endif /* ifndef HAVE_LIBP11 */ //Sqlite3 support #ifndef HAVE_SQLITE3 #define HAVE_SQLITE3 @HAVE_SQLITE3@ -#endif +#endif /* ifndef HAVE_SQLITE3 */ // TLS support #ifndef TLS_FOUND #define TLS_FOUND @TLS_FOUND@ -#endif +#endif /* ifndef TLS_FOUND */ // Strict real-time #ifndef HAVE_STRICT_REALTIME #define HAVE_STRICT_REALTIME @HAVE_STRICT_REALTIME@ -#endif +#endif /* ifndef HAVE_STRICT_REALTIME */ /* Log Macros */ @@ -95,17 +99,17 @@ #cmakedefine FASTDDS_ENFORCE_LOG_INFO #ifndef HAVE_LOG_NO_INFO #define HAVE_LOG_NO_INFO @HAVE_LOG_NO_INFO@ -#endif +#endif /* ifndef HAVE_LOG_NO_INFO */ // Log Warning #ifndef HAVE_LOG_NO_WARNING #define HAVE_LOG_NO_WARNING @HAVE_LOG_NO_WARNING@ -#endif +#endif /* ifndef HAVE_LOG_NO_WARNING */ // Log Error #ifndef HAVE_LOG_NO_ERROR #define HAVE_LOG_NO_ERROR @HAVE_LOG_NO_ERROR@ -#endif +#endif /* ifndef HAVE_LOG_NO_ERROR */ // Statistics #cmakedefine FASTDDS_STATISTICS @@ -119,7 +123,7 @@ #define FASTRTPS_DEPRECATED(msg) __declspec(deprecated(msg)) #else #define FASTRTPS_DEPRECATED(msg) -#endif +#endif /* if __cplusplus >= 201402L */ // Deprecation with version #define FASTDDS_DEPRECATED_UNTIL(major, entity_name, msg) \ @@ -128,7 +132,7 @@ #define FASTDDS_TODO_BEFORE(major, minor, msg) \ static_assert((FASTRTPS_VERSION_MAJOR < major) || \ - (FASTRTPS_VERSION_MAJOR == major && FASTRTPS_VERSION_MINOR < minor), \ - "TODO before version " #major "." #minor " : " #msg); + (FASTRTPS_VERSION_MAJOR == major && FASTRTPS_VERSION_MINOR < minor), \ + "TODO before version " #major "." #minor " : " #msg); #endif // _FASTRTPS_CONFIG_H_ diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 53b987cfeb8..f7160c0039f 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -296,6 +296,8 @@ set(${PROJECT_NAME}_security_source_files security/accesscontrol/GovernanceParser.cpp security/accesscontrol/PermissionsParser.cpp security/logging/LogTopic.cpp + security/artifact_providers/FileProvider.cpp + security/artifact_providers/Pkcs11Provider.cpp ) if(SECURITY) @@ -303,8 +305,14 @@ if(SECURITY) ${${PROJECT_NAME}_security_source_files} ) set(HAVE_SECURITY 1) + if(LIBP11_FOUND) + set(HAVE_LIBP11 1) + else() + set(HAVE_LIBP11 0) + endif() else() set(HAVE_SECURITY 0) + set(HAVE_LIBP11 0) endif() if(WIN32 AND (MSVC OR MSVC_IDE)) @@ -437,6 +445,7 @@ target_link_libraries(${PROJECT_NAME} ${PRIVACY} fastcdr foonathan_memory $<$<BOOL:${WIN32}>:iphlpapi$<SEMICOLON>Shlwapi> ${THIRDPARTY_BOOST_LINK_LIBS} PRIVATE eProsima_atomic + $<$<BOOL:${LibP11_FOUND}>:eProsima_p11> # $<TARGET_NAME_IF_EXISTS:eProsima_p11> ) if(MSVC OR MSVC_IDE) diff --git a/src/cpp/security/accesscontrol/Permissions.cpp b/src/cpp/security/accesscontrol/Permissions.cpp index 55915643117..91bcccada6c 100644 --- a/src/cpp/security/accesscontrol/Permissions.cpp +++ b/src/cpp/security/accesscontrol/Permissions.cpp @@ -43,6 +43,8 @@ #include <openssl/err.h> #include <openssl/obj_mac.h> +#include <security/artifact_providers/FileProvider.hpp> + #include <cassert> #include <fstream> @@ -351,105 +353,13 @@ static X509_STORE* load_permissions_ca( std::string& ca_algo, SecurityException& exception) { - X509_STORE* store = X509_STORE_new(); - - if (store != nullptr) - { - if (permissions_ca.size() >= 7 && permissions_ca.compare(0, 7, "file://") == 0) - { - BIO* in = BIO_new(BIO_s_file()); - - if (in != nullptr) - { - if (BIO_read_filename(in, permissions_ca.substr(7).c_str()) > 0) - { - STACK_OF(X509_INFO) * inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); - - if (inf != nullptr) - { - int i, count = 0; - there_are_crls = false; - - for (i = 0; i < sk_X509_INFO_num(inf); i++) - { - X509_INFO* itmp = sk_X509_INFO_value(inf, i); - - if (itmp->x509) - { - // Retrieve subject name for future use. - if (ca_sn.empty()) - { - X509_NAME* ca_subject_name = X509_get_subject_name(itmp->x509); - assert(ca_subject_name != nullptr); - char* ca_subject_name_str = X509_NAME_oneline(ca_subject_name, 0, 0); - assert(ca_subject_name_str != nullptr); - ca_sn = ca_subject_name_str; - OPENSSL_free(ca_subject_name_str); - } - - // Retrieve signature algorithm - if (ca_algo.empty()) - { - if (get_signature_algorithm(itmp->x509, ca_algo, exception)) - { - X509_STORE_add_cert(store, itmp->x509); - count++; - } - } - else - { - X509_STORE_add_cert(store, itmp->x509); - count++; - } - } - if (itmp->crl) - { - X509_STORE_add_crl(store, itmp->crl); - there_are_crls = true; - } - } - - sk_X509_INFO_pop_free(inf, X509_INFO_free); - - if (count > 0) - { - BIO_free(in); - - return store; - } - } - else - { - exception = _SecurityException_(std::string( - "OpenSSL library cannot read X509 info in file ") + - permissions_ca.substr(7)); - } - } - else - { - exception = _SecurityException_(std::string( - "OpenSSL library cannot read file ") + permissions_ca.substr(7)); - } - - BIO_free(in); - } - else - { - exception = _SecurityException_("OpenSSL library cannot allocate file"); - } - } - else - { - exception = _SecurityException_("Unsupported permissions_ca format"); - } - - X509_STORE_free(store); - } - else + if (permissions_ca.size() >= 7 && permissions_ca.compare(0, 7, "file://") == 0) { - exception = _SecurityException_("Creation of X509 storage"); + return detail::FileProvider::load_ca(permissions_ca, there_are_crls, ca_sn, ca_algo, get_signature_algorithm, + exception); } + exception = _SecurityException_(std::string("Unsupported URI format ") + permissions_ca); return nullptr; } diff --git a/src/cpp/security/artifact_providers/FileProvider.cpp b/src/cpp/security/artifact_providers/FileProvider.cpp new file mode 100644 index 00000000000..e9dcd3a065e --- /dev/null +++ b/src/cpp/security/artifact_providers/FileProvider.cpp @@ -0,0 +1,261 @@ +// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file FileProvider.cpp + */ + +#include <security/artifact_providers/FileProvider.hpp> + +#include <cassert> +#include <cstring> +#include <iostream> + +#define S1(x) #x +#define S2(x) S1(x) +#define LOCATION " (" __FILE__ ":" S2(__LINE__) ")" +#define _SecurityException_(str) SecurityException(std::string(str) + LOCATION) + + +namespace eprosima { +namespace fastrtps { +namespace rtps { +namespace security { +namespace detail { + +X509_STORE* FileProvider::load_ca( + const std::string& ca, + bool& there_are_crls, + std::string& ca_sn, + std::string& ca_algo, + std::function<bool(X509*, std::string&, SecurityException&)> get_signature_algorithm, + SecurityException& exception) +{ + X509_STORE* store = X509_STORE_new(); + + if (store != nullptr) + { + BIO* in = BIO_new(BIO_s_file()); + + if (in != nullptr) + { + if (BIO_read_filename(in, ca.substr(7).c_str()) > 0) + { + STACK_OF(X509_INFO) * inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + + if (inf != nullptr) + { + int i, count = 0; + there_are_crls = false; + + for (i = 0; i < sk_X509_INFO_num(inf); i++) + { + X509_INFO* itmp = sk_X509_INFO_value(inf, i); + + if (itmp->x509) + { + // Retrieve subject name for future use. + if (ca_sn.empty()) + { + X509_NAME* ca_subject_name = X509_get_subject_name(itmp->x509); + assert(ca_subject_name != nullptr); + char* ca_subject_name_str = X509_NAME_oneline(ca_subject_name, 0, 0); + assert(ca_subject_name_str != nullptr); + ca_sn = ca_subject_name_str; + OPENSSL_free(ca_subject_name_str); + } + + // Retrieve signature algorithm + if (ca_algo.empty()) + { + if (get_signature_algorithm(itmp->x509, ca_algo, exception)) + { + X509_STORE_add_cert(store, itmp->x509); + count++; + } + } + else + { + X509_STORE_add_cert(store, itmp->x509); + count++; + } + } + if (itmp->crl) + { + X509_STORE_add_crl(store, itmp->crl); + there_are_crls = true; + } + } + + sk_X509_INFO_pop_free(inf, X509_INFO_free); + + if (count > 0) + { + BIO_free(in); + + return store; + } + } + else + { + exception = _SecurityException_(std::string( + "OpenSSL library cannot read X509 info in file ") + ca.substr(7)); + } + } + else + { + exception = _SecurityException_(std::string( + "OpenSSL library cannot read file ") + ca.substr(7)); + } + + BIO_free(in); + } + else + { + exception = _SecurityException_("OpenSSL library cannot allocate file"); + } + + X509_STORE_free(store); + } + else + { + exception = _SecurityException_("Creation of X509 storage"); + } + + return nullptr; +} + +X509* FileProvider::load_certificate( + const std::string& identity_cert, + SecurityException& exception) +{ + X509* returnedValue = nullptr; + BIO* in = BIO_new(BIO_s_file()); + + if (in != nullptr) + { + if (BIO_read_filename(in, identity_cert.substr(7).c_str()) > 0) + { + returnedValue = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + } + else + { + exception = + _SecurityException_(std::string("OpenSSL library cannot read file ") + identity_cert.substr(7)); + } + + BIO_free(in); + } + else + { + exception = _SecurityException_("OpenSSL library cannot allocate file"); + } + + return returnedValue; +} + +static int private_key_password_callback( + char* buf, + int bufsize, + int /*verify*/, + const char* password) +{ + assert(password != nullptr); + + int returnedValue = static_cast<int>(strlen(password)); + + if (returnedValue > bufsize) + { + returnedValue = bufsize; + } + + memcpy(buf, password, returnedValue); + return returnedValue; +} + +EVP_PKEY* FileProvider::load_private_key( + X509* certificate, + const std::string& pkey, + const std::string& password, + SecurityException& exception) +{ + EVP_PKEY* returnedValue = nullptr; + BIO* in = BIO_new(BIO_s_file()); + + if (in != nullptr) + { + if (BIO_read_filename(in, pkey.substr(7).c_str()) > 0) + { + returnedValue = + PEM_read_bio_PrivateKey(in, NULL, (pem_password_cb*)private_key_password_callback, + (void*)password.c_str()); + + // Verify private key. + if (!X509_check_private_key(certificate, returnedValue)) + { + exception = _SecurityException_(std::string("Error verifying private key ") + pkey.substr(7)); + EVP_PKEY_free(returnedValue); + returnedValue = nullptr; + } + } + else + { + exception = _SecurityException_(std::string("OpenSSL library cannot read file ") + pkey.substr(7)); + } + + BIO_free(in); + } + else + { + exception = _SecurityException_("OpenSSL library cannot allocate file"); + } + + return returnedValue; +} + +X509_CRL* FileProvider::load_crl( + const std::string& identity_crl, + SecurityException& exception) +{ + X509_CRL* returnedValue = nullptr; + + BIO* in = BIO_new(BIO_s_file()); + + if (in != nullptr) + { + if (BIO_read_filename(in, identity_crl.substr(7).c_str()) > 0) + { + returnedValue = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + } + else + { + exception = _SecurityException_(std::string("OpenSSL library cannot read file ") + identity_crl.substr(7)); + } + + BIO_free(in); + } + else + { + exception = _SecurityException_("OpenSSL library cannot allocate file"); + } + + return returnedValue; +} + +} // namespace detail +} //namespace security +} //namespace rtps +} //namespace fastrtps +} //namespace eprosima + diff --git a/src/cpp/security/artifact_providers/FileProvider.hpp b/src/cpp/security/artifact_providers/FileProvider.hpp new file mode 100644 index 00000000000..ca3459fd66d --- /dev/null +++ b/src/cpp/security/artifact_providers/FileProvider.hpp @@ -0,0 +1,72 @@ +// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file FileProvider.hpp + */ + +#ifndef _SECURITY_ARTIFACTPROVIDERS_FILEPROVIDER_HPP_ +#define _SECURITY_ARTIFACTPROVIDERS_FILEPROVIDER_HPP_ + +#include <functional> + +#include <openssl/engine.h> +#include <openssl/err.h> +#include <openssl/ssl.h> + +#include <fastdds/rtps/security/exceptions/SecurityException.h> + + +namespace eprosima { +namespace fastrtps { +namespace rtps { +namespace security { +namespace detail { + +class FileProvider +{ + +public: + + static X509_STORE* load_ca( + const std::string& ca, + bool& there_are_crls, + std::string& ca_sn, + std::string& ca_algo, + std::function<bool(X509*, std::string&, SecurityException&)> get_signature_algorithm, + SecurityException& exception); + + static EVP_PKEY* load_private_key( + X509* certificate, + const std::string& file, + const std::string& password, + SecurityException& exception); + + static X509* load_certificate( + const std::string& identity_cert, + SecurityException& exception); + + static X509_CRL* load_crl( + const std::string& identity_crl, + SecurityException& exception); + +}; + +} // namespace detail +} //namespace security +} //namespace rtps +} //namespace fastrtps +} //namespace eprosima + +#endif // _SECURITY_ARTIFACTPROVIDERS_FILEPROVIDER_HPP_ diff --git a/src/cpp/security/artifact_providers/Pkcs11Provider.cpp b/src/cpp/security/artifact_providers/Pkcs11Provider.cpp new file mode 100644 index 00000000000..c0a7daf6de7 --- /dev/null +++ b/src/cpp/security/artifact_providers/Pkcs11Provider.cpp @@ -0,0 +1,164 @@ +// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file Pkcs11Provider.cpp + */ + +#include <security/artifact_providers/Pkcs11Provider.hpp> + +#include <iostream> + +#include <fastdds/dds/log/Log.hpp> +#include <utils/SystemInfo.hpp> + +#define S1(x) #x +#define S2(x) S1(x) +#define LOCATION " (" __FILE__ ":" S2(__LINE__) ")" +#define _SecurityException_(str) SecurityException(std::string(str) + LOCATION) + + +namespace eprosima { +namespace fastrtps { +namespace rtps { +namespace security { +namespace detail { + +constexpr const char* FASTDDS_PKCS11_PIN = "FASTDDS_PKCS11_PIN"; +constexpr const char* PKCS11_ENGINE_ID = "pkcs11"; + +static int ui_open( + UI* ui) +{ + return UI_method_get_opener(UI_OpenSSL())(ui); +} + +static int ui_read( + UI* ui, + UI_STRING* uis) +{ + switch (UI_get_string_type(uis)) + { + case UIT_PROMPT: + case UIT_VERIFY: + { + logWarning(PKCS11_PROVIDER, "PKCS#11 engine is asking: " << UI_get0_output_string(uis)); + // Return an empty password without asking the user + UI_set_result(ui, uis, ""); + return 1; + } + default: + break; + } + + // Call the default method of the engine provider + return UI_method_get_reader(UI_OpenSSL())(ui, uis); +} + +static int ui_close( + UI* ui) +{ + return UI_method_get_closer(UI_OpenSSL())(ui); +} + +Pkcs11Provider::Pkcs11Provider() +{ + SSL_load_error_strings(); /* readable error messages */ + SSL_library_init(); /* initialize library */ + + // Create an UI method to use with the engine + // This will be used to retrieve the PIN if none was given in the ENV nor in the URI + ui_method_ = UI_create_method("OpenSSL application user interface"); + UI_method_set_opener(ui_method_, ui_open); + UI_method_set_reader(ui_method_, ui_read); + UI_method_set_closer(ui_method_, ui_close); + + // Load the engine + ENGINE_load_builtin_engines(); + pkcs11_ = ENGINE_by_id(PKCS11_ENGINE_ID); + if (!pkcs11_) + { + has_initialization_error_ = true; + initialization_exception_ = _SecurityException_(std::string("Error retrieving 'pkcs11' engine")); + } + + // Load the PIN from the environment + std::string pin; + if (ReturnCode_t::RETCODE_OK == SystemInfo::get_env(FASTDDS_PKCS11_PIN, pin)) + { + if (!ENGINE_ctrl_cmd_string( pkcs11_, "PIN", pin.c_str(), 0)) + { + has_initialization_error_ = true; + initialization_exception_ = + _SecurityException_(std::string("Error setting the PIN in the 'pkcs11' engine")); + ENGINE_free(pkcs11_); + } + } + + // Init the engine with the PIN (if any) + if (!ENGINE_init(pkcs11_)) + { + has_initialization_error_ = true; + initialization_exception_ = _SecurityException_(std::string("Error initializing the HSM provider library")); + ENGINE_free(pkcs11_); + } +} + +Pkcs11Provider::~Pkcs11Provider() +{ + ENGINE_finish(pkcs11_); + ENGINE_free(pkcs11_); + + if (ui_method_) + { + UI_destroy_method(ui_method_); + } +} + +EVP_PKEY* Pkcs11Provider::load_private_key( + X509* certificate, + const std::string& pkey, + const std::string& /*password*/, + SecurityException& exception) +{ + if (has_initialization_error_) + { + exception = initialization_exception_; + return nullptr; + } + + EVP_PKEY* returnedValue = ENGINE_load_private_key(pkcs11_, pkey.c_str(), ui_method_, nullptr); + if (!returnedValue) + { + exception = _SecurityException_(std::string("Error opening the private key ") + pkey.substr(7)); + return returnedValue; + } + + // Verify private key. + if (!X509_check_private_key(certificate, returnedValue)) + { + exception = _SecurityException_(std::string("Error verifying private key ") + pkey.substr(7) + + "\n ERROR: " + ERR_error_string(ERR_get_error(), nullptr)); + EVP_PKEY_free(returnedValue); + returnedValue = nullptr; + } + + return returnedValue; +} + +} // namespace detail +} // namespace security +} // namespace rtps +} // namespace fastrtps +} // namespace eprosima diff --git a/src/cpp/security/artifact_providers/Pkcs11Provider.hpp b/src/cpp/security/artifact_providers/Pkcs11Provider.hpp new file mode 100644 index 00000000000..87f558c1ef6 --- /dev/null +++ b/src/cpp/security/artifact_providers/Pkcs11Provider.hpp @@ -0,0 +1,74 @@ +// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file Pkcs11Provider.hpp + */ + +#ifndef _SECURITY_ARTIFACTPROVIDERS_PKCS11PROVIDER_HPP_ +#define _SECURITY_ARTIFACTPROVIDERS_PKCS11PROVIDER_HPP_ + +#include <openssl/engine.h> +#include <openssl/err.h> +#include <openssl/ssl.h> + +#if HAVE_LIBP11 +#include <libp11.h> +#endif // HAVE_LIBP11 + +#include <fastdds/rtps/security/exceptions/SecurityException.h> + + +namespace eprosima { +namespace fastrtps { +namespace rtps { +namespace security { +namespace detail { + +class Pkcs11Provider +{ + +public: + + EVP_PKEY* load_private_key( + X509* certificate, + const std::string& file, + const std::string& password, + SecurityException& exception); + + Pkcs11Provider(); + + ~Pkcs11Provider(); + +private: + + EVP_PKEY* load_private_key_impl( + X509* certificate, + const std::string& file, + const std::string& password, + SecurityException& exception); + + SecurityException initialization_exception_; + bool has_initialization_error_ = false; + ENGINE* pkcs11_ = nullptr; + UI_METHOD* ui_method_ = nullptr; +}; + +} // namespace detail +} //namespace security +} //namespace rtps +} //namespace fastrtps +} //namespace eprosima + +#endif // _SECURITY_ARTIFACTPROVIDERS_PKCS11PROVIDER_HPP_ diff --git a/src/cpp/security/authentication/PKIDH.cpp b/src/cpp/security/authentication/PKIDH.cpp index 2dfcbf32d05..d51859b5f53 100644 --- a/src/cpp/security/authentication/PKIDH.cpp +++ b/src/cpp/security/authentication/PKIDH.cpp @@ -45,6 +45,9 @@ #include <openssl/err.h> #include <openssl/obj_mac.h> +#include <security/artifact_providers/FileProvider.hpp> +#include <security/artifact_providers/Pkcs11Provider.hpp> + #include <cassert> #include <algorithm> @@ -158,100 +161,13 @@ static X509_STORE* load_identity_ca( std::string& ca_algo, SecurityException& exception) { - X509_STORE* store = X509_STORE_new(); - - if (store != nullptr) - { - if (identity_ca.size() >= 7 && identity_ca.compare(0, 7, "file://") == 0) - { - BIO* in = BIO_new(BIO_s_file()); - - if (in != nullptr) - { - if (BIO_read_filename(in, identity_ca.substr(7).c_str()) > 0) - { - STACK_OF(X509_INFO) * inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); - - if (inf != nullptr) - { - int i, count = 0; - there_are_crls = false; - - for (i = 0; i < sk_X509_INFO_num(inf); i++) - { - X509_INFO* itmp = sk_X509_INFO_value(inf, i); - - if (itmp->x509) - { - // Retrieve subject name for future use. - if (ca_sn.empty()) - { - X509_NAME* ca_subject_name = X509_get_subject_name(itmp->x509); - assert(ca_subject_name != nullptr); - char* ca_subject_name_str = X509_NAME_oneline(ca_subject_name, 0, 0); - assert(ca_subject_name_str != nullptr); - ca_sn = ca_subject_name_str; - OPENSSL_free(ca_subject_name_str); - } - - // Retrieve signature algorithm - if (ca_algo.empty()) - { - if (get_signature_algorithm(itmp->x509, ca_algo, exception)) - { - X509_STORE_add_cert(store, itmp->x509); - count++; - } - } - else - { - X509_STORE_add_cert(store, itmp->x509); - count++; - } - } - if (itmp->crl) - { - X509_STORE_add_crl(store, itmp->crl); - there_are_crls = true; - } - } - - sk_X509_INFO_pop_free(inf, X509_INFO_free); - - if (count > 0) - { - BIO_free(in); - - return store; - } - } - else - { - exception = _SecurityException_(std::string( - "OpenSSL library cannot read X509 info in file ") + identity_ca.substr(7)); - } - } - else - { - exception = _SecurityException_(std::string( - "OpenSSL library cannot read file ") + identity_ca.substr(7)); - } - - BIO_free(in); - } - else - { - exception = _SecurityException_("OpenSSL library cannot allocate file"); - } - } - - X509_STORE_free(store); - } - else + if (identity_ca.size() >= 7 && identity_ca.compare(0, 7, "file://") == 0) { - exception = _SecurityException_("Creation of X509 storage"); + return detail::FileProvider::load_ca(identity_ca, there_are_crls, ca_sn, ca_algo, get_signature_algorithm, + exception); } + exception = _SecurityException_(std::string("Unsupported URI format ") + identity_ca); return nullptr; } @@ -259,33 +175,13 @@ static X509* load_certificate( const std::string& identity_cert, SecurityException& exception) { - X509* returnedValue = nullptr; - if (identity_cert.size() >= 7 && identity_cert.compare(0, 7, "file://") == 0) { - BIO* in = BIO_new(BIO_s_file()); - - if (in != nullptr) - { - if (BIO_read_filename(in, identity_cert.substr(7).c_str()) > 0) - { - returnedValue = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); - } - else - { - exception = - _SecurityException_(std::string("OpenSSL library cannot read file ") + identity_cert.substr(7)); - } - - BIO_free(in); - } - else - { - exception = _SecurityException_("OpenSSL library cannot allocate file"); - } + return detail::FileProvider::load_certificate(identity_cert, exception); } - return returnedValue; + exception = _SecurityException_(std::string("Unsupported URI format ") + identity_cert); + return nullptr; } static X509* load_certificate( @@ -355,66 +251,34 @@ static bool verify_certificate( return returnedValue; } -static int private_key_password_callback( - char* buf, - int bufsize, - int /*verify*/, - const char* password) -{ - assert(password != nullptr); - - int returnedValue = static_cast<int>(strlen(password)); - - if (returnedValue > bufsize) - { - returnedValue = bufsize; - } - - memcpy(buf, password, returnedValue); - return returnedValue; -} - static EVP_PKEY* load_private_key( X509* certificate, const std::string& file, const std::string& password, - SecurityException& exception) + SecurityException& exception, + PKIDH& pkidh) { - EVP_PKEY* returnedValue = nullptr; if (file.size() >= 7 && file.compare(0, 7, "file://") == 0) { - BIO* in = BIO_new(BIO_s_file()); - - if (in != nullptr) - { - if (BIO_read_filename(in, file.substr(7).c_str()) > 0) - { - returnedValue = - PEM_read_bio_PrivateKey(in, NULL, (pem_password_cb*)private_key_password_callback, - (void*)password.c_str()); - - // Verify private key. - if (!X509_check_private_key(certificate, returnedValue)) - { - exception = _SecurityException_(std::string("Error verifying private key ") + file.substr(7)); - EVP_PKEY_free(returnedValue); - returnedValue = nullptr; - } - } - else - { - exception = _SecurityException_(std::string("OpenSSL library cannot read file ") + file.substr(7)); - } - - BIO_free(in); - } - else + return detail::FileProvider::load_private_key(certificate, file, password, exception); + } + else if (file.size() >= 7 && file.compare(0, 7, "pkcs11:") == 0) + { +#if HAVE_LIBP11 + if (!pkidh.pkcs11_provider) { - exception = _SecurityException_("OpenSSL library cannot allocate file"); + pkidh.pkcs11_provider.reset(new detail::Pkcs11Provider()); } + return pkidh.pkcs11_provider->load_private_key(certificate, file, password, exception); +#else // HAVE_LIBP11 + static_cast<void>(pkidh); + exception = _SecurityException_(std::string("PKCS11 URIs require libp11 ") + file); + return nullptr; +#endif // HAVE_LIBP11 } - return returnedValue; + exception = _SecurityException_(std::string("Unsupported URI format ") + file); + return nullptr; } static bool store_certificate_in_buffer( @@ -613,33 +477,13 @@ static X509_CRL* load_crl( const std::string& identity_crl, SecurityException& exception) { - X509_CRL* returnedValue = nullptr; - if (identity_crl.size() >= 7 && identity_crl.compare(0, 7, "file://") == 0) { - BIO* in = BIO_new(BIO_s_file()); - - if (in != nullptr) - { - if (BIO_read_filename(in, identity_crl.substr(7).c_str()) > 0) - { - returnedValue = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } - else - { - exception = _SecurityException_(std::string("OpenSSL library cannot read file ") + identity_crl.substr( - 7)); - } - - BIO_free(in); - } - else - { - exception = _SecurityException_("OpenSSL library cannot allocate file"); - } + return detail::FileProvider::load_crl(identity_crl, exception); } - return returnedValue; + exception = _SecurityException_(std::string("Unsupported URI format ") + identity_crl); + return nullptr; } static bool adjust_participant_key( @@ -1241,7 +1085,7 @@ ValidationResult_t PKIDH::validate_local_identity( { if (get_signature_algorithm((*ih)->cert_, (*ih)->sign_alg_, exception)) { - (*ih)->pkey_ = load_private_key((*ih)->cert_, *private_key, *password, exception); + (*ih)->pkey_ = load_private_key((*ih)->cert_, *private_key, *password, exception, *this); if ((*ih)->pkey_ != nullptr) { diff --git a/src/cpp/security/authentication/PKIDH.h b/src/cpp/security/authentication/PKIDH.h index 33214388b1d..e1ef422fd4d 100644 --- a/src/cpp/security/authentication/PKIDH.h +++ b/src/cpp/security/authentication/PKIDH.h @@ -22,6 +22,7 @@ #include <fastdds/rtps/security/authentication/Authentication.h> #include <fastdds/rtps/attributes/PropertyPolicy.h> #include <security/authentication/PKIHandshakeHandle.h> +#include <security/artifact_providers/Pkcs11Provider.hpp> namespace eprosima { namespace fastrtps { @@ -30,84 +31,106 @@ namespace security { class PKIDH : public Authentication { - public: - - ValidationResult_t validate_local_identity(IdentityHandle** local_identity_handle, - GUID_t& adjusted_participant_key, - const uint32_t domain_id, - const RTPSParticipantAttributes& participant_attr, - const GUID_t& candidate_participant_key, - SecurityException& exception) override; - - ValidationResult_t validate_remote_identity(IdentityHandle** remote_identity_handle, - const IdentityHandle& local_identity_handle, - const IdentityToken& remote_identity_token, - const GUID_t& remote_participant_key, - SecurityException& exception) override; - - ValidationResult_t begin_handshake_request(HandshakeHandle** handshake_handle, - HandshakeMessageToken** handshake_message, - const IdentityHandle& initiator_identity_handle, - IdentityHandle& replier_identity_handle, - const CDRMessage_t& cdr_participant_data, - SecurityException& exception) override; - - ValidationResult_t begin_handshake_reply(HandshakeHandle** handshake_handle, - HandshakeMessageToken** handshake_message_out, - HandshakeMessageToken&& handshake_message_in, - IdentityHandle& initiator_identity_handle, - const IdentityHandle& replier_identity_handle, - const CDRMessage_t& cdr_participant_data, - SecurityException& exception) override; - - ValidationResult_t process_handshake(HandshakeMessageToken** handshake_message_out, - HandshakeMessageToken&& handshake_message_in, - HandshakeHandle& handshake_handle, - SecurityException& exception) override; - - SharedSecretHandle* get_shared_secret(const HandshakeHandle& handshake_handle, - SecurityException& exception) override; - - bool set_listener(AuthenticationListener* listener, - SecurityException& exception) override; - - bool get_identity_token(IdentityToken** identity_token, - const IdentityHandle& handle, - SecurityException& exception) override; - - bool return_identity_token(IdentityToken* token, - SecurityException& exception) override; - - bool return_handshake_handle(HandshakeHandle* handshake_handle, - SecurityException& exception) override; - - bool return_identity_handle(IdentityHandle* identity_handle, - SecurityException& exception) override; - - bool return_sharedsecret_handle(SharedSecretHandle* sharedsecret_handle, - SecurityException& exception) override; - - bool set_permissions_credential_and_token(IdentityHandle& identity_handle, - PermissionsCredentialToken& permissions_credential_token, - SecurityException& ex) override; - - bool get_authenticated_peer_credential_token(PermissionsCredentialToken **token, - const IdentityHandle& identity_handle, SecurityException& exception) override; - - bool return_authenticated_peer_credential_token(PermissionsCredentialToken* token, - SecurityException& ex) override; - - private: - - ValidationResult_t process_handshake_request(HandshakeMessageToken** handshake_message_out, - HandshakeMessageToken&& handshake_message_in, - PKIHandshakeHandle& handshake_handle, - SecurityException& exception); - - ValidationResult_t process_handshake_reply(HandshakeMessageToken** handshake_message_out, - HandshakeMessageToken&& handshake_message_in, - PKIHandshakeHandle& handshake_handle, - SecurityException& exception); +public: + + ValidationResult_t validate_local_identity( + IdentityHandle** local_identity_handle, + GUID_t& adjusted_participant_key, + const uint32_t domain_id, + const RTPSParticipantAttributes& participant_attr, + const GUID_t& candidate_participant_key, + SecurityException& exception) override; + + ValidationResult_t validate_remote_identity( + IdentityHandle** remote_identity_handle, + const IdentityHandle& local_identity_handle, + const IdentityToken& remote_identity_token, + const GUID_t& remote_participant_key, + SecurityException& exception) override; + + ValidationResult_t begin_handshake_request( + HandshakeHandle** handshake_handle, + HandshakeMessageToken** handshake_message, + const IdentityHandle& initiator_identity_handle, + IdentityHandle& replier_identity_handle, + const CDRMessage_t& cdr_participant_data, + SecurityException& exception) override; + + ValidationResult_t begin_handshake_reply( + HandshakeHandle** handshake_handle, + HandshakeMessageToken** handshake_message_out, + HandshakeMessageToken&& handshake_message_in, + IdentityHandle& initiator_identity_handle, + const IdentityHandle& replier_identity_handle, + const CDRMessage_t& cdr_participant_data, + SecurityException& exception) override; + + ValidationResult_t process_handshake( + HandshakeMessageToken** handshake_message_out, + HandshakeMessageToken&& handshake_message_in, + HandshakeHandle& handshake_handle, + SecurityException& exception) override; + + SharedSecretHandle* get_shared_secret( + const HandshakeHandle& handshake_handle, + SecurityException& exception) override; + + bool set_listener( + AuthenticationListener* listener, + SecurityException& exception) override; + + bool get_identity_token( + IdentityToken** identity_token, + const IdentityHandle& handle, + SecurityException& exception) override; + + bool return_identity_token( + IdentityToken* token, + SecurityException& exception) override; + + bool return_handshake_handle( + HandshakeHandle* handshake_handle, + SecurityException& exception) override; + + bool return_identity_handle( + IdentityHandle* identity_handle, + SecurityException& exception) override; + + bool return_sharedsecret_handle( + SharedSecretHandle* sharedsecret_handle, + SecurityException& exception) override; + + bool set_permissions_credential_and_token( + IdentityHandle& identity_handle, + PermissionsCredentialToken& permissions_credential_token, + SecurityException& ex) override; + + bool get_authenticated_peer_credential_token( + PermissionsCredentialToken** token, + const IdentityHandle& identity_handle, + SecurityException& exception) override; + + bool return_authenticated_peer_credential_token( + PermissionsCredentialToken* token, + SecurityException& ex) override; + +#if HAVE_LIBP11 + std::unique_ptr<detail::Pkcs11Provider> pkcs11_provider; +#endif // HAVE_LIBP11 + +private: + + ValidationResult_t process_handshake_request( + HandshakeMessageToken** handshake_message_out, + HandshakeMessageToken&& handshake_message_in, + PKIHandshakeHandle& handshake_handle, + SecurityException& exception); + + ValidationResult_t process_handshake_reply( + HandshakeMessageToken** handshake_message_out, + HandshakeMessageToken&& handshake_message_in, + PKIHandshakeHandle& handshake_handle, + SecurityException& exception); }; diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index bc771212308..f679fac0842 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -21,7 +21,7 @@ macro(add_blackbox_gtest) set(test "${ARGV0}") set(command "${test}") endif() - set(multiValueArgs SOURCES ENVIRONMENTS DEPENDENCIES LABELS) + set(multiValueArgs SOURCES ENVIRONMENTS DEPENDENCIES LABELS IGNORE) cmake_parse_arguments(GTEST "" "${uniValueArgs}" "${multiValueArgs}" ${ARGN}) if(GTEST_NAME) @@ -29,6 +29,12 @@ macro(add_blackbox_gtest) set(command ${GTEST_COMMAND}) endif() + # IGNORE keeps a filter expression for the test list: + # + if GTEST_INDIVIDUAL is enforced the expressions are regular expression and the matching tests would be disabled + # using cmake add_test DISABLE property + # + if no GTEST_INDIVIDUAL is enforce the filtering will be added to gtest command via --gtest_filter and it's + # own filtering syntax + if(GTEST_INDIVIDUAL) if(WIN32) set(WIN_PATH "$ENV{PATH}") @@ -55,6 +61,15 @@ macro(add_blackbox_gtest) add_test(NAME ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME} COMMAND ${command} --gtest_filter=${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}) + # decide if disable + unset(GTEST_USER_DISABLED) + foreach(GTEST_USER_FILTER ${GTEST_IGNORE}) + string(REGEX MATCH ${GTEST_USER_FILTER} GTEST_USER_DISABLED ${GTEST_TEST_NAME}) + if(GTEST_USER_DISABLED) + break() + endif() + endforeach() + # Add environment if(WIN32) set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME} APPEND PROPERTY ENVIRONMENT "PATH=${WIN_PATH}") @@ -64,8 +79,10 @@ macro(add_blackbox_gtest) set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME} APPEND PROPERTY ENVIRONMENT "${property}") endforeach() - # Add labels - set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME} PROPERTY LABELS "${GTEST_LABELS}") + # Add labels and enable + set_tests_properties(${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME} PROPERTIES + LABELS "${GTEST_LABELS}" + DISABLED $<BOOL:${GTEST_USER_DISABLED}>) endforeach() file(STRINGS ${GTEST_SOURCE_FILE} GTEST_TEST_NAMES REGEX "^TEST_P" ) @@ -77,6 +94,15 @@ macro(add_blackbox_gtest) add_test(NAME ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Transport COMMAND ${command} --gtest_filter=*/${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}/Transport*) + # decide if disable + unset(GTEST_USER_DISABLED) + foreach(GTEST_USER_FILTER ${GTEST_IGNORE}) + string(REGEX MATCH ${GTEST_USER_FILTER} GTEST_USER_DISABLED ${GTEST_TEST_NAME}) + if(GTEST_USER_DISABLED) + break() + endif() + endforeach() + # Add environment if(WIN32) set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Transport APPEND PROPERTY ENVIRONMENT "PATH=${WIN_PATH}") @@ -86,8 +112,10 @@ macro(add_blackbox_gtest) set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Transport APPEND PROPERTY ENVIRONMENT "${property}") endforeach() - # Add labels - set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Transport PROPERTY LABELS "${GTEST_LABELS}") + # Add labels and enable + set_tests_properties(${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Transport PROPERTIES + LABELS "${GTEST_LABELS}" + DISABLED $<BOOL:${GTEST_USER_DISABLED}>) add_test(NAME ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Intraprocess COMMAND ${command} --gtest_filter=*/${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}/Intraprocess*) @@ -101,8 +129,10 @@ macro(add_blackbox_gtest) set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Intraprocess APPEND PROPERTY ENVIRONMENT "${property}") endforeach() - # Add labels - set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Intraprocess PROPERTY LABELS "${GTEST_LABELS}") + # Add labels and enable + set_tests_properties(${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Intraprocess PROPERTIES + LABELS "${GTEST_LABELS}" + DISABLED $<BOOL:${GTEST_USER_DISABLED}>) if(${test} MATCHES ".*_DDS_PIM$") add_test(NAME ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Datasharing @@ -117,13 +147,22 @@ macro(add_blackbox_gtest) set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Datasharing APPEND PROPERTY ENVIRONMENT "${property}") endforeach() - # Add labels - set_property(TEST ${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Datasharing PROPERTY LABELS "${GTEST_LABELS}") + # Add labels and enable + set_tests_properties(${test}.${GTEST_GROUP_NAME}.${GTEST_TEST_NAME}.Datasharing PROPERTIES + LABELS "${GTEST_LABELS}" + DISABLED $<BOOL:${GTEST_USER_DISABLED}>) + endif() endforeach() endforeach() else() + + # add filtering statement if required + if(GTEST_IGNORE) + set(command "${command} --gtest_filter=${GTEST_IGNORE}") + endif() + add_test(NAME ${test} COMMAND ${command}) # Add environment @@ -164,9 +203,28 @@ if(WIN32) ) endif() +# OpenSSL on Windows requires a hint on which config file to load +if(WIN32 AND OPENSSL_FOUND) + get_filename_component(OPENSSL_DIR "${OPENSSL_INCLUDE_DIR}" DIRECTORY) + set(OPENSSL_CONF "${OPENSSL_DIR}/bin/cnf/openssl.cnf") + unset(OPENSSL_DIR) +endif() + ############################################################################### -# Unit tests +# Blackbox tests ############################################################################### + +# Filter pksc11 related tests if library is not available +# TODO: restore for windows when CI gets operational +#if(NOT LibP11_FOUND) +if(WIN32 OR NOT LibP11_FOUND) + if(GTEST_INDIVIDUAL) + set(pkcs_filter "[Pp][Kk][Cc][Ss]") + else() + set(pkcs_filter "-*pcks*") + endif() # GTEST_INDIVIDUAL +endif() # LibP11_FOUND + file(GLOB RTPS_BLACKBOXTESTS_TEST_SOURCE "common/RTPSBlackboxTests*.cpp") set(RTPS_BLACKBOXTESTS_SOURCE ${RTPS_BLACKBOXTESTS_TEST_SOURCE} types/HelloWorld.cpp @@ -199,7 +257,7 @@ target_compile_definitions(BlackboxTests_RTPS PRIVATE target_include_directories(BlackboxTests_RTPS PRIVATE ${Asio_INCLUDE_DIR}) target_link_libraries(BlackboxTests_RTPS fastrtps fastcdr foonathan_memory GTest::gtest) -add_blackbox_gtest(BlackboxTests_RTPS SOURCES ${RTPS_BLACKBOXTESTS_TEST_SOURCE}) +add_blackbox_gtest(BlackboxTests_RTPS SOURCES ${RTPS_BLACKBOXTESTS_TEST_SOURCE} IGNORE ${pkcs_filter}) file(GLOB BLACKBOXTESTS_TEST_SOURCE "common/BlackboxTests*.cpp") set(BLACKBOXTESTS_SOURCE ${BLACKBOXTESTS_TEST_SOURCE} @@ -280,13 +338,22 @@ if(FASTRTPS_API_TESTS) target_include_directories(BlackboxTests_FastRTPS PRIVATE ${Asio_INCLUDE_DIR} api/fastrtps_deprecated) - target_link_libraries(BlackboxTests_FastRTPS fastrtps fastcdr foonathan_memory GTest::gtest) + target_link_libraries(BlackboxTests_FastRTPS + fastrtps + fastcdr + foonathan_memory + GTest::gtest + $<$<BOOL:${LibP11_FOUND}>:eProsima_p11> # $<TARGET_NAME_IF_EXISTS:eProsima_p11> + ) + add_blackbox_gtest(BlackboxTests_FastRTPS SOURCES ${BLACKBOXTESTS_TEST_SOURCE} ENVIRONMENTS "CERTS_PATH=${PROJECT_SOURCE_DIR}/test/certs" "TOPIC_RANDOM_NUMBER=${TOPIC_RANDOM_NUMBER}" "W_UNICAST_PORT_RANDOM_NUMBER=${W_UNICAST_PORT_RANDOM_NUMBER}" "R_UNICAST_PORT_RANDOM_NUMBER=${R_UNICAST_PORT_RANDOM_NUMBER}" "MULTICAST_PORT_RANDOM_NUMBER=${MULTICAST_PORT_RANDOM_NUMBER}" + $<$<BOOL:${OPENSSL_CONF}>:OPENSSL_CONF=${OPENSSL_CONF}> + IGNORE ${pkcs_filter} ) endif(FASTRTPS_API_TESTS) @@ -319,13 +386,21 @@ if(FASTDDS_PIM_API_TESTS) target_include_directories(BlackboxTests_DDS_PIM PRIVATE ${Asio_INCLUDE_DIR} api/dds-pim) - target_link_libraries(BlackboxTests_DDS_PIM fastrtps fastcdr foonathan_memory GTest::gtest) + target_link_libraries(BlackboxTests_DDS_PIM + fastrtps + fastcdr + foonathan_memory + GTest::gtest + $<$<BOOL:${LibP11_FOUND}>:eProsima_p11> # $<TARGET_NAME_IF_EXISTS:eProsima_p11> + ) add_blackbox_gtest(BlackboxTests_DDS_PIM SOURCES ${DDS_BLACKBOXTESTS_SOURCE} ENVIRONMENTS "CERTS_PATH=${PROJECT_SOURCE_DIR}/test/certs" "TOPIC_RANDOM_NUMBER=${TOPIC_RANDOM_NUMBER}" "W_UNICAST_PORT_RANDOM_NUMBER=${W_UNICAST_PORT_RANDOM_NUMBER}" "R_UNICAST_PORT_RANDOM_NUMBER=${R_UNICAST_PORT_RANDOM_NUMBER}" "MULTICAST_PORT_RANDOM_NUMBER=${MULTICAST_PORT_RANDOM_NUMBER}" + $<$<BOOL:${OPENSSL_CONF}>:OPENSSL_CONF=${OPENSSL_CONF}> + IGNORE ${pkcs_filter} ) endif(FASTDDS_PIM_API_TESTS) diff --git a/test/blackbox/api/dds-pim/PubSubReader.hpp b/test/blackbox/api/dds-pim/PubSubReader.hpp index 0a27fbdbb40..7697a4b3667 100644 --- a/test/blackbox/api/dds-pim/PubSubReader.hpp +++ b/test/blackbox/api/dds-pim/PubSubReader.hpp @@ -349,26 +349,27 @@ class PubSubReader participant_qos_, &participant_listener_, eprosima::fastdds::dds::StatusMask::none()); - ASSERT_NE(participant_, nullptr); - ASSERT_TRUE(participant_->is_enabled()); } - participant_guid_ = participant_->guid(); + if (participant_ != nullptr) + { + participant_guid_ = participant_->guid(); - type_.reset(new type_support()); + type_.reset(new type_support()); - // Register type - ASSERT_EQ(participant_->register_type(type_), ReturnCode_t::RETCODE_OK); + // Register type + ASSERT_EQ(participant_->register_type(type_), ReturnCode_t::RETCODE_OK); - // Create topic - topic_ = - participant_->create_topic(topic_name_, type_->getName(), - eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); - ASSERT_NE(topic_, nullptr); - ASSERT_TRUE(topic_->is_enabled()); + // Create topic + topic_ = + participant_->create_topic(topic_name_, type_->getName(), + eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); + ASSERT_NE(topic_, nullptr); + ASSERT_TRUE(topic_->is_enabled()); - // Create publisher - createSubscriber(); + // Create publisher + createSubscriber(); + } } virtual void createSubscriber() diff --git a/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp b/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp index 2ae8b618bf0..a5e40ab3dff 100644 --- a/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp +++ b/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp @@ -301,22 +301,23 @@ class PubSubReader participant_ = eprosima::fastrtps::Domain::createParticipant(participant_attr, &participant_listener_); - ASSERT_NE(participant_, nullptr); - - participant_guid_ = participant_->getGuid(); + if (participant_ != nullptr) + { + participant_guid_ = participant_->getGuid(); - // Register type - ASSERT_EQ(eprosima::fastrtps::Domain::registerType(participant_, &type_), true); + // Register type + ASSERT_EQ(eprosima::fastrtps::Domain::registerType(participant_, &type_), true); - //Create subscribe r - subscriber_ = eprosima::fastrtps::Domain::createSubscriber(participant_, subscriber_attr, &listener_); + //Create subscribe r + subscriber_ = eprosima::fastrtps::Domain::createSubscriber(participant_, subscriber_attr, &listener_); - if (subscriber_ != nullptr) - { - std::cout << "Created subscriber " << subscriber_->getGuid() << " for topic " << - subscriber_attr_.topic.topicName << std::endl; + if (subscriber_ != nullptr) + { + std::cout << "Created subscriber " << subscriber_->getGuid() << " for topic " << + subscriber_attr_.topic.topicName << std::endl; - initialized_ = true; + initialized_ = true; + } } } diff --git a/test/blackbox/common/BlackboxTestsSecurity.cpp b/test/blackbox/common/BlackboxTestsSecurity.cpp index 9a51b2dfbd8..f8898919521 100644 --- a/test/blackbox/common/BlackboxTestsSecurity.cpp +++ b/test/blackbox/common/BlackboxTestsSecurity.cpp @@ -22,6 +22,9 @@ #include "PubSubParticipant.hpp" #include <gtest/gtest.h> +#include <fstream> +#include <map> +#include <algorithm> #include <fastrtps/xmlparser/XMLProfileManager.h> #include <fastdds/rtps/transport/shared_mem/SharedMemTransportDescriptor.h> @@ -83,6 +86,151 @@ class Security : public testing::TestWithParam<communication_type> }; + +class SecurityPkcs : public ::testing::Test +{ +public: + + struct HsmToken + { + std::string pin; + std::string id; + std::string serial; + std::map<std::string, std::string> urls; + }; + + static void create_hsm_token( + const char* token_id) + { + // Init the token + std::stringstream cmd; + cmd << "softhsm2-util --init-token --free --label " << token_id << " --pin " << hsm_token_pin + << " --so-pin " << hsm_token_pin << ""; + ASSERT_EQ(0, std::system (cmd.str().c_str())); + tokens[token_id] = HsmToken(); + tokens[token_id].pin = hsm_token_pin; + tokens[token_id].id = token_id; + + // Get the serial number of the HSM slot + std::stringstream serial_stream; +#ifdef _WIN32 // We are running windows + ASSERT_EQ(0, + std::system ("powershell -C \"softhsm2-util --show-slots | sls 'Serial number:\\s*([\\d\\w]+)' | " \ + "% { $_.Matches.Groups[1].Value } | Out-File -FilePath softhsm_serial -Encoding ASCII\"")); +#else // We are running something with sh + ASSERT_EQ(0, + std::system ("softhsm2-util --show-slots | grep -oP 'Serial number:\\s*\\K(\\d|\\w)+' > softhsm_serial")); +#endif // _WIN32 + serial_stream << std::ifstream("softhsm_serial").rdbuf(); + std::remove ("softhsm_serial"); + + // Read each serial number one by one + while (!serial_stream.eof()) + { + std::string serial; + serial_stream >> serial; + if (!serial.empty()) + { + if (tokens.end() == std::find_if(tokens.begin(), tokens.end(), [&serial](std::pair<const char* const, + const HsmToken> t) + { + return t.second.serial == serial; + })) + { + tokens[token_id].serial = serial; + break; + } + } + } + } + + static void delete_hsm_token( + const char* token_id) + { + auto it = tokens.find(token_id); + if (it != tokens.end()) + { + // Delete the token + std::stringstream cmd; + cmd << "softhsm2-util --delete-token --token " << token_id << " --pin " << hsm_token_pin + << " --so-pin " << hsm_token_pin << ""; + ASSERT_EQ(0, std::system (cmd.str().c_str())); + tokens.erase(it); + } + } + + static void SetUpTestCase() + { + // Init the tokens + create_hsm_token(hsm_token_id_no_pin); + create_hsm_token(hsm_token_id_url_pin); + create_hsm_token(hsm_token_id_env_pin); + + // Add the keys to the tokens + import_private_key(std::string(certs_path) + "/mainsubkey.pem", hsm_mainsubkey_label, + "1A2B3C", hsm_token_id_no_pin); + import_private_key(std::string(certs_path) + "/mainpubkey.pem", hsm_mainpubkey_label, + "ABCDEF", hsm_token_id_no_pin); + import_private_key(std::string(certs_path) + "/mainsubkey.pem", hsm_mainsubkey_label, + "123456", hsm_token_id_url_pin); + import_private_key(std::string(certs_path) + "/mainpubkey.pem", hsm_mainpubkey_label, + "789ABC", hsm_token_id_url_pin); + import_private_key(std::string(certs_path) + "/mainsubkey.pem", hsm_mainsubkey_label, + "2468AC", hsm_token_id_env_pin); + import_private_key(std::string(certs_path) + "/mainpubkey.pem", hsm_mainpubkey_label, + "13579B", hsm_token_id_env_pin); + } + + static void TearDownTestCase() + { + // delete the tokens + delete_hsm_token(hsm_token_id_no_pin); + delete_hsm_token(hsm_token_id_url_pin); + delete_hsm_token(hsm_token_id_env_pin); + } + + static void import_private_key( + const std::string& key_file, + const char* key_label, + const char* key_id, + const char* token_id) + { + ASSERT_NE(tokens.end(), tokens.find(token_id)); + + std::stringstream cmd; + cmd << "softhsm2-util --import " << key_file << " --token " << token_id << " --label " << key_label + << " --pin " << hsm_token_pin << " --id " << key_id << ""; + // Import the key + ASSERT_EQ(0, + std::system(cmd.str().c_str())); + // Construct the key URL + std::stringstream id_url; + for (unsigned int i = 0; i < strlen(key_id); i += 2) + { + id_url << "%" << key_id[i] << key_id[i + 1]; + } + + tokens[token_id].urls[key_label] = "pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=" + + tokens[token_id].serial + ";token=" + token_id + ";id=" + id_url.str() + ";object=" + key_label + + ";type=private"; + } + + static const char* const hsm_token_id_no_pin; + static const char* const hsm_token_id_url_pin; + static const char* const hsm_token_id_env_pin; + + static constexpr const char* hsm_token_pin = "1234"; + static constexpr const char* hsm_mainsubkey_label = "mainsubkey"; + static constexpr const char* hsm_mainpubkey_label = "mainpubkey"; + + static std::map<const char*, HsmToken> tokens; +}; + +std::map<const char*, SecurityPkcs::HsmToken> SecurityPkcs::tokens; +const char* const SecurityPkcs::hsm_token_id_no_pin = "testing_token_no_pin"; +const char* const SecurityPkcs::hsm_token_id_url_pin = "testing_token_url_pin"; +const char* const SecurityPkcs::hsm_token_id_env_pin = "testing_token_env_pin"; + TEST_P(Security, BuiltinAuthenticationPlugin_PKIDH_validation_ok) { PubSubReader<HelloWorldType> reader(TEST_TOPIC_NAME); @@ -2896,6 +3044,157 @@ TEST_P(Security, BuiltinAuthenticationAndAccessAndCryptoPlugin_Permissions_valid } } +#if HAVE_LIBP11 + +template <typename DataType> +void prepare_pkcs11_nodes( + PubSubReader<DataType>& reader, + PubSubWriter<DataType>& writer, + const std::string& reader_private_key_url, + const std::string& writer_private_key_url) +{ + std::string governance_file("governance_helloworld_all_enable.smime"); + + // With no PIN, the load of the private key fails + PropertyPolicy pub_property_policy; + PropertyPolicy sub_property_policy; + + sub_property_policy.properties().emplace_back(Property("dds.sec.auth.plugin", + "builtin.PKI-DH")); + sub_property_policy.properties().emplace_back(Property("dds.sec.auth.builtin.PKI-DH.identity_ca", + "file://" + std::string(certs_path) + "/maincacert.pem")); + sub_property_policy.properties().emplace_back(Property("dds.sec.auth.builtin.PKI-DH.identity_certificate", + "file://" + std::string(certs_path) + "/mainsubcert.pem")); + sub_property_policy.properties().emplace_back(Property("dds.sec.auth.builtin.PKI-DH.private_key", + reader_private_key_url)); + sub_property_policy.properties().emplace_back(Property("dds.sec.crypto.plugin", + "builtin.AES-GCM-GMAC")); + sub_property_policy.properties().emplace_back(Property("dds.sec.access.plugin", + "builtin.Access-Permissions")); + sub_property_policy.properties().emplace_back(Property( + "dds.sec.access.builtin.Access-Permissions.permissions_ca", + "file://" + std::string(certs_path) + "/maincacert.pem")); + sub_property_policy.properties().emplace_back(Property("dds.sec.access.builtin.Access-Permissions.governance", + "file://" + std::string(certs_path) + "/" + governance_file)); + sub_property_policy.properties().emplace_back(Property("dds.sec.access.builtin.Access-Permissions.permissions", + "file://" + std::string(certs_path) + "/permissions_helloworld.smime")); + + reader.history_depth(10). + reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS). + property_policy(sub_property_policy).init(); + + pub_property_policy.properties().emplace_back(Property("dds.sec.auth.plugin", + "builtin.PKI-DH")); + pub_property_policy.properties().emplace_back(Property("dds.sec.auth.builtin.PKI-DH.identity_ca", + "file://" + std::string(certs_path) + "/maincacert.pem")); + pub_property_policy.properties().emplace_back(Property("dds.sec.auth.builtin.PKI-DH.identity_certificate", + "file://" + std::string(certs_path) + "/mainpubcert.pem")); + pub_property_policy.properties().emplace_back(Property("dds.sec.auth.builtin.PKI-DH.private_key", + writer_private_key_url)); + pub_property_policy.properties().emplace_back(Property("dds.sec.crypto.plugin", + "builtin.AES-GCM-GMAC")); + pub_property_policy.properties().emplace_back(Property("dds.sec.access.plugin", + "builtin.Access-Permissions")); + pub_property_policy.properties().emplace_back(Property( + "dds.sec.access.builtin.Access-Permissions.permissions_ca", + "file://" + std::string(certs_path) + "/maincacert.pem")); + pub_property_policy.properties().emplace_back(Property("dds.sec.access.builtin.Access-Permissions.governance", + "file://" + std::string(certs_path) + "/" + governance_file)); + pub_property_policy.properties().emplace_back(Property("dds.sec.access.builtin.Access-Permissions.permissions", + "file://" + std::string(certs_path) + "/permissions_helloworld.smime")); + + writer.history_depth(10). + property_policy(pub_property_policy).init(); +} + +TEST_F(SecurityPkcs, BuiltinAuthenticationAndAccessAndCryptoPlugin_pkcs11_key) +{ + { + PubSubReader<HelloWorldType> reader("HelloWorldTopic"); + PubSubWriter<HelloWorldType> writer("HelloWorldTopic"); + prepare_pkcs11_nodes(reader, writer, + tokens[hsm_token_id_no_pin].urls[hsm_mainsubkey_label], + tokens[hsm_token_id_no_pin].urls[hsm_mainpubkey_label]); + + ASSERT_FALSE(reader.isInitialized()); + ASSERT_FALSE(writer.isInitialized()); + } + { + PubSubReader<HelloWorldType> reader("HelloWorldTopic"); + PubSubWriter<HelloWorldType> writer("HelloWorldTopic"); + prepare_pkcs11_nodes(reader, writer, + tokens[hsm_token_id_url_pin].urls[hsm_mainsubkey_label] + "?pin-value=" + hsm_token_pin, + tokens[hsm_token_id_url_pin].urls[hsm_mainpubkey_label] + "?pin-value=" + hsm_token_pin); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Wait for authorization + reader.waitAuthorized(); + writer.waitAuthorized(); + + // Wait for discovery. + writer.wait_discovery(); + reader.wait_discovery(); + + auto data = default_helloworld_data_generator(); + + reader.startReception(data); + + // Send data + writer.send(data); + // In this test all data should be sent. + ASSERT_TRUE(data.empty()); + // Block reader until reception finished or timeout. + reader.block_for_all(); + + } + { + // Set the PIN on the environment variable +#ifdef _WIN32 + _putenv_s("FASTDDS_PKCS11_PIN", "1234"); +#else + setenv("FASTDDS_PKCS11_PIN", "1234", 1); +#endif // ifdef _WIN32 + + PubSubReader<HelloWorldType> reader("HelloWorldTopic"); + PubSubWriter<HelloWorldType> writer("HelloWorldTopic"); + prepare_pkcs11_nodes(reader, writer, + tokens[hsm_token_id_env_pin].urls[hsm_mainsubkey_label], + tokens[hsm_token_id_env_pin].urls[hsm_mainpubkey_label]); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Wait for authorization + reader.waitAuthorized(); + writer.waitAuthorized(); + + // Wait for discovery. + writer.wait_discovery(); + reader.wait_discovery(); + + auto data = default_helloworld_data_generator(); + + reader.startReception(data); + + // Send data + writer.send(data); + // In this test all data should be sent. + ASSERT_TRUE(data.empty()); + // Block reader until reception finished or timeout. + reader.block_for_all(); + + // unset the PIN environment variable for the next round +#ifdef _WIN32 + _putenv_s("FASTDDS_PKCS11_PIN", ""); +#else + unsetenv("FASTDDS_PKCS11_PIN"); +#endif // ifdef _WIN32 + } +} +#endif // HAVE_LIBP11 + static void BuiltinAuthenticationAndAccessAndCryptoPlugin_Permissions_validation_ok_common( PubSubReader<HelloWorldType>& reader, PubSubWriter<HelloWorldType>& writer, diff --git a/test/unittest/dds/publisher/CMakeLists.txt b/test/unittest/dds/publisher/CMakeLists.txt index 3b5305eb46f..6efdb519daf 100644 --- a/test/unittest/dds/publisher/CMakeLists.txt +++ b/test/unittest/dds/publisher/CMakeLists.txt @@ -235,6 +235,7 @@ set(DATAWRITERTESTS_SOURCE DataWriterTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/logging/Logging.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/SecurityManager.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/SecurityPluginFactory.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/security/artifact_providers/Pkcs11Provider.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/authentication/PKIDH.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/accesscontrol/Permissions.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/cryptography/AESGCMGMAC.cpp @@ -242,6 +243,7 @@ set(DATAWRITERTESTS_SOURCE DataWriterTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/cryptography/AESGCMGMAC_KeyFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/cryptography/AESGCMGMAC_Transform.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/cryptography/AESGCMGMAC_Types.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/security/artifact_providers/FileProvider.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/authentication/PKIIdentityHandle.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/authentication/PKIHandshakeHandle.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/accesscontrol/AccessPermissionsHandle.cpp @@ -318,6 +320,7 @@ target_link_libraries(DataWriterTests fastcdr foonathan_memory $<$<BOOL:${LINK_SSL}>:OpenSSL::SSL$<SEMICOLON>OpenSSL::Crypto> $<$<BOOL:${WIN32}>:iphlpapi$<SEMICOLON>Shlwapi> ${THIRDPARTY_BOOST_LINK_LIBS} + $<$<BOOL:${LibP11_FOUND}>:eProsima_p11> # $<TARGET_NAME_IF_EXISTS:eProsima_p11> eProsima_atomic ) if(MSVC OR MSVC_IDE) diff --git a/test/unittest/security/accesscontrol/CMakeLists.txt b/test/unittest/security/accesscontrol/CMakeLists.txt index 2e84c4456ef..a13c4695f42 100644 --- a/test/unittest/security/accesscontrol/CMakeLists.txt +++ b/test/unittest/security/accesscontrol/CMakeLists.txt @@ -56,10 +56,13 @@ add_executable(AccessControlTests ${COMMON_SOURCES_ACCESS_CONTROL_TEST_SOURCE} ${PROJECT_SOURCE_DIR}/src/cpp/security/accesscontrol/GovernanceParser.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/accesscontrol/Permissions.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/accesscontrol/PermissionsParser.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/security/artifact_providers/FileProvider.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/security/artifact_providers/Pkcs11Provider.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/md5.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPFinder.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPLocator.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/StringMatching.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/utils/SystemInfo.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/publisher/qos/WriterQos.cpp ${CMAKE_CURRENT_SOURCE_DIR}/AccessControlTests.cpp) @@ -91,6 +94,7 @@ target_link_libraries(AccessControlTests foonathan_memory $<$<BOOL:${WIN32}>:ws2_32> ${TINYXML2_LIBRARY} + $<$<BOOL:${LibP11_FOUND}>:eProsima_p11> # $<TARGET_NAME_IF_EXISTS:eProsima_p11> ) if(MSVC OR MSVC_IDE) diff --git a/test/unittest/security/authentication/CMakeLists.txt b/test/unittest/security/authentication/CMakeLists.txt index 50037265c63..f30a76e3960 100644 --- a/test/unittest/security/authentication/CMakeLists.txt +++ b/test/unittest/security/authentication/CMakeLists.txt @@ -44,9 +44,12 @@ add_executable(BuiltinPKIDH ${COMMON_SOURCES_AUTH_PLUGIN_TEST_SOURCE} ${PROJECT_SOURCE_DIR}/src/cpp/security/authentication/PKIDH.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/authentication/PKIIdentityHandle.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/authentication/PKIHandshakeHandle.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/security/artifact_providers/FileProvider.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/security/artifact_providers/Pkcs11Provider.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/md5.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPFinder.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPLocator.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/utils/SystemInfo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/BuiltinPKIDHTests.cpp) target_compile_definitions(BuiltinPKIDH PRIVATE FASTRTPS_NO_LIB BOOST_ASIO_STANDALONE @@ -61,7 +64,14 @@ target_include_directories(BuiltinPKIDH PRIVATE ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include ${PROJECT_SOURCE_DIR}/src/cpp ) -target_link_libraries(BuiltinPKIDH GTest::gtest ${OPENSSL_LIBRARIES} fastcdr foonathan_memory $<$<BOOL:${WIN32}>:ws2_32>) +target_link_libraries(BuiltinPKIDH + GTest::gtest + ${OPENSSL_LIBRARIES} + fastcdr + foonathan_memory + $<$<BOOL:${WIN32}>:ws2_32> + $<$<BOOL:${LibP11_FOUND}>:eProsima_p11> # $<TARGET_NAME_IF_EXISTS:eProsima_p11> + ) add_gtest(BuiltinPKIDH SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/BuiltinPKIDHTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/AuthenticationPluginTests.hpp diff --git a/test/unittest/statistics/dds/CMakeLists.txt b/test/unittest/statistics/dds/CMakeLists.txt index 4ec673f91d4..fcc8c98a2a1 100644 --- a/test/unittest/statistics/dds/CMakeLists.txt +++ b/test/unittest/statistics/dds/CMakeLists.txt @@ -280,6 +280,7 @@ if (SQLITE3_SUPPORT AND FASTDDS_STATISTICS) ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/logging/Logging.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/SecurityManager.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/SecurityPluginFactory.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/security/artifact_providers/FileProvider.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/authentication/PKIDH.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/accesscontrol/Permissions.cpp ${PROJECT_SOURCE_DIR}/src/cpp/security/cryptography/AESGCMGMAC.cpp diff --git a/test/unittest/transport/TCPv4Tests.cpp b/test/unittest/transport/TCPv4Tests.cpp index 43780e9a8a0..e46ee0580e7 100644 --- a/test/unittest/transport/TCPv4Tests.cpp +++ b/test/unittest/transport/TCPv4Tests.cpp @@ -533,11 +533,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_client_verifies) (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { - Locators input_begin(locator_list.begin()); - Locators input_end(locator_list.end()); + Locators l_input_begin(locator_list.begin()); + Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -633,11 +633,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_server_verifies) (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { - Locators input_begin(locator_list.begin()); - Locators input_end(locator_list.end()); + Locators l_input_begin(locator_list.begin()); + Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -735,11 +735,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports) (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { - Locators input_begin(locator_list.begin()); - Locators input_end(locator_list.end()); + Locators l_input_begin(locator_list.begin()); + Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -839,11 +839,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_both_secure_ports_untrusted) int count = 0; while (!sent && count < 30) { - Locators input_begin(locator_list.begin()); - Locators input_end(locator_list.end()); + Locators l_input_begin(locator_list.begin()); + Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++count; @@ -943,11 +943,11 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_clients_1) (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); while (!sent) { - Locators input_begin(locator_list.begin()); - Locators input_end(locator_list.end()); + Locators l_input_begin(locator_list.begin()); + Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -1132,10 +1132,10 @@ TEST_F(TCPv4Tests, send_and_receive_between_secure_ports_untrusted_server) int count = 0; while (!sent && count < 30) { - Locators input_begin(locator_list.begin()); - Locators input_end(locator_list.end()); + Locators l_input_begin(locator_list.begin()); + Locators l_input_end(locator_list.end()); sent = - send_resource_list.at(0)->send(message, 5, &input_begin, &input_end, + send_resource_list.at(0)->send(message, 5, &l_input_begin, &l_input_end, (std::chrono::steady_clock::now() + std::chrono::microseconds(100))); std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++count;