From 6e140229772ca98e481e239a47d852b99be60b4f Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Tue, 10 Jan 2023 12:40:32 +0100 Subject: [PATCH] Implement changes to support .p11 files. Signed-off-by: Miguel Company --- rmw_dds_common/src/security.cpp | 109 +++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/rmw_dds_common/src/security.cpp b/rmw_dds_common/src/security.cpp index 1c14164..a363215 100644 --- a/rmw_dds_common/src/security.cpp +++ b/rmw_dds_common/src/security.cpp @@ -12,9 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include #include #include +#include #include "rcpputils/filesystem_helper.hpp" #include "rmw_dds_common/security.hpp" @@ -22,6 +25,48 @@ namespace rmw_dds_common { +// Processor for security attributes with FILE URI +static bool process_file_uri_security_file( + bool /*supports_pkcs11*/, + const std::string & prefix, + const rcpputils::fs::path & full_path, + std::string & result) +{ + if (!full_path.is_regular_file()) { + return false; + } + result = prefix + full_path.string(); + return true; +} + +// Processor for security attributes with PKCS#11 URI +static bool process_pkcs_uri_security_file( + bool supports_pkcs11, + const std::string & /*prefix*/, + const rcpputils::fs::path & full_path, + std::string & result) +{ + if (!supports_pkcs11) { + return false; + } + + const std::string p11_prefix("pkcs11:"); + + std::ifstream ifs(full_path.string()); + if (!ifs.is_open()) { + return false; + } + + if (!(ifs >> result)) { + return false; + } + if (result.find(p11_prefix) != 0) { + return false; + } + + return true; +} + bool get_security_files( const std::string & prefix, const std::string & secure_root, std::unordered_map & result) @@ -30,32 +75,66 @@ bool get_security_files( } bool get_security_files( - bool /* supports_pkcs11 */, - const std::string & prefix, const std::string & secure_root, + bool supports_pkcs11, + const std::string & prefix, + const std::string & secure_root, std::unordered_map & result) { - const std::unordered_map required_files{ - {"IDENTITY_CA", "identity_ca.cert.pem"}, - {"CERTIFICATE", "cert.pem"}, - {"PRIVATE_KEY", "key.pem"}, - {"PERMISSIONS_CA", "permissions_ca.cert.pem"}, - {"GOVERNANCE", "governance.p7s"}, - {"PERMISSIONS", "permissions.p7s"}, + using std::placeholders::_1; + using std::placeholders::_2; + using std::placeholders::_3; + using std::placeholders::_4; + using security_file_processor = + std::function; + using processor_vector = + std::vector>; + + + // Key: the security attribute + // Value: ordered sequence of pairs. Each pair contains one possible file name + // for the attribute and the corresponding processor method + // Pairs are ordered by priority: the first one matching is used. + const std::unordered_map required_files{ + {"IDENTITY_CA", { + {"identity_ca.cert.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3, _4)}, + {"identity_ca.cert.pem", std::bind(process_file_uri_security_file, _1, _2, _3, _4)}}}, + {"CERTIFICATE", { + {"cert.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3, _4)}, + {"cert.pem", std::bind(process_file_uri_security_file, _1, _2, _3, _4)}}}, + {"PRIVATE_KEY", { + {"key.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3, _4)}, + {"key.pem", std::bind(process_file_uri_security_file, _1, _2, _3, _4)}}}, + {"PERMISSIONS_CA", { + {"permissions_ca.cert.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3, _4)}, + {"permissions_ca.cert.pem", std::bind(process_file_uri_security_file, _1, _2, _3, _4)}}}, + {"GOVERNANCE", { + {"governance.p7s", std::bind(process_file_uri_security_file, _1, _2, _3, _4)}}}, + {"PERMISSIONS", { + {"permissions.p7s", std::bind(process_file_uri_security_file, _1, _2, _3, _4)}}}, }; const std::unordered_map optional_files{ {"CRL", "crl.pem"}, }; - for (const std::pair & el : required_files) { - rcpputils::fs::path full_path(secure_root); - full_path /= el.second; - if (!full_path.is_regular_file()) { + for (const std::pair>> & el : required_files) + { + std::string attribute_value; + bool processed = false; + for (auto & proc : el.second) { + rcpputils::fs::path full_path(secure_root); + full_path /= proc.first; + if (proc.second(supports_pkcs11, prefix, full_path, attribute_value)) { + processed = true; + break; + } + } + if (!processed) { result.clear(); return false; } - - result[el.first] = prefix + full_path.string(); + result[el.first] = attribute_value; } for (const std::pair & el : optional_files) {