Skip to content

Commit fb2ef9d

Browse files
JLBuenoLopezIkerLuengo
authored andcommitted
Add support for PKCS#11 in security files (#5)
* Add support for PKCS#11 in security files In addition to *.pem files containing the key or certificate, adds support for *.p11 files that contain the PKCS#11 URI of the key or certificate in an HSM. Signed-off-by: Iker Luengo <ikerluengo@eprosima.com> * linters Signed-off-by: Iker Luengo <ikerluengo@eprosima.com> Co-authored-by: Iker Luengo <ikerluengo@eprosima.com>
1 parent b45e735 commit fb2ef9d

1 file changed

Lines changed: 118 additions & 1 deletion

File tree

rmw_fastrtps_shared_cpp/src/participant.cpp

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#include <string>
1818
#include <unordered_map>
1919
#include <vector>
20+
#include <fstream>
21+
#include <functional>
22+
#include <utility>
2023

2124
#include "fastdds/dds/core/status/StatusMask.hpp"
2225
#include "fastdds/dds/domain/DomainParticipantFactory.hpp"
@@ -35,6 +38,7 @@
3538
#include "fastrtps/utils/IPLocator.h"
3639

3740
#include "rcpputils/scope_exit.hpp"
41+
#include "rcpputils/filesystem_helper.hpp"
3842
#include "rcutils/env.h"
3943
#include "rcutils/filesystem.h"
4044

@@ -142,6 +146,119 @@ __create_participant(
142146
return participant_info;
143147
}
144148

149+
// Processor for security attributes with FILE URI
150+
bool process_file_uri_security_file(
151+
const std::string & prefix, const rcpputils::fs::path & full_path,
152+
std::string & result)
153+
{
154+
if (!full_path.is_regular_file()) {
155+
return false;
156+
}
157+
result = prefix + full_path.string();
158+
return true;
159+
}
160+
161+
// Processor for security attributes with PKCS#11 URI
162+
bool process_pkcs_uri_security_file(
163+
const std::string & /*prefix*/, const rcpputils::fs::path & full_path,
164+
std::string & result)
165+
{
166+
const std::string p11_prefix("pkcs11:");
167+
168+
std::ifstream ifs(full_path.string());
169+
if (!ifs.is_open()) {
170+
return false;
171+
}
172+
173+
if (!(ifs >> result)) {
174+
return false;
175+
}
176+
if (result.find(p11_prefix) != 0) {
177+
return false;
178+
}
179+
180+
return true;
181+
}
182+
183+
bool get_security_files(
184+
const std::string & prefix, const std::string & secure_root,
185+
std::unordered_map<std::string, std::string> & result)
186+
{
187+
using std::placeholders::_1;
188+
using std::placeholders::_2;
189+
using std::placeholders::_3;
190+
using security_file_processor =
191+
std::function<bool (const std::string &, const rcpputils::fs::path &, std::string &)>;
192+
using processor_vector =
193+
std::vector<std::pair<std::string, security_file_processor>>;
194+
195+
// Key: the security attribute
196+
// Value: ordered sequence of pairs. Each pair contains one possible file name
197+
// for the attribute and the corresponding processor method
198+
// Pairs are ordered by priority: the first one matching is used.
199+
const std::unordered_map<std::string, processor_vector> required_files{
200+
{"IDENTITY_CA", {
201+
{"identity_ca.cert.pem", std::bind(process_file_uri_security_file, _1, _2, _3)},
202+
{"identity_ca.cert.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3)}}},
203+
{"CERTIFICATE", {
204+
{"cert.pem", std::bind(process_file_uri_security_file, _1, _2, _3)},
205+
{"cert.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3)}}},
206+
{"PRIVATE_KEY", {
207+
{"key.pem", std::bind(process_file_uri_security_file, _1, _2, _3)},
208+
{"key.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3)}}},
209+
{"PERMISSIONS_CA", {
210+
{"permissions_ca.cert.pem", std::bind(process_file_uri_security_file, _1, _2, _3)},
211+
{"permissions_ca.cert.p11", std::bind(process_pkcs_uri_security_file, _1, _2, _3)}}},
212+
{"GOVERNANCE", {
213+
{"governance.p7s", std::bind(process_file_uri_security_file, _1, _2, _3)}}},
214+
{"PERMISSIONS", {
215+
{"permissions.p7s", std::bind(process_file_uri_security_file, _1, _2, _3)}}},
216+
};
217+
218+
const std::unordered_map<std::string, processor_vector> optional_files{
219+
{"CRL", {
220+
{"crl.pem", std::bind(process_file_uri_security_file, _1, _2, _3)}}}
221+
};
222+
223+
for (const std::pair<const std::string,
224+
std::vector<std::pair<std::string, security_file_processor>>> & el : required_files)
225+
{
226+
std::string attribute_value;
227+
bool processed = false;
228+
for (auto & proc : el.second) {
229+
rcpputils::fs::path full_path(secure_root);
230+
full_path /= proc.first;
231+
if (proc.second(prefix, full_path, attribute_value)) {
232+
processed = true;
233+
break;
234+
}
235+
}
236+
if (!processed) {
237+
result.clear();
238+
return false;
239+
}
240+
result[el.first] = attribute_value;
241+
}
242+
243+
for (const std::pair<const std::string, processor_vector> & el : optional_files) {
244+
std::string attribute_value;
245+
bool processed = false;
246+
for (auto & proc : el.second) {
247+
rcpputils::fs::path full_path(secure_root);
248+
full_path /= proc.first;
249+
if (proc.second(prefix, full_path, attribute_value)) {
250+
processed = true;
251+
break;
252+
}
253+
}
254+
if (processed) {
255+
result[el.first] = attribute_value;
256+
}
257+
}
258+
259+
return true;
260+
}
261+
145262
CustomParticipantInfo *
146263
rmw_fastrtps_shared_cpp::create_participant(
147264
const char * identifier,
@@ -318,7 +435,7 @@ rmw_fastrtps_shared_cpp::create_participant(
318435
// if security_root_path provided, try to find the key and certificate files
319436
#if HAVE_SECURITY
320437
std::unordered_map<std::string, std::string> security_files_paths;
321-
if (rmw_dds_common::get_security_files(
438+
if (get_security_files(
322439
"file://", security_options->security_root_path, security_files_paths))
323440
{
324441
eprosima::fastrtps::rtps::PropertyPolicy property_policy;

0 commit comments

Comments
 (0)