Vanetza
Loading...
Searching...
No Matches
header_field.cpp
1#include <vanetza/security/exception.hpp>
2#include <vanetza/security/v2/header_field.hpp>
3#include <boost/optional.hpp>
4#include <boost/variant/apply_visitor.hpp>
5#include <boost/variant/static_visitor.hpp>
6
7namespace vanetza
8{
9namespace security
10{
11namespace v2
12{
13
14HeaderFieldType get_type(const HeaderField& field)
15{
16 struct HeaderFieldVisitor : public boost::static_visitor<HeaderFieldType>
17 {
18 HeaderFieldType operator()(const Time64&)
19 {
20 return HeaderFieldType::Generation_Time;
21 }
22 HeaderFieldType operator()(const Time64WithStandardDeviation&)
23 {
24 return HeaderFieldType::Generation_Time_Confidence;
25 }
26 HeaderFieldType operator()(const Time32&)
27 {
28 return HeaderFieldType::Expiration;
29 }
30 HeaderFieldType operator()(const ThreeDLocation&)
31 {
32 return HeaderFieldType::Generation_Location;
33 }
34 HeaderFieldType operator()(const std::list<HashedId3>&)
35 {
36 return HeaderFieldType::Request_Unrecognized_Certificate;
37 }
38 HeaderFieldType operator()(const IntX&)
39 {
40 return HeaderFieldType::Its_Aid;
41 }
42 HeaderFieldType operator()(const SignerInfo&)
43 {
44 return HeaderFieldType::Signer_Info;
45 }
46 HeaderFieldType operator()(const std::list<RecipientInfo>&)
47 {
48 return HeaderFieldType::Recipient_Info;
49 }
50 HeaderFieldType operator()(const EncryptionParameter&)
51 {
52 return HeaderFieldType::Encryption_Parameters;
53 }
54 };
55
56 HeaderFieldVisitor visit;
57 return boost::apply_visitor(visit, field);
58}
59
60size_t get_size(const HeaderField& field)
61{
62 size_t size = sizeof(HeaderFieldType);
63 struct HeaderFieldVisitor : public boost::static_visitor<>
64 {
65 void operator()(const Time64&)
66 {
67 m_size = sizeof(Time64);
68 }
69 void operator()(const Time64WithStandardDeviation& time)
70 {
71 m_size = sizeof(time.time64);
72 m_size += sizeof(time.log_std_dev);
73 }
74 void operator()(const Time32&)
75 {
76 m_size = sizeof(Time32);
77 }
78 void operator()(const ThreeDLocation& loc)
79 {
80 m_size = get_size(loc);
81 }
82 void operator()(const std::list<HashedId3>& list)
83 {
84 m_size = 0;
85 for (auto& elem : list) {
86 m_size += elem.size();
87 }
88 m_size += length_coding_size(m_size);
89 }
90 void operator()(const IntX& itsAid)
91 {
92 m_size = get_size(itsAid);
93 }
94 void operator()(const SignerInfo& info)
95 {
96 m_size = get_size(info);
97 }
98 void operator()(const std::list<RecipientInfo>& list)
99 {
100 m_size = get_size(list);
101 m_size += length_coding_size(m_size);
102 }
103 void operator()(const EncryptionParameter& enc)
104 {
105 m_size = get_size(enc);
106 }
107 size_t m_size;
108 };
109
110 HeaderFieldVisitor visit;
111 boost::apply_visitor(visit, field);
112 size += visit.m_size;
113 return size;
114}
115
116void serialize(OutputArchive& ar, const HeaderField& field)
117{
118 struct HeaderFieldVisitor : public boost::static_visitor<>
119 {
120 HeaderFieldVisitor(OutputArchive& ar) :
121 m_archive(ar)
122 {
123 }
124 void operator()(const Time64& time)
125 {
126 serialize(m_archive, host_cast(time));
127 }
128 void operator()(const Time64WithStandardDeviation& time)
129 {
130 serialize(m_archive, host_cast(time.time64));
131 serialize(m_archive, host_cast(time.log_std_dev));
132 }
133 void operator()(const Time32& time)
134 {
135 serialize(m_archive, host_cast(time));
136 }
137 void operator()(const ThreeDLocation& loc)
138 {
139 serialize(m_archive, loc);
140 }
141 void operator()(const std::list<HashedId3>& list)
142 {
143 size_t size = 0;
144 for (auto& elem : list) {
145 size += elem.size();
146 }
147 serialize_length(m_archive, size);
148 for (auto& elem : list) {
149 m_archive << elem[0];
150 m_archive << elem[1];
151 m_archive << elem[2];
152 }
153 }
154 void operator()(const IntX& itsAid)
155 {
156 serialize(m_archive, itsAid);
157 }
158 void operator()(const SignerInfo& info)
159 {
160 serialize(m_archive, info);
161 }
162 void operator()(const std::list<RecipientInfo>& list)
163 {
164 // TODO: only works until further symmetric algorithms are introduced
165 serialize(m_archive, list, SymmetricAlgorithm::AES128_CCM);
166 }
167 void operator()(const EncryptionParameter& param)
168 {
169 serialize(m_archive, param);
170 }
171
172 OutputArchive& m_archive;
173 };
174 HeaderFieldType type = get_type(field);
175 serialize(ar, type);
176 HeaderFieldVisitor visit(ar);
177 boost::apply_visitor(visit, field);
178}
179
180std::size_t deserialize(InputArchive& ar, std::list<HeaderField>& list)
181{
182 static const std::size_t size_limit = 1024;
183 const std::size_t size = trim_size(deserialize_length(ar));
184 if (size > size_limit) {
185 ar.fail(InputArchive::ErrorCode::ExcessiveLength);
186 }
187
188 std::size_t read = 0;
189 boost::optional<SymmetricAlgorithm> sym_algo;
190 while (read < size && ar.is_good()) {
191 HeaderField field;
192 HeaderFieldType type;
193 deserialize(ar, type);
194 read += sizeof(HeaderFieldType);
195 switch (type) {
196 case HeaderFieldType::Generation_Time: {
197 Time64 time;
198 deserialize(ar, time);
199 field = time;
200 list.push_back(field);
201 read += sizeof(Time64);
202 break;
203 }
204 case HeaderFieldType::Generation_Time_Confidence: {
206 deserialize(ar, time.time64);
207 deserialize(ar, time.log_std_dev);
208 field = time;
209 list.push_back(field);
210 read += sizeof(Time64);
211 read += sizeof(uint8_t);
212 break;
213 }
214 case HeaderFieldType::Expiration: {
215 Time32 time;
216 deserialize(ar, time);
217 field = time;
218 list.push_back(field);
219 read += sizeof(Time32);
220 break;
221 }
222 case HeaderFieldType::Generation_Location: {
223 ThreeDLocation loc;
224 read += deserialize(ar, loc);
225 field = loc;
226 list.push_back(field);
227 break;
228 }
229 case HeaderFieldType::Request_Unrecognized_Certificate: {
230 const std::size_t tmp_size = trim_size(deserialize_length(ar));
231 read += tmp_size;
232 std::list<HashedId3> hashedList;
233 for (std::size_t c = 0; c < tmp_size; c += 3) {
234 HashedId3 id;
235 ar >> id[0];
236 ar >> id[1];
237 ar >> id[2];
238 hashedList.push_back(id);
239 }
240 field = hashedList;
241 read += length_coding_size(tmp_size);
242 list.push_back(field);
243 break;
244 }
245 case HeaderFieldType::Its_Aid: {
246 IntX its_aid;
247 read += deserialize(ar, its_aid);
248 field = its_aid;
249 list.push_back(field);
250 break;
251 }
252 case HeaderFieldType::Signer_Info: {
253 SignerInfo info;
254 read += deserialize(ar, info);
255 field = info;
256 list.push_back(field);
257 break;
258 }
259 case HeaderFieldType::Recipient_Info: {
260 std::list<RecipientInfo> recipientList;
261 if (sym_algo) {
262 const size_t tmp_size = deserialize(ar, recipientList, sym_algo.get());
263 read += tmp_size;
264 read += length_coding_size(tmp_size);
265 field = recipientList;
266 list.push_back(field);
267 } else {
268 throw deserialization_error("HeaderFields: RecipientInfo read before EncryptionParameters: SymmetricAlgorithm still unknown");
269 }
270 break;
271 }
272 case HeaderFieldType::Encryption_Parameters: {
273 EncryptionParameter param;
274 read += deserialize(ar, param);
275 field = param;
276 sym_algo = get_type(param);
277 list.push_back(field);
278 break;
279 }
280 default:
281 throw deserialization_error("Unknown HeaderFieldType");
282 break;
283 }
284 }
285 return read;
286}
287
288} // namespace v2
289} // namespace security
290} // namespace vanetza
IntX specified in TS 103 097 v1.2.1, section 4.2.1.
Definition int_x.hpp:21
ThreeDLocation specified in TS 103 097 v1.2.1, section 4.2.19.
Definition region.hpp:21
Time64WithStandardDeviation specified in TS 103 097 v1.2.1, section 4.2.16.