Skip to content

Commit

Permalink
First integration security V3 sending
Browse files Browse the repository at this point in the history
  • Loading branch information
Romain Tessier committed Jul 1, 2024
1 parent 4d5f164 commit db35abd
Show file tree
Hide file tree
Showing 19 changed files with 1,685 additions and 28 deletions.
53 changes: 25 additions & 28 deletions tools/socktap/security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
#include <vanetza/security/delegating_security_entity.hpp>
#include <vanetza/security/straight_verify_service.hpp>
#include <vanetza/security/v2/certificate_cache.hpp>
#include <vanetza/security/v3/certificate_cache.hpp>
#include <vanetza/security/v2/default_certificate_validator.hpp>
#include <vanetza/security/v2/naive_certificate_provider.hpp>
#include <vanetza/security/v2/null_certificate_validator.hpp>

#include <vanetza/security/v3/naive_certificate_provider.hpp>
#include <vanetza/security/v3/static_certificate_provider.hpp>
#include <vanetza/security/v2/persistence.hpp>
#include <vanetza/security/v2/sign_header_policy.hpp>
#include <vanetza/security/v3/persistence.hpp>
#include <vanetza/security/v3/sign_header_policy.hpp>
#include <vanetza/security/v2/sign_service.hpp>
#include <vanetza/security/v2/static_certificate_provider.hpp>

#include <vanetza/security/v2/trust_store.hpp>
#include <vanetza/security/v3/sign_service.hpp>
#include <stdexcept>
#include <iostream>

using namespace vanetza;
namespace po = boost::program_options;
Expand All @@ -22,8 +27,8 @@ class SecurityContext : public security::SecurityEntity
runtime(runtime), positioning(positioning),
backend(security::create_backend("default")),
sign_header_policy(runtime, positioning),
cert_cache(runtime),
cert_validator(*backend, cert_cache, trust_store)
cert_cache()
//cert_validator(*backend, cert_cache, trust_store)
{
}

Expand All @@ -49,25 +54,22 @@ class SecurityContext : public security::SecurityEntity
throw std::runtime_error("certificate provider is missing");
}
std::unique_ptr<security::SignService> sign_service { new
security::v2::StraightSignService(*cert_provider, *backend, sign_header_policy) };
security::v3::StraightSignService(*cert_provider, *backend, sign_header_policy) };
std::unique_ptr<security::StraightVerifyService> verify_service { new
security::StraightVerifyService(runtime, *backend, positioning) };
verify_service->use_certificate_provider(cert_provider.get());
verify_service->use_certificate_cache(&cert_cache);
verify_service->use_certitifcate_validator(&cert_validator);
verify_service->use_sign_header_policy(&sign_header_policy);
entity.reset(new security::DelegatingSecurityEntity { std::move(sign_service), std::move(verify_service) });
}

const Runtime& runtime;
PositionProvider& positioning;
std::unique_ptr<security::Backend> backend;
std::unique_ptr<security::SecurityEntity> entity;
std::unique_ptr<security::v2::CertificateProvider> cert_provider;
security::v2::DefaultSignHeaderPolicy sign_header_policy;
std::unique_ptr<security::v3::CertificateProvider> cert_provider;
security::v3::DefaultSignHeaderPolicy sign_header_policy;
security::v2::TrustStore trust_store;
security::v2::CertificateCache cert_cache;
security::v2::DefaultCertificateValidator cert_validator;
security::v3::CertificateCache cert_cache;
//security::v2::DefaultCertificateValidator cert_validator;
};


Expand All @@ -81,7 +83,7 @@ create_security_entity(const po::variables_map& vm, const Runtime& runtime, Posi
// no operation
} else if (name == "dummy") {
std::unique_ptr<security::SignService> sign_service { new
security::v2::DummySignService { runtime, nullptr } };
vanetza::security::v3::DummySignService { runtime, nullptr } };
std::unique_ptr<security::VerifyService> verify_service { new
security::DummyVerifyService {
security::VerificationReport::Success, security::CertificateValidity::valid() } };
Expand All @@ -97,27 +99,22 @@ 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::v2::load_certificate_from_file(certificate_path);
auto authorization_ticket_key = security::v2::load_private_key_from_file(certificate_key_path);

std::list<security::v2::Certificate> chain;
auto authorization_ticket = security::v3::load_certificate_from_file(certificate_path);
auto authorization_ticket_key = security::v3::load_private_key_from_file(certificate_key_path);
std::list<security::v3::Certificate> chain;

if (vm.count("certificate-chain")) {
for (auto& chain_path : vm["certificate-chain"].as<std::vector<std::string> >()) {
auto chain_certificate = security::v2::load_certificate_from_file(chain_path);
auto chain_certificate = security::v3::load_certificate_from_file(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.
if (chain_certificate.subject_info.subject_type == security::v2::SubjectType::Root_CA) {
context->trust_store.insert(chain_certificate);
}
context->cert_cache.store(chain_certificate);
}
}

context->cert_provider.reset(new security::v2::StaticCertificateProvider(authorization_ticket, authorization_ticket_key.private_key, chain));
context->cert_provider.reset(new security::v3::StaticCertificateProvider(authorization_ticket, authorization_ticket_key.private_key, chain));
} else {
context->cert_provider.reset(new security::v2::NaiveCertificateProvider(runtime));
context->cert_provider.reset(new security::v3::NaiveCertificateProvider(runtime));
}

if (vm.count("trusted-certificate")) {
Expand Down
6 changes: 6 additions & 0 deletions vanetza/security/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ add_vanetza_component(security
v3/certificate.cpp
v3/certificate_cache.cpp
v3/secured_message.cpp
v3/sign_service.cpp
v3/signer_info.cpp
v3/naive_certificate_provider.cpp
v3/sign_header_policy.cpp
v3/static_certificate_provider.cpp
v3/persistence.cpp
)
target_link_libraries(security PUBLIC asn1 asn1_security common net)
target_link_libraries(security PRIVATE GeographicLib::GeographicLib)
Expand Down
188 changes: 188 additions & 0 deletions vanetza/security/v3/certificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,194 @@ ByteBuffer get_app_permissions(const EtsiTs103097Certificate_t& cert, ItsAid aid
return perms;
}

void add_psid_group_permission(PsidGroupPermissions* group_permission, ItsAid aid, const ByteBuffer& ssp, const ByteBuffer& bitmask){
PsidSspRange* psid_range_scr = static_cast<PsidSspRange*>(vanetza::asn1::allocate(sizeof(PsidSspRange)));
psid_range_scr->psid = aid;
psid_range_scr->sspRange = static_cast<SspRange*>(vanetza::asn1::allocate(sizeof(SspRange)));
psid_range_scr->sspRange->present = SspRange_PR_bitmapSspRange;
OCTET_STRING_fromBuf(
&psid_range_scr->sspRange->choice.bitmapSspRange.sspValue,
reinterpret_cast<const char*>(ssp.data()),
ssp.size()
);
OCTET_STRING_fromBuf(
&psid_range_scr->sspRange->choice.bitmapSspRange.sspBitmask,
reinterpret_cast<const char*>(bitmask.data()),
bitmask.size()
);
ASN_SEQUENCE_ADD(&group_permission->subjectPermissions.choice.Explicit, psid_range_scr);
}

void add_app_permissions(Certificate& cert, ItsAid aid) {
SequenceOfPsidSsp_t* seq = cert->toBeSigned.appPermissions;
if (!seq) {
seq = static_cast<SequenceOfPsidSsp_t*>(vanetza::asn1::allocate(sizeof(SequenceOfPsidSsp_t)));
cert->toBeSigned.appPermissions = seq;
}
// Allocate the memory
PsidSsp* psid_ptr = static_cast<PsidSsp*>(vanetza::asn1::allocate(sizeof(PsidSsp)));
psid_ptr->psid = aid;
ASN_SEQUENCE_ADD(seq, psid_ptr);
}

void Certificate::add_permission(ItsAid aid, const ByteBuffer& ssp){
SequenceOfPsidSsp_t* seq = m_struct->toBeSigned.appPermissions;
if (!seq) {
seq = static_cast<SequenceOfPsidSsp_t*>(vanetza::asn1::allocate(sizeof(SequenceOfPsidSsp_t)));
m_struct->toBeSigned.appPermissions = seq;
}
// Allocate the memory
PsidSsp* psid_ptr = static_cast<PsidSsp*>(vanetza::asn1::allocate(sizeof(PsidSsp)));
psid_ptr->psid = aid;
psid_ptr->ssp = static_cast<ServiceSpecificPermissions*>(vanetza::asn1::allocate(sizeof(ServiceSpecificPermissions)));
psid_ptr->ssp->present = ServiceSpecificPermissions_PR_opaque;
OCTET_STRING_fromBuf(
&(psid_ptr->ssp->choice.opaque),
reinterpret_cast<const char *>(ssp.data()),
ssp.size()
);
ASN_SEQUENCE_ADD(seq, psid_ptr);

}

void Certificate::add_cert_permission(PsidGroupPermissions* group_permission){
SequenceOfPsidGroupPermissions* seq = m_struct->toBeSigned.certIssuePermissions;
if (!seq) {
seq = static_cast<SequenceOfPsidGroupPermissions*>(vanetza::asn1::allocate(sizeof(SequenceOfPsidGroupPermissions)));
m_struct->toBeSigned.certIssuePermissions = seq;
}
ASN_SEQUENCE_ADD(seq, group_permission);
}

void Certificate::set_signature(const SomeEcdsaSignature& signature) {
struct ecc_point_visitor : public boost::static_visitor<EccP256CurvePoint_t> {
EccP256CurvePoint_t operator()(const X_Coordinate_Only& x_only) const
{
EccP256CurvePoint_t* to_return = static_cast<EccP256CurvePoint_t*>(vanetza::asn1::allocate(sizeof(EccP256CurvePoint_t)));
to_return->present = EccP256CurvePoint_PR_x_only;
OCTET_STRING_fromBuf(
&(to_return->choice.x_only),
reinterpret_cast<const char*>(x_only.x.data()),
x_only.x.size()
);
return *to_return;
}
EccP256CurvePoint_t operator()(const Compressed_Lsb_Y_0& y0) const
{
EccP256CurvePoint_t* to_return = static_cast<EccP256CurvePoint_t*>(vanetza::asn1::allocate(sizeof(EccP256CurvePoint_t)));
to_return->present = EccP256CurvePoint_PR_compressed_y_0;
OCTET_STRING_fromBuf(
&(to_return->choice.compressed_y_0),
reinterpret_cast<const char*>(y0.x.data()),
y0.x.size()
);
return *to_return;
}
EccP256CurvePoint_t operator()(const Compressed_Lsb_Y_1& y1) const
{
EccP256CurvePoint_t* to_return = static_cast<EccP256CurvePoint_t*>(vanetza::asn1::allocate(sizeof(EccP256CurvePoint_t)));
to_return->present = EccP256CurvePoint_PR_compressed_y_1;
OCTET_STRING_fromBuf(
&(to_return->choice.compressed_y_1),
reinterpret_cast<const char*>(y1.x.data()),
y1.x.size()
);
return *to_return;
}
EccP256CurvePoint_t operator()(const Uncompressed& unc) const
{
EccP256CurvePoint_t* to_return = static_cast<EccP256CurvePoint_t*>(vanetza::asn1::allocate(sizeof(EccP256CurvePoint_t)));
to_return->present = EccP256CurvePoint_PR_uncompressedP256;
OCTET_STRING_fromBuf(
&(to_return->choice.uncompressedP256.x),
reinterpret_cast<const char*>(unc.x.data()),
unc.x.size()
);
OCTET_STRING_fromBuf(
&(to_return->choice.uncompressedP256.y),
reinterpret_cast<const char*>(unc.y.data()),
unc.y.size()
);
return *to_return;
}
};
struct signature_visitor : public boost::static_visitor<Signature_t*>
{
Signature_t* operator()(const EcdsaSignature& signature) const
{
Signature_t* final_signature = static_cast<Signature_t*>(vanetza::asn1::allocate(sizeof(Signature_t)));
final_signature->present = Signature_PR_ecdsaNistP256Signature;
OCTET_STRING_fromBuf(
&(final_signature->choice.ecdsaNistP256Signature.sSig),
reinterpret_cast<const char*>(signature.s.data()),
signature.s.size()
);
final_signature->choice.ecdsaNistP256Signature.rSig = boost::apply_visitor(
ecc_point_visitor(),
signature.R
);
return final_signature;
}
Signature_t* operator()(const EcdsaSignatureFuture& signature) const
{
Signature_t* final_signature = static_cast<Signature_t*>(vanetza::asn1::allocate(sizeof(Signature_t)));
/* EcdsaSignature temp = signature.get();
final_signature = boost::apply_visitor(signature_visitor(), temp); */
return final_signature;
}
};
m_struct->signature = (boost::apply_visitor(signature_visitor(), signature));
}

ByteBuffer Certificate::serialize() {
return this->encode();
}

ByteBuffer Certificate::convert_for_signing(){
vanetza::ByteBuffer to_return;
try{
to_return = vanetza::asn1::encode_oer(asn_DEF_EtsiTs103097Certificate, m_struct);
}catch(std::runtime_error& er){
}
return to_return;
}

Certificate fake_certificate() {

Certificate certi;
certi->issuer.present = IssuerIdentifier_PR_self;
certi->toBeSigned.id.present = CertificateId_PR_none;
std::vector<uint8_t> craciId(3, 0); // Correct length for P256 signature part
OCTET_STRING_fromBuf(
&certi->toBeSigned.cracaId,
reinterpret_cast<const char*>(craciId.data()),
craciId.size()
);
certi->version = 3;
certi->toBeSigned.crlSeries = 0;
certi->toBeSigned.validityPeriod.start = 0;
certi->toBeSigned.validityPeriod.duration.present = Duration_PR_minutes;
certi->toBeSigned.validityPeriod.duration.choice.minutes = 10080;
certi->toBeSigned.verifyKeyIndicator.present = VerificationKeyIndicator_PR_verificationKey;
certi->toBeSigned.verifyKeyIndicator.choice.verificationKey.present = PublicVerificationKey_PR_ecdsaNistP256;
certi->toBeSigned.verifyKeyIndicator.choice.verificationKey.choice.ecdsaNistP256.present = EccP256CurvePoint_PR_x_only;
std::vector<uint8_t> dummy_r(32, 0); // Correct length for P256 signature part
dummy_r[0] = 0; // Ensure the leading byte is set to zero if needed
OCTET_STRING_fromBuf(
&certi->toBeSigned.verifyKeyIndicator.choice.verificationKey.choice.ecdsaNistP256.choice.x_only,
reinterpret_cast<const char*>(dummy_r.data()),
dummy_r.size()
);
certi.add_permission(aid::CA, ByteBuffer({ 1, 0, 0 }));
return certi;
}

void serialize(OutputArchive& ar, Certificate& certificate) {
vanetza::ByteBuffer buffer = certificate.serialize();
for (auto& temp_byte : buffer){
ar << temp_byte;
}
}
namespace
{

Expand Down
19 changes: 19 additions & 0 deletions vanetza/security/v3/certificate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include <vanetza/security/hashed_id.hpp>
#include <vanetza/security/public_key.hpp>
#include <boost/optional/optional_fwd.hpp>
#include <vanetza/net/packet_variant.hpp>
#include <vanetza/security/signature.hpp>
#include <fstream>

namespace vanetza
{
Expand All @@ -16,6 +19,16 @@ namespace v3
struct Certificate : public asn1::asn1c_oer_wrapper<EtsiTs103097Certificate_t>
{
Certificate();

void add_permission(ItsAid aid, const ByteBuffer& ssp);

void add_cert_permission(PsidGroupPermissions* group_permission);

void set_signature(const SomeEcdsaSignature& signature);

ByteBuffer serialize();

ByteBuffer convert_for_signing();
};

/**
Expand All @@ -40,6 +53,12 @@ boost::optional<PublicKey> get_public_key(const EtsiTs103097Certificate_t& cert)
*/
ByteBuffer get_app_permissions(const EtsiTs103097Certificate_t& cert, ItsAid aid);

void add_psid_group_permission(PsidGroupPermissions* group_permission, ItsAid aid, const ByteBuffer& ssp, const ByteBuffer& bitmask);

void serialize(OutputArchive& ar, Certificate& certificate);

Certificate fake_certificate();

} // namespace v3
} // namespace security
} // namespace vanetza
Loading

0 comments on commit db35abd

Please sign in to comment.