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.
287 lines
8.4 KiB
C++
287 lines
8.4 KiB
C++
#pragma once
|
|
#include <vanetza/asn1/asn1c_wrapper.hpp>
|
|
#include <vanetza/asn1/security_profile.hpp>
|
|
#include VANETZA_ASN1_SECURITY_HEADER(EtsiTs103097Certificate.h)
|
|
#include <vanetza/common/clock.hpp>
|
|
#include <vanetza/common/its_aid.hpp>
|
|
#include <vanetza/common/position_fix.hpp>
|
|
#include <vanetza/net/packet_variant.hpp>
|
|
#include <vanetza/security/hashed_id.hpp>
|
|
#include <vanetza/security/key_type.hpp>
|
|
#include <vanetza/security/public_key.hpp>
|
|
#include <vanetza/security/signature.hpp>
|
|
#include <vanetza/security/v3/asn1_types.hpp>
|
|
#include <vanetza/security/v3/location_checker.hpp>
|
|
#include <vanetza/security/v3/validity_restriction.hpp>
|
|
#include <boost/optional/optional_fwd.hpp>
|
|
#include <cstdint>
|
|
#include <list>
|
|
|
|
namespace vanetza
|
|
{
|
|
namespace security
|
|
{
|
|
namespace v3
|
|
{
|
|
|
|
// forward declaration
|
|
class Certificate;
|
|
|
|
/**
|
|
* Read-only view on a certificate
|
|
*
|
|
* In contrast to Certificate, a view does not own the certificate data.
|
|
* A view can be created with low overhead as no heavy copying is required.
|
|
*/
|
|
class CertificateView
|
|
{
|
|
public:
|
|
explicit CertificateView(const asn1::EtsiTs103097Certificate* cert);
|
|
|
|
/**
|
|
* Calculate digest of certificate
|
|
* \return digest if possible
|
|
*/
|
|
boost::optional<HashedId8> calculate_digest() const;
|
|
|
|
/**
|
|
* Get start and end validity
|
|
* \return certificate start and end validity
|
|
*/
|
|
StartAndEndValidity get_start_and_end_validity() const;
|
|
|
|
/**
|
|
* Get verification key type
|
|
* \return verification key type if possible; otherwise unspecified
|
|
*/
|
|
KeyType get_verification_key_type() const;
|
|
|
|
/**
|
|
* Get issuer digest (if any)
|
|
* \return issuer digest
|
|
*/
|
|
boost::optional<HashedId8> issuer_digest() const;
|
|
|
|
/**
|
|
* Check if certificate is self-signed
|
|
* \return true if certificate is self-signed
|
|
*/
|
|
bool issuer_is_self() const;
|
|
|
|
/**
|
|
* Check if certificate is a Certification Authority certificate
|
|
* \return true if certificate is a CA certificate
|
|
*/
|
|
bool is_ca_certificate() const;
|
|
|
|
/**
|
|
* Check if certificate is an Authorization Ticket certificate
|
|
* \return true if certificate is an AT certificate
|
|
*/
|
|
bool is_at_certificate() const;
|
|
|
|
/**
|
|
* Check if certificate has an region restriction
|
|
* \return true if certificate is only valid within a specific region
|
|
*/
|
|
bool has_region_restriction() const;
|
|
|
|
/**
|
|
* Check if certificate is valid at given location
|
|
*
|
|
* \param location location to be checked
|
|
* \return true if certificate is valid at location
|
|
*/
|
|
bool valid_at_location(const PositionFix& location, const LocationChecker* lc) const;
|
|
|
|
/**
|
|
* Check if certificate is valid at given time point
|
|
*
|
|
* \param time_point time point to be checked
|
|
* \return true if certificate is valid at time point
|
|
*/
|
|
bool valid_at_timepoint(const Clock::time_point& time_point) const;
|
|
|
|
/**
|
|
* Check if certificate is valid for given application
|
|
*
|
|
* \param aid application to be checked
|
|
* \return true if certificate is valid for application
|
|
*/
|
|
bool valid_for_application(ItsAid aid) const;
|
|
|
|
/**
|
|
* Check if certificate issue permissions allow issuing a given application.
|
|
*
|
|
* \param aid application to be checked
|
|
* \return true if certificate may issue certificates for application
|
|
*/
|
|
bool is_allowed_to_issue(ItsAid aid) const;
|
|
|
|
/**
|
|
* Get subject assurance level encoded in this certificate.
|
|
*
|
|
* \return raw assurance level byte if present
|
|
*/
|
|
boost::optional<std::uint8_t> assurance_level() const;
|
|
|
|
/**
|
|
* Check if this certificate's region restriction is within issuer's region restriction.
|
|
*
|
|
* If issuer has no region restriction, any subject region is accepted.
|
|
* Currently supports circular regions and exact rectangular-region equality;
|
|
* unsupported region combinations are rejected conservatively.
|
|
*
|
|
* \param issuer issuing certificate
|
|
* \return true if this certificate's region is contained in issuer's region
|
|
*/
|
|
bool region_is_within(const CertificateView& issuer) const;
|
|
|
|
/**
|
|
* Check if certificate has a canonical format
|
|
* \return true if certificate is in canonical format
|
|
*/
|
|
bool is_canonical() const;
|
|
|
|
/**
|
|
* Convert certificate into its canonical format if possible.
|
|
* \return canonical certificate (or none if conversion failed)
|
|
*/
|
|
boost::optional<Certificate> canonicalize() const;
|
|
|
|
/**
|
|
* Encode certificate.
|
|
* \return encoded certificate
|
|
*/
|
|
ByteBuffer encode() const;
|
|
|
|
protected:
|
|
const asn1::EtsiTs103097Certificate* m_cert = nullptr;
|
|
};
|
|
|
|
struct Certificate : public asn1::asn1c_oer_wrapper<asn1::EtsiTs103097Certificate>, public CertificateView
|
|
{
|
|
using Wrapper = asn1::asn1c_oer_wrapper<asn1::EtsiTs103097Certificate>;
|
|
|
|
Certificate();
|
|
explicit Certificate(const asn1::EtsiTs103097Certificate&);
|
|
|
|
Certificate(const Certificate&);
|
|
Certificate& operator=(const Certificate&);
|
|
|
|
Certificate(Certificate&&);
|
|
Certificate& operator=(Certificate&&);
|
|
|
|
// resolve ambiguity
|
|
ByteBuffer encode() const;
|
|
|
|
/**
|
|
* \brief add application permissions as bitmap
|
|
*
|
|
* \param aid application identifier
|
|
* \param ssp permission bitmap
|
|
*/
|
|
void add_app_permission(ItsAid aid, const ByteBuffer& ssp);
|
|
|
|
/**
|
|
* \brief add cert issuing permission
|
|
*
|
|
* \param group_permission to be added permission
|
|
*/
|
|
void add_cert_issue_permission(asn1::PsidGroupPermissions* group_permission);
|
|
|
|
void set_signature(const SomeEcdsaSignature& signature);
|
|
};
|
|
|
|
/**
|
|
* Calculate digest of v3 certificate
|
|
* \param cert certificate
|
|
* \return digest if possible
|
|
*/
|
|
boost::optional<HashedId8> calculate_digest(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Check if certificate is in canonical format suitable for digest calculation.
|
|
* \param cert certificate
|
|
* \return true if certificate is in canonical format
|
|
*/
|
|
bool is_canonical(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Convert certificate into its canonical format if possible.
|
|
* \param cert certificate
|
|
* \return canonical certificate (or none if conversion failed)
|
|
*/
|
|
boost::optional<Certificate> canonicalize(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Check if certificate is valid at given time point
|
|
*
|
|
* \param cert certificate to be checked
|
|
* \param time_point time point to be checked
|
|
* \return true if certificate is valid at time point
|
|
*/
|
|
bool valid_at_timepoint(const asn1::EtsiTs103097Certificate& cert, const Clock::time_point& time_point);
|
|
|
|
/**
|
|
* Check if certificate is valid for given application
|
|
*
|
|
* \param cert certificate to be checked
|
|
* \param aid application to be checked
|
|
* \return true if certificate is valid for application
|
|
*/
|
|
bool valid_for_application(const asn1::EtsiTs103097Certificate& cert, ItsAid aid);
|
|
|
|
/**
|
|
* Extract the public key out of a certificate
|
|
* \param cert certificate
|
|
* \return public key if possible
|
|
*/
|
|
boost::optional<PublicKey> get_public_key(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Get verification key type
|
|
* \param cert certificate
|
|
* \return verification key type (maybe unspecified)
|
|
*/
|
|
KeyType get_verification_key_type(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Extract the public key for encrypting out of a certificate
|
|
* \param cert certificate
|
|
* \return encryption key if possible
|
|
*/
|
|
boost::optional<PublicKey> get_public_encryption_key(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Extract the signature out of a certificate
|
|
* \param cert certificate
|
|
* \return signature if possible
|
|
*/
|
|
boost::optional<Signature> get_signature(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Get list of ITS AID permissions from certificate
|
|
* \param cert certificate
|
|
* \return list of ITS AIDs
|
|
*/
|
|
std::list<ItsAid> get_aids(const asn1::EtsiTs103097Certificate& cert);
|
|
|
|
/**
|
|
* Get application permissions (SSP = service specific permissions)
|
|
* \param cert certificate containing application permissions
|
|
* \param aid look up permissions for this application identifier
|
|
* \return SSP bitmap or empty buffer
|
|
*/
|
|
ByteBuffer get_app_permissions(const asn1::EtsiTs103097Certificate& cert, ItsAid aid);
|
|
|
|
void add_psid_group_permission(asn1::PsidGroupPermissions* group_permission, ItsAid aid, const ByteBuffer& ssp, const ByteBuffer& bitmask);
|
|
|
|
void serialize(OutputArchive& ar, const Certificate& certificate);
|
|
|
|
Certificate fake_certificate();
|
|
|
|
} // namespace v3
|
|
} // namespace security
|
|
} // namespace vanetza
|