1 /*
2 Copyright (c) 2022 Eriptic Technologies. See the COPYRIGHT
3 file at the top-level directory of this distribution.
4
5 Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 option. This file may not be copied, modified, or distributed
9 except according to those terms.
10 */
11
12 #include <string.h>
13
14 #include <zephyr/zephyr.h>
15 #include <zephyr/ztest.h>
16
17 #include "common/byte_array.h"
18 #include "common/unit_test.h"
19
20 #include "oscore/oscore_coap.h"
21 #include "oscore/option.h"
22
coap_get_message_type_and_compare(struct o_coap_packet * coap_packet,enum o_coap_msg * msg_type,enum err expected_result,enum o_coap_msg expected_msg_type)23 static void coap_get_message_type_and_compare(struct o_coap_packet * coap_packet, enum o_coap_msg * msg_type, enum err expected_result, enum o_coap_msg expected_msg_type)
24 {
25 PRINTF("coap_get_message_type; expected result = %d\n", expected_result);
26 enum err result = coap_get_message_type(coap_packet, msg_type);
27 zassert_equal(expected_result, result, "unexpected result: %d", result);
28
29 if (ok == result)
30 {
31 zassert_equal(*msg_type, expected_msg_type, "");
32 }
33 }
34
generate_test_packet(uint8_t code,uint8_t options_count,uint8_t * observe_value,uint16_t observe_len)35 static struct o_coap_packet generate_test_packet(uint8_t code, uint8_t options_count, uint8_t * observe_value, uint16_t observe_len)
36 {
37 struct o_coap_packet result;
38 result.header.code = code;
39 result.options_cnt = options_count;
40 result.options[0].option_number = OBSERVE;
41 result.options[0].value = observe_value;
42 result.options[0].len = observe_len;
43 return result;
44 };
45
serialization_test(struct o_coap_option * options,uint8_t opt_cnt,struct byte_array * expected)46 static void serialization_test(struct o_coap_option *options, uint8_t opt_cnt,
47 struct byte_array *expected)
48 {
49 uint8_t out_buf[expected->len];
50 struct byte_array out = BYTE_ARRAY_INIT(out_buf, sizeof(out_buf));
51
52 enum err r = options_serialize(options, opt_cnt, &out);
53 zassert_equal(r, ok, "Error in options_serialize. r: %d", r);
54
55 PRINT_ARRAY("computed", out.ptr, out.len);
56 PRINT_ARRAY("expected", expected->ptr, expected->len);
57
58 zassert_mem_equal__(out.ptr, expected->ptr, expected->len,
59 "serialization incorrect");
60 }
61
deserialization_test(uint8_t * in_data,uint16_t in_data_len,struct o_coap_option * options,uint32_t options_len_in_byte)62 static void deserialization_test(uint8_t *in_data, uint16_t in_data_len,
63 struct o_coap_option *options,
64 uint32_t options_len_in_byte)
65 {
66 struct o_coap_packet coap_pkt;
67 struct byte_array d = BYTE_ARRAY_INIT(in_data, in_data_len);
68 enum err r =
69 options_deserialize(&d,
70 (struct o_coap_option *)&coap_pkt.options,
71 &coap_pkt.options_cnt, &coap_pkt.payload);
72
73 zassert_equal(r, ok, "Error in options_deserialize. r: %d", r);
74
75 for (uint8_t i = 0; i < coap_pkt.options_cnt; i++) {
76 zassert_equal(options[i].delta, coap_pkt.options[i].delta,
77 "delta mismatch: %d", coap_pkt.options[i].delta);
78 zassert_equal(options[i].len, coap_pkt.options[i].len,
79 "len mismatch: %d", coap_pkt.options[i].len);
80 zassert_equal(options[i].option_number,
81 coap_pkt.options[i].option_number,
82 "option_number mismatch: %d",
83 coap_pkt.options[i].option_number);
84 zassert_mem_equal__(options[i].value, coap_pkt.options[i].value,
85 options[i].len, "option value mismatch");
86 }
87 }
88
t200_options_serialize_deserialize(void)89 void t200_options_serialize_deserialize(void)
90 {
91 /*
92 * two options
93 * short delta (delta < 12)
94 * short data length (length < 12)
95 */
96 uint8_t uri_host_val[] = { 'c', 'o', 'a', 'p', '.', 'm', 'e' };
97 uint8_t uri_path_val[] = { 't', 'e', 's', 't' };
98 struct o_coap_option options[] = { { .delta = 3,
99 .len = sizeof(uri_host_val),
100 .value = uri_host_val,
101 .option_number = URI_HOST },
102 { .delta = 8,
103 .len = sizeof(uri_path_val),
104 .value = uri_path_val,
105 .option_number = URI_PATH } };
106
107 uint8_t EXPECTED[] = {
108 0x37, 0x63, 0x6f, 0x61, 0x70, 0x2e, 0x6d,
109 0x65, 0x84, 0x74, 0x65, 0x73, 0x74,
110 };
111 struct byte_array expt = BYTE_ARRAY_INIT(EXPECTED, sizeof(EXPECTED));
112
113 serialization_test(options, sizeof(options) / sizeof(options[0]),
114 &expt);
115
116 deserialization_test(EXPECTED, sizeof(EXPECTED), options,
117 sizeof(options));
118
119 /*
120 * four options
121 * short delta (delta < 12)
122 * short data length (length < 12)
123 */
124 uint8_t location_path1[] = {
125 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '1'
126 };
127 uint8_t location_path2[] = {
128 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '2'
129 };
130 uint8_t location_path3[] = {
131 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '3'
132 };
133 struct o_coap_option options1[] = { { .delta = 8,
134 .len = sizeof(location_path1),
135 .value = location_path1,
136 .option_number = LOCATION_PATH },
137 { .delta = 0,
138 .len = sizeof(location_path2),
139 .value = location_path2,
140 .option_number = LOCATION_PATH },
141 { .delta = 0,
142 .len = sizeof(location_path3),
143 .value = location_path3,
144 .option_number = LOCATION_PATH },
145 { .delta = 4,
146 .len = 0,
147 .value = NULL,
148 .option_number =
149 CONTENT_FORMAT } };
150
151 uint8_t EXPECTED1[] = { 0x89, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
152 0x6e, 0x31, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74,
153 0x69, 0x6f, 0x6e, 0x32, 0x09, 0x6c, 0x6f, 0x63,
154 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x33, 0x40 };
155
156 struct byte_array expt1 = BYTE_ARRAY_INIT(EXPECTED1, sizeof(EXPECTED1));
157
158 serialization_test(options1, sizeof(options1) / sizeof(options1[0]),
159 &expt1);
160
161 deserialization_test(EXPECTED1, sizeof(EXPECTED1), options1,
162 sizeof(options1));
163
164 /*
165 * three options
166 * opt1 and opt2 short delta (delta < 12)
167 * opt3 delta 16
168 * short data length (length < 12)
169 */
170 uint8_t uri_host_val2[] = { 'c', 'o', 'a', 'p', '.', 'm', 'e' };
171 uint8_t uri_path_val2[] = { 'l', 'a', 'r', 'g', 'e', '-',
172 'u', 'p', 'd', 'a', 't', 'e' };
173 uint8_t block1_val[] = { 0x06 };
174 struct o_coap_option options2[] = { { .delta = 3,
175 .len = sizeof(uri_host_val2),
176 .value = uri_host_val,
177 .option_number = URI_HOST },
178 { .delta = 8,
179 .len = sizeof(uri_path_val2),
180 .value = uri_path_val2,
181 .option_number = URI_PATH },
182 { .delta = 16,
183 .len = sizeof(block1_val),
184 .value = block1_val,
185 .option_number = BLOCK1 } };
186 uint8_t EXPECTED2[] = { 0x37, 0x63, 0x6f, 0x61, 0x70, 0x2e, 0x6d, 0x65,
187 0x8c, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x2d, 0x75,
188 0x70, 0x64, 0x61, 0x74, 0x65, 0xd1, 0x03, 0x06 };
189
190 struct byte_array expt2 = BYTE_ARRAY_INIT(EXPECTED2, sizeof(EXPECTED2));
191
192 serialization_test(options2, sizeof(options2) / sizeof(options2[0]),
193 &expt2);
194 deserialization_test(EXPECTED2, sizeof(EXPECTED2), options2,
195 sizeof(options2));
196
197 /*
198 * one option
199 * opt3 delta 13
200 * short data length (length < 12)
201 */
202 uint8_t block1_val3[] = { 0x06 };
203 struct o_coap_option options3[] = { { .delta = 27,
204 .len = sizeof(block1_val3),
205 .value = block1_val3,
206 .option_number = BLOCK1 } };
207 uint8_t EXPECTED3[] = { 0xd1, 0x0e, 0x06 };
208
209 struct byte_array expt3 = BYTE_ARRAY_INIT(EXPECTED3, sizeof(EXPECTED3));
210 serialization_test(options3, sizeof(options3) / sizeof(options3[0]),
211 &expt3);
212 deserialization_test(EXPECTED3, sizeof(EXPECTED3), options3,
213 sizeof(options3));
214
215 /*
216 * one option
217 * delta 15
218 * length 0
219 */
220 struct o_coap_option options4[] = { { .delta = 20,
221 .len = 0,
222 .value = NULL,
223 .option_number =
224 LOCATION_QUERY } };
225 uint8_t EXPECTED4[] = { 0xd0, 0x07 };
226
227 struct byte_array expt4 = BYTE_ARRAY_INIT(EXPECTED4, sizeof(EXPECTED4));
228 serialization_test(options4, sizeof(options4) / sizeof(options4[0]),
229 &expt4);
230 deserialization_test(EXPECTED4, sizeof(EXPECTED4), options4,
231 sizeof(options4));
232
233 /*
234 * one option
235 * delta 780
236 * length 0
237 */
238 struct o_coap_option options5[] = {
239 { .delta = 780, .len = 0, .value = NULL, .option_number = 780 }
240 }; //there is no such option actually;)
241 uint8_t EXPECTED5[] = { 0xe0, 0x01, 0xff };
242
243 struct byte_array expt5 = BYTE_ARRAY_INIT(EXPECTED5, sizeof(EXPECTED5));
244 serialization_test(options5, sizeof(options5) / sizeof(options5[0]),
245 &expt5);
246 deserialization_test(EXPECTED5, sizeof(EXPECTED5), options5,
247 sizeof(options5));
248
249 /*
250 * one option
251 * delta 280
252 * length 500
253 */
254 uint8_t val7[500];
255 memset(val7, 0, sizeof(val7));
256 struct o_coap_option options7[] = { { .delta = 280,
257 .len = sizeof(val7),
258 .value = val7,
259 .option_number = 280 } };
260
261 uint8_t EXPECTED7[505];
262 memset(EXPECTED7, 0, sizeof(EXPECTED7));
263 EXPECTED7[0] = 0xee;
264 EXPECTED7[1] = 0x00;
265 EXPECTED7[2] = 0x0b;
266 EXPECTED7[3] = 0x00;
267 EXPECTED7[4] = 0xe7;
268
269 struct byte_array expt7 = BYTE_ARRAY_INIT(EXPECTED7, sizeof(EXPECTED7));
270 serialization_test(options7, sizeof(options7) / sizeof(options7[0]),
271 &expt7);
272 deserialization_test(EXPECTED7, sizeof(EXPECTED7), options7,
273 sizeof(options7));
274
275 /*
276 * one option
277 * delta 22
278 * length 500
279 */
280 uint8_t val8[500];
281 memset(val8, 0, sizeof(val8));
282 struct o_coap_option options8[] = { { .delta = 22,
283 .len = sizeof(val8),
284 .value = val8,
285 .option_number = 22 } };
286
287 uint8_t EXPECTED8[504];
288 memset(EXPECTED8, 0, sizeof(EXPECTED8));
289 EXPECTED8[0] = 0xde;
290 EXPECTED8[1] = 0x09;
291 EXPECTED8[2] = 0x00;
292 EXPECTED8[3] = 0xe7;
293
294 struct byte_array expt8 = BYTE_ARRAY_INIT(EXPECTED8, sizeof(EXPECTED8));
295 serialization_test(options8, sizeof(options8) / sizeof(options8[0]),
296 &expt8);
297 deserialization_test(EXPECTED8, sizeof(EXPECTED8), options8,
298 sizeof(options8));
299 /*
300 * one option
301 * delta 7
302 * length 500
303 */
304 uint8_t val9[500];
305 memset(val9, 0, sizeof(val9));
306 struct o_coap_option options9[] = { { .delta = 7,
307 .len = sizeof(val9),
308 .value = val9,
309 .option_number = 7 } };
310
311 uint8_t EXPECTED9[503];
312 memset(EXPECTED9, 0, sizeof(EXPECTED9));
313 EXPECTED9[0] = 0x7e;
314 EXPECTED9[1] = 0x00;
315 EXPECTED9[2] = 0xe7;
316
317 struct byte_array expt9 = BYTE_ARRAY_INIT(EXPECTED9, sizeof(EXPECTED9));
318 serialization_test(options9, sizeof(options9) / sizeof(options9[0]),
319 &expt9);
320 deserialization_test(EXPECTED9, sizeof(EXPECTED9), options9,
321 sizeof(options9));
322 /*
323 * one option
324 * delta 500
325 * length 20
326 */
327 uint8_t val10[20];
328 memset(val10, 0, sizeof(val10));
329 struct o_coap_option options10[] = { { .delta = 500,
330 .len = sizeof(val10),
331 .value = val10,
332 .option_number = 500 } };
333
334 uint8_t EXPECTED10[24];
335 memset(EXPECTED10, 0, sizeof(EXPECTED10));
336 EXPECTED10[0] = 0xed;
337 EXPECTED10[1] = 0x00;
338 EXPECTED10[2] = 0xe7;
339 EXPECTED10[3] = 0x07;
340
341 struct byte_array expt10 =
342 BYTE_ARRAY_INIT(EXPECTED10, sizeof(EXPECTED10));
343 serialization_test(options10, sizeof(options10) / sizeof(options10[0]),
344 &expt10);
345 deserialization_test(EXPECTED10, sizeof(EXPECTED10), options10,
346 sizeof(options10));
347 /*
348 * one option
349 * delta 20
350 * length 20
351 */
352 uint8_t val11[20];
353 memset(val11, 0, sizeof(val11));
354 struct o_coap_option options11[] = { { .delta = 20,
355 .len = sizeof(val11),
356 .value = val11,
357 .option_number = 20 } };
358
359 uint8_t EXPECTED11[23];
360 memset(EXPECTED11, 0, sizeof(EXPECTED11));
361 EXPECTED11[0] = 0xdd;
362 EXPECTED11[1] = 0x07;
363 EXPECTED11[2] = 0x07;
364
365 struct byte_array expt11 =
366 BYTE_ARRAY_INIT(EXPECTED11, sizeof(EXPECTED11));
367 serialization_test(options11, sizeof(options11) / sizeof(options11[0]),
368 &expt11);
369 deserialization_test(EXPECTED11, sizeof(EXPECTED11), options11,
370 sizeof(options11));
371 /*
372 * one option
373 * delta 4
374 * length 20
375 */
376 uint8_t val12[20];
377 memset(val12, 0, sizeof(val12));
378 struct o_coap_option options12[] = { { .delta = 4,
379 .len = sizeof(val12),
380 .value = val12,
381 .option_number = 4 } };
382
383 uint8_t EXPECTED12[22];
384 memset(EXPECTED12, 0, sizeof(EXPECTED12));
385 EXPECTED12[0] = 0x4d;
386 EXPECTED12[1] = 0x07;
387
388 struct byte_array expt12 =
389 BYTE_ARRAY_INIT(EXPECTED12, sizeof(EXPECTED12));
390 serialization_test(options12, sizeof(options12) / sizeof(options12[0]),
391 &expt12);
392 deserialization_test(EXPECTED12, sizeof(EXPECTED12), options12,
393 sizeof(options12));
394
395 /*
396 * one option
397 * delta 252
398 * length 12
399 */
400 uint8_t val13[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
401 0x06, 0x07, 0x08, 0x09, 0x10, 0x11 };
402 struct o_coap_option options13[] = { { .delta = 252,
403 .len = sizeof(val13),
404 .value = val13,
405 .option_number = ECHO } };
406 uint8_t EXPECTED13[] = { 0xdc, 0xef, 0x00, 0x01, 0x02, 0x03, 0x04,
407 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11 };
408
409 struct byte_array expt13 =
410 BYTE_ARRAY_INIT(EXPECTED13, sizeof(EXPECTED13));
411 serialization_test(options13, sizeof(options13) / sizeof(options13[0]),
412 &expt13);
413 deserialization_test(EXPECTED13, sizeof(EXPECTED13), options13,
414 sizeof(options13));
415 }
416
t201_coap_serialize_deserialize(void)417 void t201_coap_serialize_deserialize(void)
418 {
419 enum err r;
420 /*test malformed input data*/
421 struct byte_array in = BYTE_ARRAY_INIT(NULL, 0);
422 struct o_coap_packet out;
423
424 r = coap_deserialize(&in, &out);
425 zassert_equal(r, not_valid_input_packet,
426 "Error in coap_deserialize. r: %d", r);
427
428 /*test no token*/
429 uint8_t in_buf[] = { 0x40, 0x00, 0x00, 0x00 };
430 in.ptr = in_buf;
431 in.len = sizeof(in_buf);
432
433 r = coap_deserialize(&in, &out);
434 zassert_equal(r, ok, "Error in coap_deserialize. r: %d", r);
435 zassert_is_null(out.token, "invalid token");
436 zassert_equal(out.header.TKL, 0, "invalid TKL");
437
438 uint8_t ser_dat[sizeof(in_buf)];
439 uint32_t ser_dat_len = 0;
440 r = coap_serialize(&out, (uint8_t *)&ser_dat, &ser_dat_len);
441 zassert_equal(r, ok, "Error in coap_deserialize. r: %d", r);
442 zassert_equal(ser_dat_len, sizeof(in_buf), "wrong ser_dat_len");
443 zassert_mem_equal__(ser_dat, in_buf, ser_dat_len, "wrong ser_dat");
444
445 /*test too long token*/
446 uint8_t in_buf_too_long_tkl[] = { 0x4F, 0x00, 0x00, 0x00 };
447 in.ptr = in_buf_too_long_tkl;
448 in.len = sizeof(in_buf_too_long_tkl);
449
450 r = coap_deserialize(&in, &out);
451 zassert_equal(r, oscore_inpkt_invalid_tkl,
452 "Error in coap_deserialize. r: %d", r);
453
454 /*test valid tkl but no payload*/
455 uint8_t in_buf_valid_tkl_no_payload[] = { 0x41, 0x00, 0x00, 0x00 };
456 in.ptr = in_buf_valid_tkl_no_payload;
457 in.len = sizeof(in_buf_valid_tkl_no_payload);
458
459 r = coap_deserialize(&in, &out);
460 zassert_equal(r, oscore_inpkt_invalid_tkl,
461 "Error in coap_deserialize. r: %d", r);
462 }
463
t202_options_deserialize_corner_cases(void)464 void t202_options_deserialize_corner_cases(void)
465 {
466 enum err r;
467 struct o_coap_packet coap_pkt;
468
469 /*test only payload marker no payload*/
470 uint8_t in_data1[] = { 0xff };
471 struct byte_array d1 = BYTE_ARRAY_INIT(in_data1, sizeof(in_data1));
472
473 r = options_deserialize(&d1, (struct o_coap_option *)&coap_pkt.options,
474 &coap_pkt.options_cnt, &coap_pkt.payload);
475
476 zassert_equal(r, not_valid_input_packet,
477 "Error in options_deserialize. r: %d", r);
478
479 /*test invalid delta*/
480 uint8_t in_data2[] = { 0xf0 }; //delta is 15 -> not a valid value
481 struct byte_array d2 = BYTE_ARRAY_INIT(in_data2, sizeof(in_data2));
482
483 r = options_deserialize(&d2, (struct o_coap_option *)&coap_pkt.options,
484 &coap_pkt.options_cnt, &coap_pkt.payload);
485
486 zassert_equal(r, oscore_inpkt_invalid_option_delta,
487 "Error in options_deserialize. r: %d", r);
488
489 /*test invalid len*/
490 uint8_t in_data3[] = { 0x0f }; //len is 15 -> not a valid value
491 struct byte_array d3 = BYTE_ARRAY_INIT(in_data3, sizeof(in_data3));
492
493 r = options_deserialize(&d3, (struct o_coap_option *)&coap_pkt.options,
494 &coap_pkt.options_cnt, &coap_pkt.payload);
495
496 zassert_equal(r, oscore_inpkt_invalid_optionlen,
497 "Error in options_deserialize. r: %d", r);
498
499 /*test too many options*/
500 uint8_t in_data4[] = {
501 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
504 }; //21 options with option number 1
505 struct byte_array d4 = BYTE_ARRAY_INIT(in_data4, sizeof(in_data4));
506
507 r = options_deserialize(&d4, (struct o_coap_option *)&coap_pkt.options,
508 &coap_pkt.options_cnt, &coap_pkt.payload);
509
510 zassert_equal(r, too_many_options,
511 "Error in options_deserialize. r: %d", r);
512 }
513
t203_coap_get_message_type(void)514 void t203_coap_get_message_type(void)
515 {
516 struct o_coap_packet packet_request_1 = generate_test_packet(CODE_REQ_GET, 0, NULL, 0); //no OBSERVE option
517 struct o_coap_packet packet_request_2 = generate_test_packet(CODE_REQ_POST, 1, "\x01\x02\x03", 3);
518 struct o_coap_packet packet_registration_1 = generate_test_packet(CODE_REQ_GET, 1, "\x00", 1);
519 struct o_coap_packet packet_registration_2 = generate_test_packet(CODE_REQ_POST, 1, NULL, 0); //empty OBSERVE option
520 struct o_coap_packet packet_cancellation = generate_test_packet(CODE_REQ_GET, 1, "\x01", 1);
521 struct o_coap_packet packet_response = generate_test_packet(CODE_RESP_CONTENT, 0, NULL, 0);
522 struct o_coap_packet packet_notification_1 = generate_test_packet(CODE_RESP_CONTENT, 1, NULL, 0);
523 struct o_coap_packet packet_notification_2 = generate_test_packet(CODE_RESP_CONTENT, 1, "\x01\x02", 2);
524
525 /* Test null pointers. */
526 enum o_coap_msg msg_type;
527 coap_get_message_type_and_compare(NULL, &msg_type, wrong_parameter, 0);
528 coap_get_message_type_and_compare(&packet_request_1, NULL, wrong_parameter, 0);
529
530 /* Test different valid packets. */
531 coap_get_message_type_and_compare(&packet_request_1, &msg_type, ok, COAP_MSG_REQUEST);
532 coap_get_message_type_and_compare(&packet_request_2, &msg_type, ok, COAP_MSG_REQUEST);
533 coap_get_message_type_and_compare(&packet_registration_1, &msg_type, ok, COAP_MSG_REGISTRATION);
534 coap_get_message_type_and_compare(&packet_registration_2, &msg_type, ok, COAP_MSG_REGISTRATION);
535 coap_get_message_type_and_compare(&packet_cancellation, &msg_type, ok, COAP_MSG_CANCELLATION);
536 coap_get_message_type_and_compare(&packet_response, &msg_type, ok, COAP_MSG_RESPONSE);
537 coap_get_message_type_and_compare(&packet_notification_1, &msg_type, ok, COAP_MSG_NOTIFICATION);
538 coap_get_message_type_and_compare(&packet_notification_2, &msg_type, ok, COAP_MSG_NOTIFICATION);
539 }
540