Files
MicrOBU/microbu-esp32c5/external/vanetza-idf/vanetza/security/v2/naive_certificate_provider.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

239 lines
8.5 KiB
C++

#include <vanetza/common/its_aid.hpp>
//#include <vanetza/security/v2/basic_elements.hpp>
//#include <vanetza/security/v2/ecc_point.hpp>
#include <vanetza/security/v2/naive_certificate_provider.hpp>
//#include <vanetza/security/v2/payload.hpp>
//#include <vanetza/security/v2/secured_message.hpp>
//#include <vanetza/security/v2/signature.hpp>
namespace vanetza
{
namespace security
{
namespace v2
{
NaiveCertificateProvider::NaiveCertificateProvider(const Runtime& rt) :
m_crypto_backend(create_backend("default")),
m_runtime(rt),
m_own_key_pair(m_crypto_backend->generate_key_pair()),
m_own_certificate(generate_authorization_ticket()) { }
const Certificate& NaiveCertificateProvider::own_certificate()
{
// renew certificate if necessary
for (auto& validity_restriction : m_own_certificate.validity_restriction) {
auto start_and_end = boost::get<StartAndEndValidity>(&validity_restriction);
auto renewal_deadline = convert_time32(m_runtime.now() + std::chrono::hours(1));
if (start_and_end && start_and_end->end_validity < renewal_deadline) {
m_own_certificate = generate_authorization_ticket();
break;
}
}
return m_own_certificate;
}
std::list<Certificate> NaiveCertificateProvider::own_chain()
{
static const std::list<Certificate> chain = { aa_certificate() };
return chain;
}
const ecdsa256::PrivateKey& NaiveCertificateProvider::own_private_key()
{
return m_own_key_pair.private_key;
}
const ecdsa256::KeyPair& NaiveCertificateProvider::aa_key_pair()
{
static const ecdsa256::KeyPair aa_key_pair = m_crypto_backend->generate_key_pair();
return aa_key_pair;
}
const ecdsa256::KeyPair& NaiveCertificateProvider::root_key_pair()
{
static const ecdsa256::KeyPair root_key_pair = m_crypto_backend->generate_key_pair();
return root_key_pair;
}
const Certificate& NaiveCertificateProvider::aa_certificate()
{
static const std::string aa_subject("Naive Authorization CA");
static const Certificate aa_certificate = generate_aa_certificate(aa_subject);
return aa_certificate;
}
const Certificate& NaiveCertificateProvider::root_certificate()
{
static const std::string root_subject("Naive Root CA");
static const Certificate root_certificate = generate_root_certificate(root_subject);
return root_certificate;
}
Certificate NaiveCertificateProvider::generate_authorization_ticket()
{
// create certificate
Certificate certificate;
// section 6.1 in TS 103 097 v1.2.1
certificate.signer_info = calculate_hash(aa_certificate());
// section 6.3 in TS 103 097 v1.2.1
certificate.subject_info.subject_type = SubjectType::Authorization_Ticket;
// section 7.4.2 in TS 103 097 v1.2.1, subject_name implicit empty
// set assurance level
certificate.subject_attributes.push_back(SubjectAssurance(0x00));
certificate.add_permission(aid::CA, ByteBuffer({ 1, 0, 0 }));
certificate.add_permission(aid::DEN, ByteBuffer({ 1, 0xff, 0xff, 0xff}));
certificate.add_permission(aid::GN_MGMT, ByteBuffer({})); // required for beacons
certificate.add_permission(aid::IPV6_ROUTING, ByteBuffer({})); // required for routing tests
// section 7.4.1 in TS 103 097 v1.2.1
// set subject attributes
// set the verification_key
Uncompressed coordinates;
coordinates.x.assign(m_own_key_pair.public_key.x.begin(), m_own_key_pair.public_key.x.end());
coordinates.y.assign(m_own_key_pair.public_key.y.begin(), m_own_key_pair.public_key.y.end());
EccPoint ecc_point = coordinates;
ecdsa_nistp256_with_sha256 ecdsa;
ecdsa.public_key = ecc_point;
VerificationKey verification_key;
verification_key.key = ecdsa;
certificate.subject_attributes.push_back(verification_key);
// section 6.7 in TS 103 097 v1.2.1
// set validity restriction
StartAndEndValidity start_and_end;
start_and_end.start_validity = convert_time32(m_runtime.now() - std::chrono::hours(1));
start_and_end.end_validity = convert_time32(m_runtime.now() + std::chrono::hours(23));
certificate.validity_restriction.push_back(start_and_end);
sign_authorization_ticket(certificate);
return certificate;
}
void NaiveCertificateProvider::sign_authorization_ticket(Certificate& certificate)
{
sort(certificate);
ByteBuffer data_buffer = convert_for_signing(certificate);
certificate.signature = m_crypto_backend->sign_data(aa_key_pair().private_key, data_buffer);
}
Certificate NaiveCertificateProvider::generate_aa_certificate(const std::string& subject_name)
{
// create certificate
Certificate certificate;
// section 6.1 in TS 103 097 v1.2.1
certificate.signer_info = calculate_hash(root_certificate());
// section 6.3 in TS 103 097 v1.2.1
certificate.subject_info.subject_type = SubjectType::Authorization_Authority;
// section 7.4.2 in TS 103 097 v1.2.1
std::vector<unsigned char> subject(subject_name.begin(), subject_name.end());
certificate.subject_info.subject_name = subject;
// section 6.6 in TS 103 097 v1.2.1 - levels currently undefined
certificate.subject_attributes.push_back(SubjectAssurance(0x00));
certificate.add_permission(aid::CA);
certificate.add_permission(aid::DEN);
certificate.add_permission(aid::GN_MGMT); // required for beacons
certificate.add_permission(aid::IPV6_ROUTING); // required for routing tests
// section 7.4.1 in TS 103 097 v1.2.1
// set subject attributes
// set the verification_key
Uncompressed coordinates;
coordinates.x.assign(aa_key_pair().public_key.x.begin(), aa_key_pair().public_key.x.end());
coordinates.y.assign(aa_key_pair().public_key.y.begin(), aa_key_pair().public_key.y.end());
EccPoint ecc_point = coordinates;
ecdsa_nistp256_with_sha256 ecdsa;
ecdsa.public_key = ecc_point;
VerificationKey verification_key;
verification_key.key = ecdsa;
certificate.subject_attributes.push_back(verification_key);
// section 6.7 in TS 103 097 v1.2.1
// set validity restriction
StartAndEndValidity start_and_end;
start_and_end.start_validity = convert_time32(m_runtime.now() - std::chrono::hours(1));
start_and_end.end_validity = convert_time32(m_runtime.now() + std::chrono::hours(23));
certificate.validity_restriction.push_back(start_and_end);
sort(certificate);
// set signature
ByteBuffer data_buffer = convert_for_signing(certificate);
certificate.signature = m_crypto_backend->sign_data(root_key_pair().private_key, data_buffer);
return certificate;
}
Certificate NaiveCertificateProvider::generate_root_certificate(const std::string& subject_name)
{
// create certificate
Certificate certificate;
// section 6.1 in TS 103 097 v1.2.1
certificate.signer_info = nullptr; /* self */
// section 6.3 in TS 103 097 v1.2.1
certificate.subject_info.subject_type = SubjectType::Root_CA;
// section 7.4.2 in TS 103 097 v1.2.1
std::vector<unsigned char> subject(subject_name.begin(), subject_name.end());
certificate.subject_info.subject_name = subject;
// section 6.6 in TS 103 097 v1.2.1 - levels currently undefined
certificate.subject_attributes.push_back(SubjectAssurance(0x00));
certificate.add_permission(aid::CA);
certificate.add_permission(aid::DEN);
certificate.add_permission(aid::GN_MGMT); // required for beacons
certificate.add_permission(aid::IPV6_ROUTING); // required for routing tests
// section 7.4.1 in TS 103 097 v1.2.1
// set subject attributes
// set the verification_key
Uncompressed coordinates;
coordinates.x.assign(root_key_pair().public_key.x.begin(), root_key_pair().public_key.x.end());
coordinates.y.assign(root_key_pair().public_key.y.begin(), root_key_pair().public_key.y.end());
EccPoint ecc_point = coordinates;
ecdsa_nistp256_with_sha256 ecdsa;
ecdsa.public_key = ecc_point;
VerificationKey verification_key;
verification_key.key = ecdsa;
certificate.subject_attributes.push_back(verification_key);
// section 6.7 in TS 103 097 v1.2.1
// set validity restriction
StartAndEndValidity start_and_end;
start_and_end.start_validity = convert_time32(m_runtime.now() - std::chrono::hours(1));
start_and_end.end_validity = convert_time32(m_runtime.now() + std::chrono::hours(365 * 24));
certificate.validity_restriction.push_back(start_and_end);
sort(certificate);
// set signature
ByteBuffer data_buffer = convert_for_signing(certificate);
certificate.signature = m_crypto_backend->sign_data(root_key_pair().private_key, data_buffer);
return certificate;
}
} // namespace v2
} // namespace security
} // namespace vanetza