Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security V1.3.1 #130

Closed
wants to merge 11 commits into from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ build
conanfile.pyc
doxygen/html/
www/
.vscode/
2 changes: 1 addition & 1 deletion tools/socktap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,4 @@ int main(int argc, const char** argv)
}

return 0;
}
}
105 changes: 96 additions & 9 deletions tools/socktap/security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ class SecurityContext : public security::SecurityEntity
entity.reset(new security::DelegatingSecurityEntity { sign_service, verify_service });
}

void build_entity_v3()
{
if (!cert_provider) {
throw std::runtime_error("certificate provider is missing");
}
security::SignService sign_service = straight_sign_serviceV3(*cert_provider, *backend, sign_header_policy);
security::VerifyService verify_service = straight_verify_service(runtime, *cert_provider, cert_validator,
*backend, cert_cache, sign_header_policy, positioning);
entity.reset(new security::DelegatingSecurityEntity { sign_service, verify_service });
}

const Runtime& runtime;
PositionProvider& positioning;
std::unique_ptr<security::Backend> backend;
Expand All @@ -63,10 +74,8 @@ class SecurityContext : public security::SecurityEntity
security::DefaultCertificateValidator cert_validator;
};


std::unique_ptr<security::SecurityEntity>
create_security_entity(const po::variables_map& vm, const Runtime& runtime, PositionProvider& positioning)
{
create_security_entity_v2(const po::variables_map& vm, const Runtime& runtime, PositionProvider& positioning){
std::unique_ptr<security::SecurityEntity> security;
const std::string name = vm["security"].as<std::string>();

Expand All @@ -88,27 +97,29 @@ create_security_entity(const po::variables_map& vm, const Runtime& runtime, Posi
const std::string& certificate_path = vm["certificate"].as<std::string>();
const std::string& certificate_key_path = vm["certificate-key"].as<std::string>();

auto authorization_ticket = security::load_certificate_from_file(certificate_path);
security::CertificateVariant authorization_ticket = security::load_certificate_from_file(certificate_path);
auto authorization_ticket_key = security::load_private_key_from_file(certificate_key_path);

std::list<security::Certificate> chain;
std::list<security::CertificateVariant> chain;

if (vm.count("certificate-chain")) {
for (auto& chain_path : vm["certificate-chain"].as<std::vector<std::string> >()) {
auto chain_certificate = security::load_certificate_from_file(chain_path);
security::CertificateVariant chain_certificate = security::load_certificate_from_file(chain_path);
chain.push_back(chain_certificate);
context->cert_cache.insert(chain_certificate);

const security::Certificate& chain_certificate_ = boost::get<security::Certificate&>(chain_certificate);
// Only add root certificates to trust store, so certificate requests are visible for demo purposes.
if (chain_certificate.subject_info.subject_type == security::SubjectType::Root_CA) {
if (chain_certificate_.subject_info.subject_type == security::SubjectType::Root_CA) {
context->trust_store.insert(chain_certificate);
}
}
}

context->cert_provider.reset(new security::StaticCertificateProvider(authorization_ticket, authorization_ticket_key.private_key, chain));
} else {
context->cert_provider.reset(new security::NaiveCertificateProvider(runtime));
// context->cert_provider.reset(new security::NaiveCertificateProvider(runtime));
throw std::runtime_error("Naive not implemented for V1.3.1!");
}

if (vm.count("trusted-certificate")) {
Expand All @@ -127,14 +138,90 @@ create_security_entity(const po::variables_map& vm, const Runtime& runtime, Posi
return security;
}

std::unique_ptr<security::SecurityEntity>
create_security_entity_v3(const po::variables_map& vm, const Runtime& runtime, PositionProvider& positioning){
std::unique_ptr<security::SecurityEntity> security;
const std::string name = vm["security"].as<std::string>();

if (name.empty() || name == "none") {
// no operation
} else if (name == "dummy") {
security::SignService sign_service = security::dummy_sign_serviceV3(runtime, nullptr);
security::VerifyService verify_service = security::dummy_verify_service(
security::VerificationReport::Success, security::CertificateValidity::valid());
security.reset(new security::DelegatingSecurityEntity { sign_service, verify_service });
} else if (name == "certs") {
std::unique_ptr<SecurityContext> context { new SecurityContext(runtime, positioning) };

if (vm.count("certificate") ^ vm.count("certificate-key")) {
throw std::runtime_error("Either --certificate and --certificate-key must be present or none.");
}

if (vm.count("certificate") && vm.count("certificate-key")) {
const std::string& certificate_path = vm["certificate"].as<std::string>();
const std::string& certificate_key_path = vm["certificate-key"].as<std::string>();

security::CertificateVariant authorization_ticket = security::load_certificate_from_file_v3(certificate_path);
auto authorization_ticket_key = security::load_private_key_from_file_v3(certificate_key_path);

std::list<security::CertificateVariant> chain;

if (vm.count("certificate-chain")) {
for (auto& chain_path : vm["certificate-chain"].as<std::vector<std::string> >()) {
security::CertificateVariant chain_certificate = security::load_certificate_from_file_v3(chain_path);
chain.push_back(chain_certificate);
context->cert_cache.insert(chain_certificate);

// Only add root certificates to trust store, so certificate requests are visible for demo purposes.
// SUBJECT INFO HAS DISAPPEARED IN THE 3rd VERSION SO STILL THERE IS NO WAY TO FIND OUT
// if (chain_certificate.subject_info.subject_type == security::SubjectType::Root_CA) {
// context->trust_store.insert(chain_certificate);
// }
}
}

context->cert_provider.reset(new security::StaticCertificateProvider(authorization_ticket, authorization_ticket_key.private_key, chain));
} else {
// Not implemented yet
// context->cert_provider.reset(new security::NaiveCertificateProvider(runtime));
throw "Naive certificate provider is not implemented yet for the 3rd version!";
}

if (vm.count("trusted-certificate")) {
for (auto& cert_path : vm["trusted-certificate"].as<std::vector<std::string> >()) {
security::CertificateVariant trusted_certificate = security::load_certificate_from_file_v3(cert_path);
context->trust_store.insert(trusted_certificate);
}
}
context->build_entity_v3();
security = std::move(context);
} else {
throw std::runtime_error("Unknown security entity requested");
}
return security;
}

std::unique_ptr<security::SecurityEntity>
create_security_entity(const po::variables_map& vm, const Runtime& runtime, PositionProvider& positioning)
{
const int version = vm["security-version"].as<int>();
if(version==2){
return create_security_entity_v2(vm, runtime, positioning);
}else if(version ==3){
return create_security_entity_v3(vm, runtime, positioning);
}else{
throw std::runtime_error("Invalid Security Version");
}
}

void add_security_options(po::options_description& options)
{
options.add_options()
("security", po::value<std::string>()->default_value("dummy"), "Security entity [none,dummy,certs]")
("security-version", po::value<int>()->default_value(3), "Security version [2, 3]")
("certificate", po::value<std::string>(), "Certificate to use for secured messages.")
("certificate-key", po::value<std::string>(), "Certificate key to use for secured messages.")
("certificate-chain", po::value<std::vector<std::string> >()->multitoken(), "Certificate chain to use, use as often as needed.")
("trusted-certificate", po::value<std::vector<std::string> >()->multitoken(), "Trusted certificate, use as often as needed. Root certificates in the chain are automatically trusted.")
;
}

4 changes: 2 additions & 2 deletions vanetza/asn1/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ add_asn1_component(its)
add_asn1_component(security)
add_asn1_component(pki)

add_vanetza_component(asn1 asn1c_wrapper.cpp)
target_link_libraries(asn1 PUBLIC asn1_its Boost::boost)
add_vanetza_component(asn1 asn1c_wrapper.cpp utils.cpp)
target_link_libraries(asn1 PUBLIC asn1_its asn1_security Boost::boost)

add_test_subdirectory(tests)
24 changes: 24 additions & 0 deletions vanetza/asn1/etsi_certificate.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef EtsiTs103097Certificate_HPP_WXYNEKFN
#define EtsiTs103097Certificate_HPP_WXYNEKFN

#include <vanetza/asn1/asn1c_conversion.hpp>
#include <vanetza/asn1/asn1c_wrapper.hpp>
#include <vanetza/asn1/security/EtsiTs103097Certificate.h>


namespace vanetza
{
namespace asn1
{

class EtsiTs103097Certificate : public asn1c_oer_wrapper<EtsiTs103097Certificate_t>
{
public:
using wrapper = asn1c_oer_wrapper<EtsiTs103097Certificate_t>;
EtsiTs103097Certificate() : wrapper(asn_DEF_EtsiTs103097Certificate) {}
};

} // namespace asn1
} // namespace vanetza

#endif /* EtsiTs103097Certificate_HPP_WXYNEKFN */
24 changes: 24 additions & 0 deletions vanetza/asn1/etsi_secured_data.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef EtsiTs103097Data_HPP_WXYNEKFN
#define EtsiTs103097Data_HPP_WXYNEKFN

#include <vanetza/asn1/asn1c_conversion.hpp>
#include <vanetza/asn1/asn1c_wrapper.hpp>
#include <vanetza/asn1/security/EtsiTs103097Data.h>


namespace vanetza
{
namespace asn1
{

class EtsiTs103097Data : public asn1c_oer_wrapper<EtsiTs103097Data_t>
{
public:
using wrapper = asn1c_oer_wrapper<EtsiTs103097Data_t>;
EtsiTs103097Data() : wrapper(asn_DEF_EtsiTs103097Data) {}
};

} // namespace asn1
} // namespace vanetza

#endif /* EtsiTs103097Data_HPP_WXYNEKFN */
24 changes: 24 additions & 0 deletions vanetza/asn1/ieee1609dot2_certificate.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef Ieee1609Dot2Certificate_HPP_WXYNEKFN
#define Ieee1609Dot2Certificate_HPP_WXYNEKFN

#include <vanetza/asn1/asn1c_conversion.hpp>
#include <vanetza/asn1/asn1c_wrapper.hpp>
#include <vanetza/asn1/security/Certificate.h>


namespace vanetza
{
namespace asn1
{

class Ieee1609Dot2Certificate : public asn1c_oer_wrapper<Certificate_t>
{
public:
using wrapper = asn1c_oer_wrapper<Certificate_t>;
Ieee1609Dot2Certificate() : wrapper(asn_DEF_Certificate) {}
};

} // namespace asn1
} // namespace vanetza

#endif /* Ieee1609Dot2Certificate_HPP_WXYNEKFN */
120 changes: 120 additions & 0 deletions vanetza/asn1/utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#include <vanetza/asn1/utils.hpp>


namespace vanetza
{
namespace asn1
{
void convert_bytebuffer_to_octet_string(OCTET_STRING_t* octet, const vanetza::ByteBuffer& buffer)
{
OCTET_STRING_fromBuf(
octet,
reinterpret_cast<const char *>(buffer.data()),
buffer.size()
);
}

vanetza::security::EccPoint EccP256CurvePoint_to_EccPoint(const EccP256CurvePoint_t& curve_point){
vanetza::security::EccPoint to_return;
switch(curve_point.present){
case EccP256CurvePoint_PR_x_only:
to_return = vanetza::security::X_Coordinate_Only{
.x=OCTET_STRING_to_ByteBuffer(curve_point.choice.x_only)
};
break;
case EccP256CurvePoint_PR_compressed_y_0:
to_return = vanetza::security::Compressed_Lsb_Y_0{
.x=OCTET_STRING_to_ByteBuffer(curve_point.choice.compressed_y_0)
};
break;
case EccP256CurvePoint_PR_compressed_y_1:
to_return = vanetza::security::Compressed_Lsb_Y_1{
.x=OCTET_STRING_to_ByteBuffer(curve_point.choice.compressed_y_1)
};
break;
case EccP256CurvePoint_PR_uncompressedP256:
to_return = vanetza::security::Uncompressed{
.x=OCTET_STRING_to_ByteBuffer(curve_point.choice.uncompressedP256.x),
.y=OCTET_STRING_to_ByteBuffer(curve_point.choice.uncompressedP256.y)};
break;
}
return to_return;
}

vanetza::security::GeographicRegion GeographicRegionAsn_to_GeographicRegion(const GeographicRegion_t& region){
vanetza::security::GeographicRegion to_return = vanetza::security::NoneRegion();
std::list<vanetza::security::RectangularRegion> to_return_list;
vanetza::security::PolygonalRegion polygon;
switch(region.present){
case GeographicRegion_PR_circularRegion:
to_return = vanetza::security::CircularRegion(
TwoDLocationAsn_to_TwoDLocation(
region.choice.circularRegion.center
),
geonet::distance_u16t::from_value(region.choice.circularRegion.radius)
);
break;
case GeographicRegion_PR_rectangularRegion:
for (int i=0; i<region.choice.rectangularRegion.list.count; i++){
to_return_list.push_back(
vanetza::security::RectangularRegion{
.northwest = TwoDLocationAsn_to_TwoDLocation(
region.choice.rectangularRegion.list.array[i]->northWest
),
.southeast = TwoDLocationAsn_to_TwoDLocation(
region.choice.rectangularRegion.list.array[i]->southEast)
}
);
}
to_return = to_return_list;
break;
case GeographicRegion_PR_polygonalRegion:
for (int i=0; i<region.choice.polygonalRegion.list.count; i++){
polygon.push_back(
TwoDLocationAsn_to_TwoDLocation(
*region.choice.polygonalRegion.list.array[i]
)
);
}
to_return = polygon;
break;
case GeographicRegion_PR_identifiedRegion:
// TODO: There is no reason for retrocompatibility whilst the region identification is not programmed
break;
}
return to_return;
}

vanetza::security::TwoDLocation TwoDLocationAsn_to_TwoDLocation(const TwoDLocation_t& location){
vanetza::security::TwoDLocation to_return = vanetza::security::TwoDLocation(vanetza::units::GeoAngle((location.latitude/10000000)*boost::units::degree::degrees),
vanetza::units::GeoAngle((location.latitude/10000000)*boost::units::degree::degrees));
return to_return;
}


vanetza::ByteBuffer OCTET_STRING_to_ByteBuffer(const OCTET_STRING_t& octet){
return ByteBuffer(octet.buf, octet.buf+octet.size);
}

vanetza::security::HashedId8 HashedId8_asn_to_HashedId8(const HashedId8_t& hashed){
vanetza::security::HashedId8 to_return = vanetza::security::HashedId8{0,0,0,0,0,0,0,0};
if (hashed.size == 8){
for(int i =0; i<hashed.size; i++){
to_return[i] = hashed.buf[i];
}
}
return to_return;
}

vanetza::security::HashedId3 HashedId3_asn_to_HashedId3(const HashedId3_t& hashed){
vanetza::security::HashedId3 to_return = vanetza::security::HashedId3{0,0,0};
if (hashed.size == 3){
for(int i =0; i<hashed.size; i++){
to_return[i] = hashed.buf[i];
}
}
return to_return;
}

}
}
Loading