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