diff --git a/vanetza/security/straight_verify_service.cpp b/vanetza/security/straight_verify_service.cpp index b1b688328..3ce51f59b 100644 --- a/vanetza/security/straight_verify_service.cpp +++ b/vanetza/security/straight_verify_service.cpp @@ -518,6 +518,13 @@ VerifyConfirm StraightVerifyService::verify(const v3::SecuredMessage& msg) return confirm; } + // Check certificate region validity + if (!v3::check_certificate_region(cert, m_position_provider.position_fix())) { + confirm.report = VerificationReport::Invalid_Certificate; + confirm.certificate_validity = CertificateInvalidReason::Off_Region; + return confirm; + } + ByteBuffer data_hash = m_backend.calculate_hash(public_key->type, msg.signing_payload()); ByteBuffer cert_hash = m_backend.calculate_hash(public_key->type, encoded_cert); ByteBuffer concat_hash = data_hash; diff --git a/vanetza/security/v3/certificate.cpp b/vanetza/security/v3/certificate.cpp index cdbba3179..32e8cf070 100644 --- a/vanetza/security/v3/certificate.cpp +++ b/vanetza/security/v3/certificate.cpp @@ -72,6 +72,39 @@ StartAndEndValidity Certificate::get_start_and_end_validity() const return start_and_end; } +v2::GeographicRegion Certificate::get_region() const +{ + v2::GeographicRegion to_return = v2::NoneRegion(); + if (!m_struct->toBeSigned.region) { + return to_return; + } + + // ETSI TS 103 600 v1.2.1 5.2 - 1.7 requires handling of DENMs signed with + // ATs containing certificate regional restrictions: id and circular + switch (m_struct->toBeSigned.region->present) + { + case Vanetza_Security_GeographicRegion_PR_circularRegion: { + Vanetza_Security_CircularRegion_t& region = m_struct->toBeSigned.region->choice.circularRegion; + to_return = v2::CircularRegion { + v2::TwoDLocation( + vanetza::units::GeoAngle((region.center.latitude/10000000)*boost::units::degree::degrees), + vanetza::units::GeoAngle((region.center.latitude/10000000)*boost::units::degree::degrees) + ), + geonet::distance_u16t::from_value(region.radius) + }; + break; + } + case Vanetza_Security_GeographicRegion_PR_identifiedRegion: + // TODO + break; + default: + // TODO handle other region types + break; + } + + return to_return; +} + boost::optional calculate_digest(const asn1::EtsiTs103097Certificate& cert) { boost::optional digest; diff --git a/vanetza/security/v3/certificate.hpp b/vanetza/security/v3/certificate.hpp index 0e89ff830..0b91e3f68 100644 --- a/vanetza/security/v3/certificate.hpp +++ b/vanetza/security/v3/certificate.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,8 @@ struct Certificate : public asn1::asn1c_oer_wrapper get_verification_key_type() const; StartAndEndValidity get_start_and_end_validity() const; + + v2::GeographicRegion get_region() const; }; /** @@ -81,6 +84,11 @@ boost::optional get_public_encryption_key(const asn1::EtsiTs103097Cer */ boost::optional get_signature(const asn1::EtsiTs103097Certificate& cert); +/** + * Get list of ITS AID permissions from certificate + * \param cert certificate + * \return list of ITS AIDs + */ std::list get_aids(const asn1::EtsiTs103097Certificate& cert); /** diff --git a/vanetza/security/v3/default_certificate_validator.cpp b/vanetza/security/v3/default_certificate_validator.cpp index 6eb9c6a68..c917a6fc4 100644 --- a/vanetza/security/v3/default_certificate_validator.cpp +++ b/vanetza/security/v3/default_certificate_validator.cpp @@ -53,8 +53,11 @@ bool check_subject_assurance_consistency(const Certificate& certificate, const C bool check_region_consistency(const Certificate& certificate, const Certificate& signer) { - // TODO - return true; + printf("Checking region consistency\n"); + auto certificate_region = certificate.get_region(); + auto signer_region = signer.get_region(); + + return is_within(certificate_region, signer_region); } bool check_consistency(const Certificate& certificate, const Certificate& signer) diff --git a/vanetza/security/v3/verification.cpp b/vanetza/security/v3/verification.cpp index de5858320..d551a0462 100644 --- a/vanetza/security/v3/verification.cpp +++ b/vanetza/security/v3/verification.cpp @@ -67,6 +67,22 @@ bool check_certificate_time(const Certificate& certificate, Clock::time_point no return true; } +bool check_certificate_region(const Certificate& certificate, const PositionFix& position) +{ + auto region = certificate.get_region(); + + if (get_type(region) == v2::RegionType::None) { + return true; + } + + if (!position.confidence) { + // return false; // cannot check region restrictions without good position fix + return true; // do not invalidate based on bad position fix for now + } + + return v2::is_within(v2::TwoDLocation(position.latitude, position.longitude), region); +} + } // namespace v3 } // namespace security } // namespace vanetza diff --git a/vanetza/security/v3/verification.hpp b/vanetza/security/v3/verification.hpp index 01d10f1e7..355e1e6c4 100644 --- a/vanetza/security/v3/verification.hpp +++ b/vanetza/security/v3/verification.hpp @@ -14,6 +14,8 @@ namespace v3 bool check_generation_time(const SecuredMessage& message, Clock::time_point now); bool check_certificate_time(const Certificate& certificate, Clock::time_point now); +bool check_certificate_region(const Certificate& certificate, const PositionFix& position); + } // namespace v3 } // namespace security } // namespace vanetza