Files
MicrOBU/microbu-esp32c5/external/vanetza-idf/vanetza/security/v2/signer_info.cpp
T
Ashin Walpola 0e9525162d Keep the colleague's microbu-esp32c5 tree in this repository
obu-firmware builds against vanetza-idf from microbu-esp32c5/external, but
that tree was gitignored, so a clone of this repository could not build the
firmware it ships. It is now committed here as ordinary files in its own
folder, microbu-esp32c5/: the colleague's commit cf4b99f plus the V2X2MAP
bridge's signature verification (--trust) used on the bench. Nothing is
fetched from or pushed to the colleague's repository; this repository and
its remotes carry everything. The folder's own .gitignore keeps build output,
downloaded components and private key material out, as it did there; the
committed file set is identical to that repository's tracked files.

The ESP32-C5 is still flashed from obu-firmware/, which only takes
vanetza-idf from microbu-esp32c5/, so the two stay separate folders.
FLASHING.md says how to take a newer version of the colleague's tree (copy
it over the folder, rebuild, test, commit).
2026-09-23 17:46:40 +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