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;
}
}
107 changes: 98 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,92 @@ 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);
}
}
std::cout << "Ending the process of creating the security entity" << std::endl;
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){
std::cout << "Creating security entity V3" << std::endl;
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.")
;
}

2 changes: 1 addition & 1 deletion vanetza/asn1/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,6 @@ add_asn1_component(security)
add_asn1_component(pki)

add_vanetza_component(asn1 asn1c_wrapper.cpp)
target_link_libraries(asn1 PUBLIC asn1_its Boost::boost)
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 */
6 changes: 6 additions & 0 deletions vanetza/common/archives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ InputArchive::InputArchive(StreamBuffer& buf) :
{
}

std::size_t InputArchive::get_available()
{
return m_stream_buffer->in_avail();
}


void InputArchive::load_binary(unsigned char* data, std::size_t len)
{
load_binary(reinterpret_cast<char*>(data), len);
Expand Down
2 changes: 2 additions & 0 deletions vanetza/common/archives.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class InputArchive
return *this;
}

size_t get_available();
JordiMarias marked this conversation as resolved.
Show resolved Hide resolved

void load_binary(unsigned char* data, std::size_t len);
void load_binary(char* data, std::size_t len);

Expand Down
4 changes: 2 additions & 2 deletions vanetza/geonet/extended_pdu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ template<class HEADER>
class ExtendedPdu : public Pdu
{
public:
using SecuredMessage = security::SecuredMessage;
using SecuredMessage = security::SecuredMessageVariant;
using ExtendedHeader = HEADER;

ExtendedPdu() = default;
Expand Down Expand Up @@ -72,7 +72,7 @@ template<class HEADER>
class ExtendedPduConstRefs : public ConstAccessiblePdu
{
public:
using SecuredMessage = security::SecuredMessage;
using SecuredMessage = security::SecuredMessageVariant;
using ExtendedHeader = HEADER;

ExtendedPduConstRefs(const BasicHeader& basic, const CommonHeader& common, const HEADER& extended) :
Expand Down
2 changes: 1 addition & 1 deletion vanetza/geonet/indication_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class IndicationContext
{
public:
using UpPacketPtr = std::unique_ptr<UpPacket>;
using SecuredMessage = security::SecuredMessageV2;
using SecuredMessage = security::SecuredMessageVariant;
using LinkLayer = geonet::LinkLayer;

// parser commands
Expand Down
9 changes: 8 additions & 1 deletion vanetza/geonet/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,20 @@ std::size_t Parser::parse_common(CommonHeader& common)
return bytes;
}

std::size_t Parser::parse_secured(security::SecuredMessageV2& secured)
std::size_t Parser::parse_secured(security::SecuredMessageVariant& secured)
{
std::size_t bytes = 0;
try {
secured = security::SecuredMessageV3();
bytes = deserialize(m_archive, secured);
} catch (InputArchive::Exception&) {
} catch (security::deserialization_error&) {
try{
JordiMarias marked this conversation as resolved.
Show resolved Hide resolved
secured = security::SecuredMessageV2();
bytes = deserialize(m_archive, secured);
}catch (InputArchive::Exception&) {
} catch (security::deserialization_error&) {
}
}

m_read_bytes += bytes;
Expand Down
5 changes: 2 additions & 3 deletions vanetza/geonet/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
#include <vanetza/common/byte_buffer_source.hpp>
#include <vanetza/geonet/header_type.hpp>
#include <vanetza/geonet/header_variant.hpp>
#include <vanetza/security/secured_message.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/range/iterator_range.hpp>
#include <cstdint>

namespace vanetza
{

// forward declaration
namespace security { struct SecuredMessageV2; }

namespace geonet
{
Expand All @@ -30,7 +29,7 @@ class Parser

std::size_t parse_basic(BasicHeader&);
std::size_t parse_common(CommonHeader&);
std::size_t parse_secured(security::SecuredMessageV2&);
std::size_t parse_secured(security::SecuredMessageVariant&);
std::size_t parse_extended(HeaderVariant&, HeaderType);
std::size_t parsed_bytes() const;

Expand Down
5 changes: 2 additions & 3 deletions vanetza/geonet/pdu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@

#include <vanetza/geonet/header_variant.hpp>
#include <vanetza/geonet/serialization.hpp>
#include <vanetza/security/secured_message.hpp>
#include <cstddef>
#include <memory>

namespace vanetza
{
// forward declarations
namespace security { struct SecuredMessageV2; }

namespace geonet
{
Expand All @@ -22,7 +21,7 @@ class Pdu;
class ConstAccessiblePdu
{
public:
using SecuredMessage = security::SecuredMessageV2;
using SecuredMessage = security::SecuredMessageVariant;

virtual const BasicHeader& basic() const = 0;
virtual const CommonHeader& common() const = 0;
Expand Down
1 change: 1 addition & 0 deletions vanetza/geonet/router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ void Router::set_security_entity(security::SecurityEntity* entity)
m_security_entity = entity;
}


void Router::set_access_interface(dcc::RequestInterface* ifc)
{
m_request_interface = (ifc == nullptr ? get_default_request_interface() : ifc);
Expand Down
2 changes: 1 addition & 1 deletion vanetza/geonet/tests/router_request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ TEST_F(RouterRequest, router_request)
// check if packet has secured part
EXPECT_EQ(NextHeaderBasic::Secured, pdu->basic().next_header);
EXPECT_TRUE(pdu_ext->secured());
auto secured = *pdu_ext->secured();
auto secured = boost::get<security::SecuredMessageV2>(*pdu_ext->secured());

// check payload of packet
EXPECT_EQ(security::PayloadType::Signed, secured.payload.type);
Expand Down
Loading