Vanetza
Loading...
Searching...
No Matches
sign_header_policy.cpp
1#include <vanetza/common/its_aid.hpp>
2#include <vanetza/common/position_provider.hpp>
3#include <vanetza/security/sign_service.hpp>
4#include <vanetza/security/v3/certificate.hpp>
5#include <vanetza/security/v3/certificate_provider.hpp>
6#include <vanetza/security/v3/sign_header_policy.hpp>
7#include <cmath>
8
9namespace vanetza
10{
11namespace security
12{
13namespace v3
14{
15
16asn1::ThreeDLocation build_location(const PositionFix& fix)
17{
18 asn1::ThreeDLocation location;
19 static constexpr long latitude_scale = Vanetza_Security_NinetyDegreeInt_max;
20 static constexpr long longitude_scale = Vanetza_Security_OneEightyDegreeInt_max;
21
22 long lat = std::round((fix.latitude / units::degree / 90.0) * latitude_scale);
23 if (lat >= Vanetza_Security_NinetyDegreeInt_min && lat <= Vanetza_Security_NinetyDegreeInt_max) {
24 location.latitude = lat;
25 } else {
26 location.latitude = Vanetza_Security_NinetyDegreeInt_unknown;
27 }
28
29 long lon = std::round((fix.longitude / units::degree / 180.0) * longitude_scale);
30 if (lon >= Vanetza_Security_OneEightyDegreeInt_min && lon <= Vanetza_Security_OneEightyDegreeInt_max) {
31 location.longitude = lon;
32 } else {
33 location.longitude = Vanetza_Security_OneEightyDegreeInt_unknown;
34 }
35
36 location.elevation = 4096; // no "not available" value specified, set 0m as fallback
37 if (fix.altitude) {
38 long elev_dm = std::round(fix.altitude->value() / units::si::meter * 10.0);
39 if (elev_dm >= -4095 && elev_dm <= 61439) {
40 location.elevation = elev_dm + 4096;
41 }
42 }
43
44 return location;
45}
46
47DefaultSignHeaderPolicy::DefaultSignHeaderPolicy(const Runtime& rt, PositionProvider& positioning, CertificateProvider& certs) :
48 m_runtime(rt), m_positioning(positioning), m_cert_provider(certs),
49 m_cam_next_certificate(m_runtime.now()),
50 m_cert_requested(false)
51{
52}
53
55{
56 const auto now = m_runtime.now();
57 secured_message.set_its_aid(request.its_aid);
58 secured_message.set_generation_time(vanetza::security::v2::convert_time64(now));
59
60 if (request.its_aid == aid::CA) {
61 bool signer_full_cert = false;
62 const auto& at_cert = m_cert_provider.own_certificate();
63 const auto maybe_at_digest = at_cert.calculate_digest();
64
65 // include full certificate if its digest has been requested by a peer
66 if (maybe_at_digest && m_incoming_requests.is_pending(truncate(*maybe_at_digest))) {
67 m_cert_requested = true;
68 m_incoming_requests.discard_request(truncate(*maybe_at_digest));
69 }
70
71 // section 7.1.1 in TS 103 097 v2.1.1
72 if (now < m_cam_next_certificate && !m_cert_requested) {
73 if (maybe_at_digest) {
74 secured_message.set_signer_identifier(*maybe_at_digest);
75 }
76 } else {
77 signer_full_cert = true;
78 m_cert_requested = false;
79 secured_message.set_signer_identifier(at_cert);
80 m_cam_next_certificate = now + std::chrono::seconds(1) - std::chrono::milliseconds(50);
81 }
82
83 // peer-to-peer certificate distribution
84 secured_message.set_inline_p2pcd_request(m_outgoing_requests.all());
85 if (!signer_full_cert) {
86 while (auto p2p_hid = m_incoming_requests.next_one()) {
87 // provide requested CA certificates (no AT certificates here)
88 auto p2p_cert = m_cert_provider.cache().lookup(*p2p_hid);
89 if (p2p_cert && p2p_cert->is_ca_certificate()) {
90 secured_message.set_requested_certificate(*p2p_cert);
91 break;
92 }
93 }
94 }
95 } else if (request.its_aid == aid::DEN) {
96 // section 7.1.2 in TS 103 097 v2.1.1
97 secured_message.set_signer_identifier(m_cert_provider.own_certificate());
98 secured_message.set_generation_location(build_location(m_positioning.position_fix()));
99 } else if (request.its_aid == aid::SCR) {
100 // section 6.2.3.2 and 6.2.3.3 in TS 102 941 v2.1.1
101 // some structures in the SCR are self-signed
102 if (request.self_signed)
103 secured_message.set_signer_identifier_self();
104 else {
105 const auto digest = m_cert_provider.own_certificate().calculate_digest();
106 if (digest)
107 secured_message.set_signer_identifier(*digest);
108 }
109 } else {
110 secured_message.set_signer_identifier(m_cert_provider.own_certificate());
111 }
112}
113
115{
116 m_outgoing_requests.add_request(truncate(id));
117}
118
120{
121 m_cert_requested = true;
122}
123
125{
126 m_incoming_requests.add_request(id);
127}
128
130{
131 m_incoming_requests.discard_request(id);
132}
133
134} // namespace v3
135} // namespace security
136} // namespace vanetza
virtual const PositionFix & position_fix()=0
virtual Clock::time_point now() const =0
virtual CertificateCache & cache()=0
virtual const Certificate & own_certificate()=0
boost::optional< HashedId8 > calculate_digest() const
void request_unrecognized_certificate(HashedId8 id) override
void prepare_header(const SignRequest &request, SecuredMessage &secured_message) override