Files
Ashin Walpola d107534eb2 Keep vanetza-idf in obu-firmware, so a plain clone builds the firmware
obu-firmware builds against the vanetza-idf C-ITS library, which until now
came from the colleague's microbu-esp32c5 tree beside the repository and was
not tracked here, so a clone of this repository could not build the firmware
it ships. The library alone is now part of obu-firmware, as
obu-firmware/external/vanetza-idf: their external/vanetza-idf at commit
cf4b99f, unchanged (9775 files; see its PROVENANCE.md). CMake takes it from
there by default; -DVANETZA_IDF_DIR still points the build elsewhere.

The rest of the colleague's tree (their own VAM firmware, PKI tooling,
station-link Python tools, the V2X2MAP bridge) stays out of this repository
and gitignored; nothing is pushed to their repository. NOTES.md, docs/06,
TODO.md and the pcap verifier's usage line point at the new location.
2026-09-24 10:56:05 +02:00

232 lines
6.1 KiB
C++

#include <vanetza/security/exception.hpp>
#include <vanetza/security/v2/certificate.hpp>
#include <vanetza/security/v2/length_coding.hpp>
#include <vanetza/security/v2/signer_info.hpp>
namespace vanetza
{
namespace security
{
namespace v2
{
SignerInfoType get_type(const SignerInfo& info)
{
struct SignerInfo_visitor : public boost::static_visitor<SignerInfoType>
{
SignerInfoType operator()(const std::nullptr_t)
{
return SignerInfoType::Self;
}
SignerInfoType operator()(const HashedId8&)
{
return SignerInfoType::Certificate_Digest_With_SHA256;
}
SignerInfoType operator()(const Certificate&)
{
return SignerInfoType::Certificate;
}
SignerInfoType operator()(const std::list<Certificate>&)
{
return SignerInfoType::Certificate_Chain;
}
SignerInfoType operator()(const CertificateDigestWithOtherAlgorithm&)
{
return SignerInfoType::Certificate_Digest_With_Other_Algorithm;
}
};
SignerInfo_visitor visit;
return boost::apply_visitor(visit, info);
}
size_t get_size(const CertificateDigestWithOtherAlgorithm& cert)
{
size_t size = cert.digest.size();
size += sizeof(cert.algorithm);
return size;
}
size_t get_size(const SignerInfo& info)
{
size_t size = sizeof(SignerInfoType);
struct SignerInfo_visitor : public boost::static_visitor<size_t>
{
size_t operator()(const std::nullptr_t&)
{
return 0;
}
size_t operator()(const HashedId8& id)
{
return id.size();
}
size_t operator()(const Certificate& cert)
{
return get_size(cert);
}
size_t operator()(const std::list<Certificate>& list)
{
size_t size = get_size(list);
size += length_coding_size(size);
return size;
}
size_t operator()(const CertificateDigestWithOtherAlgorithm& cert)
{
return get_size(cert);
}
};
SignerInfo_visitor visit;
size += boost::apply_visitor(visit, info);
return size;
}
void serialize(OutputArchive& ar, const CertificateDigestWithOtherAlgorithm& cert)
{
serialize(ar, cert.algorithm);
for (auto& byte : cert.digest) {
ar << byte;
}
}
void serialize(OutputArchive& ar, const SignerInfo& info)
{
struct SignerInfo_visitor : public boost::static_visitor<>
{
SignerInfo_visitor(OutputArchive& ar) :
m_archive(ar)
{
}
void operator()(const std::nullptr_t)
{
// intentionally do nothing
}
void operator()(const HashedId8& id)
{
for (auto& byte : id) {
m_archive << byte;
}
}
void operator()(const Certificate& cert)
{
serialize(m_archive, cert);
}
void operator()(const std::list<Certificate>& list)
{
serialize(m_archive, list);
}
void operator()(const CertificateDigestWithOtherAlgorithm& cert)
{
serialize(m_archive, cert);
}
OutputArchive& m_archive;
};
SignerInfoType type = get_type(info);
serialize(ar, type);
SignerInfo_visitor visit(ar);
boost::apply_visitor(visit, info);
}
size_t deserialize(InputArchive& ar, CertificateDigestWithOtherAlgorithm& cert)
{
deserialize(ar, cert.algorithm);
for (size_t c = 0; c < 8; c++) {
ar >> cert.digest[c];
}
size_t size = cert.digest.size();
size += sizeof(cert.algorithm);
return size;
}
size_t deserialize(InputArchive& ar, SignerInfo& info)
{
SignerInfoType type;
size_t size = 0;
deserialize(ar, type);
size += sizeof(SignerInfoType);
switch (type) {
case SignerInfoType::Certificate: {
Certificate cert;
size += deserialize(ar, cert);
info = cert;
break;
}
case SignerInfoType::Certificate_Chain: {
std::list<Certificate> list;
size += deserialize(ar, list);
size += length_coding_size(size);
info = list;
break;
}
case SignerInfoType::Certificate_Digest_With_SHA256: {
HashedId8 cert;
for (size_t c = 0; c < 8; c++) {
ar >> cert[c];
}
info = cert;
size += sizeof(cert);
break;
}
case SignerInfoType::Certificate_Digest_With_Other_Algorithm: {
CertificateDigestWithOtherAlgorithm cert;
size += deserialize(ar, cert);
info = cert;
break;
}
case SignerInfoType::Self:
info = nullptr;
break;
default:
throw deserialization_error("Unknown SignerInfoType");
break;
}
return size;
}
size_t deserialize_certificate_signer(InputArchive& ar, SignerInfo& info)
{
SignerInfoType type;
size_t size = 0;
deserialize(ar, type);
size += sizeof(SignerInfoType);
switch (type) {
case SignerInfoType::Certificate:
case SignerInfoType::Certificate_Chain:
// TS 103 097 v1.2.1 clause 6.1 forbids these signer info types for certificates
throw deserialization_error("Illegal SignerInfo for Certificate");
break;
case SignerInfoType::Certificate_Digest_With_SHA256: {
HashedId8 cert;
for (size_t c = 0; c < 8; c++) {
ar >> cert[c];
}
info = cert;
size += sizeof(cert);
break;
}
case SignerInfoType::Certificate_Digest_With_Other_Algorithm: {
CertificateDigestWithOtherAlgorithm cert;
size += deserialize(ar, cert);
info = cert;
break;
}
case SignerInfoType::Self:
info = nullptr;
break;
default:
throw deserialization_error("Unknown SignerInfoType");
break;
}
return size;
}
} // ns v2
} // ns security
} // ns vanetza