Update Security module
- Using security entity v3 (from vanetza) - Added the option to use certificates (through ros parameters) Signed-off-by: Tiago Garcia <tiago.rgarcia@av.it.pt>
This commit is contained in:
parent
7b7bb53b39
commit
90b5c22ac3
|
@ -22,7 +22,7 @@ set(VANETZA_INSTALL ON)
|
||||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||||
find_package(Vanetza REQUIRED)
|
find_package(Vanetza REQUIRED)
|
||||||
find_package(GeographicLib 1.37 REQUIRED)
|
find_package(GeographicLib 1.37 REQUIRED)
|
||||||
find_package(Boost COMPONENTS thread REQUIRED)
|
find_package(Boost COMPONENTS thread program_options REQUIRED)
|
||||||
find_package(etsi_its_cam_ts_coding REQUIRED)
|
find_package(etsi_its_cam_ts_coding REQUIRED)
|
||||||
find_package(etsi_its_cam_ts_conversion REQUIRED)
|
find_package(etsi_its_cam_ts_conversion REQUIRED)
|
||||||
ament_auto_find_build_dependencies()
|
ament_auto_find_build_dependencies()
|
||||||
|
@ -48,7 +48,7 @@ ament_auto_add_library(autoware_v2x SHARED
|
||||||
src/security.cpp
|
src/security.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(autoware_v2x Vanetza::vanetza ${GeographicLib_LIBRARIES} Boost::thread sqlite3 etsi_its_cam_ts_coding::etsi_its_cam_ts_coding etsi_its_cam_ts_conversion::etsi_its_cam_ts_conversion)
|
target_link_libraries(autoware_v2x Vanetza::vanetza ${GeographicLib_LIBRARIES} Boost::thread Boost::program_options sqlite3 etsi_its_cam_ts_coding::etsi_its_cam_ts_coding etsi_its_cam_ts_conversion::etsi_its_cam_ts_conversion)
|
||||||
|
|
||||||
rclcpp_components_register_node(autoware_v2x
|
rclcpp_components_register_node(autoware_v2x
|
||||||
PLUGIN "v2x::V2XNode"
|
PLUGIN "v2x::V2XNode"
|
||||||
|
|
|
@ -2,3 +2,8 @@
|
||||||
ros__parameters:
|
ros__parameters:
|
||||||
network_interface: "v2x_testing"
|
network_interface: "v2x_testing"
|
||||||
is_sender: true
|
is_sender: true
|
||||||
|
security: "none"
|
||||||
|
certificate: ""
|
||||||
|
certificate-key: ""
|
||||||
|
certificate-chain:
|
||||||
|
- ""
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
std::unique_ptr<vanetza::security::SecurityEntity>
|
std::unique_ptr<vanetza::security::SecurityEntity>
|
||||||
create_security_entity(const vanetza::Runtime&, vanetza::PositionProvider&);
|
create_security_entity(const boost::program_options::variables_map&, const vanetza::Runtime&, vanetza::PositionProvider&);
|
||||||
|
|
||||||
#endif /* SECURITY_HPP_FV13ZIYA */
|
#endif /* SECURITY_HPP_FV13ZIYA */
|
||||||
|
|
||||||
|
|
116
src/security.cpp
116
src/security.cpp
|
@ -1,13 +1,27 @@
|
||||||
|
/**
|
||||||
|
* From Vanetza (https://github.com/riebl/Vanetza)
|
||||||
|
* Using Security V3
|
||||||
|
*
|
||||||
|
* https://github.com/riebl/vanetza/tree/master/vanetza/security
|
||||||
|
* https://github.com/riebl/vanetza/tree/master/tools/socktap/security.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
#include "autoware_v2x/security.hpp"
|
#include "autoware_v2x/security.hpp"
|
||||||
#include <vanetza/security/certificate_cache.hpp>
|
|
||||||
#include <vanetza/security/default_certificate_validator.hpp>
|
#include <memory>
|
||||||
#include <vanetza/security/delegating_security_entity.hpp>
|
#include <vanetza/security/delegating_security_entity.hpp>
|
||||||
#include <vanetza/security/naive_certificate_provider.hpp>
|
#include <vanetza/security/straight_verify_service.hpp>
|
||||||
#include <vanetza/security/null_certificate_validator.hpp>
|
#include "vanetza/security/v2/certificate_provider.hpp"
|
||||||
#include <vanetza/security/persistence.hpp>
|
#include <vanetza/security/v2/certificate_cache.hpp>
|
||||||
#include <vanetza/security/sign_header_policy.hpp>
|
#include <vanetza/security/v2/default_certificate_validator.hpp>
|
||||||
#include <vanetza/security/static_certificate_provider.hpp>
|
#include <vanetza/security/v2/sign_service.hpp>
|
||||||
#include <vanetza/security/trust_store.hpp>
|
#include <vanetza/security/v3/certificate_cache.hpp>
|
||||||
|
#include <vanetza/security/v3/naive_certificate_provider.hpp>
|
||||||
|
#include <vanetza/security/v3/persistence.hpp>
|
||||||
|
#include <vanetza/security/v3/sign_header_policy.hpp>
|
||||||
|
#include <vanetza/security/v3/sign_service.hpp>
|
||||||
|
#include <vanetza/security/v3/static_certificate_provider.hpp>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace vanetza;
|
using namespace vanetza;
|
||||||
|
@ -16,18 +30,18 @@ namespace po = boost::program_options;
|
||||||
class SecurityContext : public security::SecurityEntity
|
class SecurityContext : public security::SecurityEntity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SecurityContext(const Runtime &runtime, PositionProvider &positioning) : runtime(runtime), positioning(positioning),
|
SecurityContext(const Runtime &runtime, PositionProvider &positioning)
|
||||||
|
: runtime(runtime),
|
||||||
|
positioning(positioning),
|
||||||
backend(security::create_backend("default")),
|
backend(security::create_backend("default")),
|
||||||
sign_header_policy(runtime, positioning),
|
sign_header_policy(runtime, positioning),
|
||||||
cert_cache(runtime),
|
cert_cache()
|
||||||
cert_validator(*backend, cert_cache, trust_store)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
security::EncapConfirm encapsulate_packet(security::EncapRequest &&request) override
|
security::EncapConfirm encapsulate_packet(security::EncapRequest &&request) override
|
||||||
{
|
{
|
||||||
if (!entity)
|
if (!entity) {
|
||||||
{
|
|
||||||
throw std::runtime_error("security entity is not ready");
|
throw std::runtime_error("security entity is not ready");
|
||||||
}
|
}
|
||||||
return entity->encapsulate_packet(std::move(request));
|
return entity->encapsulate_packet(std::move(request));
|
||||||
|
@ -35,8 +49,7 @@ public:
|
||||||
|
|
||||||
security::DecapConfirm decapsulate_packet(security::DecapRequest &&request) override
|
security::DecapConfirm decapsulate_packet(security::DecapRequest &&request) override
|
||||||
{
|
{
|
||||||
if (!entity)
|
if (!entity) {
|
||||||
{
|
|
||||||
throw std::runtime_error("security entity is not ready");
|
throw std::runtime_error("security entity is not ready");
|
||||||
}
|
}
|
||||||
return entity->decapsulate_packet(std::move(request));
|
return entity->decapsulate_packet(std::move(request));
|
||||||
|
@ -44,31 +57,78 @@ public:
|
||||||
|
|
||||||
void build_entity()
|
void build_entity()
|
||||||
{
|
{
|
||||||
if (!cert_provider)
|
if (!cert_provider) {
|
||||||
{
|
|
||||||
throw std::runtime_error("certificate provider is missing");
|
throw std::runtime_error("certificate provider is missing");
|
||||||
}
|
}
|
||||||
security::SignService sign_service = straight_sign_service(*cert_provider, *backend, sign_header_policy);
|
std::unique_ptr<security::SignService> sign_service{new security::v3::StraightSignService(*cert_provider, *backend, sign_header_policy)};
|
||||||
security::VerifyService verify_service = straight_verify_service(runtime, *cert_provider, cert_validator,
|
std::unique_ptr<security::StraightVerifyService> verify_service{new security::StraightVerifyService(runtime, *backend, positioning)};
|
||||||
*backend, cert_cache, sign_header_policy, positioning);
|
verify_service->use_certificate_cache(&cert_cache);
|
||||||
entity.reset(new security::DelegatingSecurityEntity{sign_service, verify_service});
|
entity = std::make_unique<security::DelegatingSecurityEntity>(std::move(sign_service), std::move(verify_service));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Runtime & runtime;
|
const Runtime & runtime;
|
||||||
PositionProvider & positioning;
|
PositionProvider & positioning;
|
||||||
std::unique_ptr<security::Backend> backend;
|
std::unique_ptr<security::Backend> backend;
|
||||||
std::unique_ptr<security::SecurityEntity> entity;
|
std::unique_ptr<security::SecurityEntity> entity;
|
||||||
std::unique_ptr<security::CertificateProvider> cert_provider;
|
std::unique_ptr<security::v3::CertificateProvider> cert_provider;
|
||||||
security::DefaultSignHeaderPolicy sign_header_policy;
|
security::v3::DefaultSignHeaderPolicy sign_header_policy;
|
||||||
security::TrustStore trust_store;
|
security::v3::CertificateCache cert_cache;
|
||||||
security::CertificateCache cert_cache;
|
|
||||||
security::DefaultCertificateValidator cert_validator;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<security::SecurityEntity>
|
std::unique_ptr<security::v3::CertificateProvider> load_certificates(
|
||||||
create_security_entity(const Runtime &runtime, PositionProvider &positioning)
|
const std::string &cert_path, const std::string &cert_key_path,
|
||||||
|
const std::vector<std::string> &cert_chain_path, security::v3::CertificateCache &cert_cache)
|
||||||
|
{
|
||||||
|
auto authorization_ticket = security::v3::load_certificate_from_file(cert_path);
|
||||||
|
auto authorization_ticket_key = security::v3::load_private_key_from_file(cert_key_path);
|
||||||
|
|
||||||
|
std::list<security::v3::Certificate> chain;
|
||||||
|
for (auto & chain_path : cert_chain_path) {
|
||||||
|
auto chain_certificate = security::v3::load_certificate_from_file(chain_path);
|
||||||
|
chain.push_back(chain_certificate);
|
||||||
|
cert_cache.store(chain_certificate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<security::v3::StaticCertificateProvider>(authorization_ticket, authorization_ticket_key.private_key, chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<security::SecurityEntity> create_security_entity(const po::variables_map &options, const Runtime &runtime, PositionProvider &positioning)
|
||||||
{
|
{
|
||||||
std::unique_ptr<security::SecurityEntity> security;
|
std::unique_ptr<security::SecurityEntity> security;
|
||||||
|
const std::string name = options["security"].as<std::string>();
|
||||||
|
|
||||||
|
if (name.empty() || name == "none") {
|
||||||
|
// no operation
|
||||||
|
} else if (name == "certs") {
|
||||||
|
if (options.count("certificate") ^ options.count("certificate-key")) {
|
||||||
|
throw std::runtime_error("Either certificate and certificate-key must be present or none.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.count("certificate") && options.count("certificate-key")) {
|
||||||
|
const auto &cert_path = options["certificate"].as<std::string>();
|
||||||
|
const auto &cert_key_path = options["certificate-key"].as<std::string>();
|
||||||
|
std::vector<std::string> chain_paths;
|
||||||
|
if (options.count("certificate-chain")) {
|
||||||
|
chain_paths = options["certificate-chain"].as<std::vector<std::string>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto context = std::make_unique<SecurityContext>(runtime, positioning);
|
||||||
|
context->cert_provider = load_certificates(cert_path, cert_key_path, chain_paths, context->cert_cache);
|
||||||
|
context->build_entity();
|
||||||
|
security = std::move(context);
|
||||||
|
} else {
|
||||||
|
auto context = std::make_unique<SecurityContext>(runtime, positioning);
|
||||||
|
context->cert_provider = std::make_unique<security::v3::NaiveCertificateProvider>(runtime);
|
||||||
|
context->build_entity();
|
||||||
|
security = std::move(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!security) {
|
||||||
|
throw std::runtime_error("internal failure setting up security entity");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Unknown security entity requested");
|
||||||
|
}
|
||||||
|
|
||||||
return security;
|
return security;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
namespace gn = vanetza::geonet;
|
namespace gn = vanetza::geonet;
|
||||||
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
using namespace vanetza;
|
using namespace vanetza;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
@ -160,7 +161,29 @@ namespace v2x
|
||||||
// Create raw socket on device and LinkLayer object
|
// Create raw socket on device and LinkLayer object
|
||||||
auto link_layer = create_link_layer(io_service, device, "ethernet");
|
auto link_layer = create_link_layer(io_service, device, "ethernet");
|
||||||
auto positioning = create_position_provider(io_service, trigger.runtime());
|
auto positioning = create_position_provider(io_service, trigger.runtime());
|
||||||
auto security = create_security_entity(trigger.runtime(), *positioning);
|
|
||||||
|
po::variables_map security_options;
|
||||||
|
std::string entity;
|
||||||
|
std::string certificate;
|
||||||
|
std::string certificate_key;
|
||||||
|
std::vector<std::string> certificate_chain;
|
||||||
|
// Grab the values from the node parameters
|
||||||
|
node_->get_parameter("security", entity);
|
||||||
|
security_options.insert(std::make_pair("security", po::variable_value(entity, false)));
|
||||||
|
if (node_->has_parameter("certificate")) {
|
||||||
|
node_->get_parameter("certificate", certificate);
|
||||||
|
security_options.insert(std::make_pair("certificate", po::variable_value(certificate, false)));
|
||||||
|
}
|
||||||
|
if (node_->has_parameter("certificate-key")) {
|
||||||
|
node_->get_parameter("certificate-key", certificate_key);
|
||||||
|
security_options.insert(std::make_pair("certificate-key", po::variable_value(certificate_key, false)));
|
||||||
|
}
|
||||||
|
if (node_->has_parameter("certificate-chain")) {
|
||||||
|
node_->get_parameter("certificate-chain", certificate_chain);
|
||||||
|
security_options.insert(std::make_pair("certificate-chain", po::variable_value(certificate_chain, false)));
|
||||||
|
}
|
||||||
|
auto security = create_security_entity(security_options, trigger.runtime(), *positioning);
|
||||||
|
|
||||||
RouterContext context(mib, trigger, *positioning, security.get());
|
RouterContext context(mib, trigger, *positioning, security.get());
|
||||||
|
|
||||||
context.set_link_layer(link_layer.get());
|
context.set_link_layer(link_layer.get());
|
||||||
|
|
|
@ -58,6 +58,7 @@ namespace v2x
|
||||||
// Declare Parameters
|
// Declare Parameters
|
||||||
this->declare_parameter<std::string>("network_interface", "v2x_testing");
|
this->declare_parameter<std::string>("network_interface", "v2x_testing");
|
||||||
this->declare_parameter<bool>("is_sender", true);
|
this->declare_parameter<bool>("is_sender", true);
|
||||||
|
this->declare_parameter<std::string>("security", "none");
|
||||||
|
|
||||||
// Launch V2XApp in a new thread
|
// Launch V2XApp in a new thread
|
||||||
app = new V2XApp(this);
|
app = new V2XApp(this);
|
||||||
|
|
Loading…
Reference in New Issue