Vanetza
 
Loading...
Searching...
No Matches
secured_message.cpp
1#include <vanetza/common/byte_buffer.hpp>
2#include <vanetza/common/byte_buffer_sink.hpp>
3#include <vanetza/security/exception.hpp>
4#include <vanetza/security/v2/serialization.hpp>
5#include <vanetza/security/v2/secured_message.hpp>
6#include <boost/iostreams/stream.hpp>
7
8namespace vanetza
9{
10namespace security
11{
12namespace v2
13{
14
15HeaderField* SecuredMessage::header_field(HeaderFieldType type)
16{
17 HeaderField* match = nullptr;
18 for (auto& field : header_fields) {
19 if (get_type(field) == type) {
20 match = &field;
21 break;
22 }
23 }
24 return match;
25}
26
27const HeaderField* SecuredMessage::header_field(HeaderFieldType type) const
28{
29 const HeaderField* match = nullptr;
30 for (auto& field : header_fields) {
31 if (get_type(field) == type) {
32 match = &field;
33 break;
34 }
35 }
36 return match;
37}
38
39TrailerField* SecuredMessage::trailer_field(TrailerFieldType type)
40{
41 TrailerField* match = nullptr;
42 for (auto& field : trailer_fields) {
43 if (get_type(field) == type) {
44 match = &field;
45 break;
46 }
47 }
48 return match;
49}
50
51const TrailerField* SecuredMessage::trailer_field(TrailerFieldType type) const
52{
53 const TrailerField* match = nullptr;
54 for (auto& field : trailer_fields) {
55 if (get_type(field) == type) {
56 match = &field;
57 break;
58 }
59 }
60 return match;
61}
62
63size_t get_size(const SecuredMessage& message)
64{
65 size_t size = sizeof(uint8_t); // protocol version
66 size += get_size(message.header_fields);
67 size += length_coding_size(get_size(message.header_fields));
68 size += get_size(message.trailer_fields);
69 size += length_coding_size(get_size(message.trailer_fields));
70 size += get_size(message.payload);
71 return size;
72}
73
74void serialize(OutputArchive& ar, const SecuredMessage& message)
75{
76 const uint8_t protocol_version = message.protocol_version();
77 ar << protocol_version;
78 serialize(ar, message.header_fields);
79 serialize(ar, message.payload);
80 serialize(ar, message.trailer_fields);
81}
82
83size_t deserialize(InputArchive& ar, SecuredMessage& message)
84{
85 uint8_t protocol_version = 0;
86 ar >> protocol_version;
87 size_t length = sizeof(protocol_version);
88 if (protocol_version == 2) {
89 const size_t hdr_length = deserialize(ar, message.header_fields);
90 length += hdr_length + length_coding_size(hdr_length);
91 length += deserialize(ar, message.payload);
92 const size_t trlr_length = deserialize(ar, message.trailer_fields);
93 length += trlr_length + length_coding_size(trlr_length);
94 } else {
95 throw deserialization_error("Unsupported SecuredMessage protocol version");
96 }
97 return length;
98}
99
100ByteBuffer convert_for_signing(const SecuredMessage& message, const std::list<TrailerField>& trailer_fields)
101{
102 ByteBuffer buf;
103 byte_buffer_sink sink(buf);
104
105 boost::iostreams::stream_buffer<byte_buffer_sink> stream(sink);
106 OutputArchive ar(stream);
107
108 const uint8_t protocol_version = message.protocol_version();
109 ar << protocol_version;
110 serialize(ar, message.header_fields);
111 serialize(ar, message.payload);
112
113 // Encode the total length, all trailer fields before the signature and the type of the signature
114 // (see TS 103 097 v1.2.1, section 5.6)
115 serialize_length(ar, get_size(trailer_fields));
116 for (auto& elem : trailer_fields) {
117 TrailerFieldType type = get_type(elem);
118 if (type == TrailerFieldType::Signature) {
119 serialize(ar, type);
120 break; // exclude fields after signature
121 } else {
122 serialize(ar, elem);
123 }
124 }
125
126 stream.close();
127 return buf;
128}
129
130ItsAid get_its_aid(const SecuredMessage& msg)
131{
132 const IntX* raw = msg.header_field<HeaderFieldType::Its_Aid>();
133 return raw ? raw->get() : 0;
134}
135
136} // namespace v2
137} // namespace security
138} // namespace vanetza
SecuredMessage as specified in TS 103 097 v1.2.1, section 5.1.