1313// limitations under the License.
1414
1515#include < filesystem>
16+ #include < fstream>
17+ #include < functional>
1618#include < string>
1719#include < utility>
1820#include < unordered_map>
21+ #include < vector>
1922
2023#include " rmw_dds_common/security.hpp"
2124
2225namespace rmw_dds_common
2326{
2427
28+ // Processor for security attributes with FILE URI
29+ static bool process_file_uri_security_file (
30+ bool /* supports_pkcs11*/ ,
31+ const std::string & prefix,
32+ const std::filesystem::path & full_path,
33+ std::string & result)
34+ {
35+ if (!std::filesystem::is_regular_file (full_path)) {
36+ return false ;
37+ }
38+ result = prefix + full_path.generic_string ();
39+ return true ;
40+ }
41+
42+ // Processor for security attributes with PKCS#11 URI
43+ static bool process_pkcs_uri_security_file (
44+ bool supports_pkcs11,
45+ const std::string & /* prefix*/ ,
46+ const std::filesystem::path & full_path,
47+ std::string & result)
48+ {
49+ if (!supports_pkcs11) {
50+ return false ;
51+ }
52+
53+ const std::string p11_prefix (" pkcs11:" );
54+
55+ std::ifstream ifs (full_path);
56+ if (!ifs.is_open ()) {
57+ return false ;
58+ }
59+
60+ if (!(ifs >> result)) {
61+ return false ;
62+ }
63+ if (result.find (p11_prefix) != 0 ) {
64+ return false ;
65+ }
66+
67+ return true ;
68+ }
69+
2570bool get_security_files (
2671 const std::string & prefix, const std::string & secure_root,
2772 std::unordered_map<std::string, std::string> & result)
@@ -30,32 +75,66 @@ bool get_security_files(
3075}
3176
3277bool get_security_files (
33- bool /* supports_pkcs11 */ ,
34- const std::string & prefix, const std::string & secure_root,
78+ bool supports_pkcs11,
79+ const std::string & prefix,
80+ const std::string & secure_root,
3581 std::unordered_map<std::string, std::string> & result)
3682{
37- const std::unordered_map<std::string, std::string> required_files{
38- {" IDENTITY_CA" , " identity_ca.cert.pem" },
39- {" CERTIFICATE" , " cert.pem" },
40- {" PRIVATE_KEY" , " key.pem" },
41- {" PERMISSIONS_CA" , " permissions_ca.cert.pem" },
42- {" GOVERNANCE" , " governance.p7s" },
43- {" PERMISSIONS" , " permissions.p7s" },
83+ using std::placeholders::_1;
84+ using std::placeholders::_2;
85+ using std::placeholders::_3;
86+ using std::placeholders::_4;
87+ using security_file_processor =
88+ std::function<bool (bool , const std::string &, const std::filesystem::path &, std::string &)>;
89+ using processor_vector =
90+ std::vector<std::pair<std::string, security_file_processor>>;
91+
92+
93+ // Key: the security attribute
94+ // Value: ordered sequence of pairs. Each pair contains one possible file name
95+ // for the attribute and the corresponding processor method
96+ // Pairs are ordered by priority: the first one matching is used.
97+ const std::unordered_map<std::string, processor_vector> required_files{
98+ {" IDENTITY_CA" , {
99+ {" identity_ca.cert.p11" , std::bind (process_pkcs_uri_security_file, _1, _2, _3, _4)},
100+ {" identity_ca.cert.pem" , std::bind (process_file_uri_security_file, _1, _2, _3, _4)}}},
101+ {" CERTIFICATE" , {
102+ {" cert.p11" , std::bind (process_pkcs_uri_security_file, _1, _2, _3, _4)},
103+ {" cert.pem" , std::bind (process_file_uri_security_file, _1, _2, _3, _4)}}},
104+ {" PRIVATE_KEY" , {
105+ {" key.p11" , std::bind (process_pkcs_uri_security_file, _1, _2, _3, _4)},
106+ {" key.pem" , std::bind (process_file_uri_security_file, _1, _2, _3, _4)}}},
107+ {" PERMISSIONS_CA" , {
108+ {" permissions_ca.cert.p11" , std::bind (process_pkcs_uri_security_file, _1, _2, _3, _4)},
109+ {" permissions_ca.cert.pem" , std::bind (process_file_uri_security_file, _1, _2, _3, _4)}}},
110+ {" GOVERNANCE" , {
111+ {" governance.p7s" , std::bind (process_file_uri_security_file, _1, _2, _3, _4)}}},
112+ {" PERMISSIONS" , {
113+ {" permissions.p7s" , std::bind (process_file_uri_security_file, _1, _2, _3, _4)}}},
44114 };
45115
46116 const std::unordered_map<std::string, std::string> optional_files{
47117 {" CRL" , " crl.pem" },
48118 };
49119
50- for (const std::pair<const std::string, std::string> & el : required_files) {
51- std::filesystem::path full_path (secure_root);
52- full_path /= el.second ;
53- if (!std::filesystem::is_regular_file (full_path)) {
120+ for (const std::pair<const std::string,
121+ std::vector<std::pair<std::string, security_file_processor>>> & el : required_files)
122+ {
123+ std::string attribute_value;
124+ bool processed = false ;
125+ for (auto & proc : el.second ) {
126+ std::filesystem::path full_path (secure_root);
127+ full_path /= proc.first ;
128+ if (proc.second (supports_pkcs11, prefix, full_path, attribute_value)) {
129+ processed = true ;
130+ break ;
131+ }
132+ }
133+ if (!processed) {
54134 result.clear ();
55135 return false ;
56136 }
57-
58- result[el.first ] = prefix + full_path.generic_string ();
137+ result[el.first ] = attribute_value;
59138 }
60139
61140 for (const std::pair<const std::string, std::string> & el : optional_files) {
0 commit comments