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 2.1.1 - Tx and RX #230

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading