Branch data Line data Source code
1 : : /*
2 : : Copyright (c) 2023 Assa Abloy. 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 <stdio.h>
13 : : #include <string.h>
14 : : #include <zephyr/ztest.h>
15 : :
16 : : #include "oscore/oscore_interactions.h"
17 : :
18 : : #define DUMMY_BYTE 10
19 : : #define INTERACTIONS_ARRAY_SIZE (OSCORE_INTERACTIONS_COUNT * sizeof(struct oscore_interaction_t))
20 : :
21 : : #define URI_PATHS_DEFAULT "some/resource"
22 : : #define TOKEN_DEFAULT "123456"
23 : :
24 : : #define URI_PATHS_2 (URI_PATHS_DEFAULT "2")
25 : : #define TOKEN_2 (TOKEN_DEFAULT "7")
26 : :
27 : : static struct oscore_interaction_t default_record =
28 : : {
29 : : .token = TOKEN_DEFAULT,
30 : : .token_len = sizeof(TOKEN_DEFAULT),
31 : : .uri_paths = URI_PATHS_DEFAULT,
32 : : .uri_paths_len = sizeof(URI_PATHS_DEFAULT),
33 : : .request_piv = {0x01, 0x02, 0x03},
34 : : .request_piv_len = 3,
35 : : .request_kid = {0x10, 0x20},
36 : : .request_kid_len = 2,
37 : : };
38 : :
39 : : /**
40 : : * @brief Call set_record and check its result.
41 : : */
42 : 0 : static void set_record_and_expect(struct oscore_interaction_t * interactions, struct oscore_interaction_t * record, enum err expected_result)
43 : : {
44 : 0 : PRINTF("set_record; expected result = %d\n", expected_result);
45 : 0 : enum err result = oscore_interactions_set_record(interactions, record);
46 : 0 : zassert_equal(expected_result, result, "");
47 : 0 : }
48 : :
49 : : /**
50 : : * @brief Call set_record and compare resulting interactions array with expected data.
51 : : */
52 : 0 : static void set_record_and_compare(struct oscore_interaction_t * interactions, struct oscore_interaction_t * record, enum err expected_result, struct oscore_interaction_t * expected_interactions)
53 : : {
54 : 0 : set_record_and_expect(interactions, record, expected_result);
55 : 0 : zassert_mem_equal(interactions, expected_interactions, INTERACTIONS_ARRAY_SIZE, "");
56 : 0 : }
57 : :
58 : : /**
59 : : * @brief Call get_record and check its result. Pointer to resulting record will be written to given handle.
60 : : */
61 : 0 : static void get_record_and_expect(struct oscore_interaction_t * interactions, uint8_t * token, uint8_t token_len, struct oscore_interaction_t ** record, enum err expected_result)
62 : : {
63 : 0 : PRINTF("get_record; expected result = %d\n", expected_result);
64 : 0 : enum err result = oscore_interactions_get_record(interactions, token, token_len, record);
65 : 0 : zassert_equal(expected_result, result, "");
66 : 0 : }
67 : :
68 : : /**
69 : : * @brief Call get_record and compare resulting record with expected data.
70 : : */
71 : 0 : static void get_record_and_compare(struct oscore_interaction_t * interactions, struct oscore_interaction_t * record)
72 : : {
73 : 0 : struct oscore_interaction_t * received_record;
74 : 0 : get_record_and_expect(interactions, record->token, record->token_len, &received_record, ok);
75 : 0 : zassert_mem_equal(received_record, record, sizeof(struct oscore_interaction_t), "");
76 : 0 : }
77 : :
78 : : /**
79 : : * @brief Call remove_record and check its result.
80 : : */
81 : 0 : static void remove_record_and_expect(struct oscore_interaction_t * interactions, uint8_t * token, uint8_t token_len, enum err expected_result)
82 : : {
83 : 0 : PRINTF("remove_record; expected result = %d\n", expected_result);
84 : 0 : enum err result = oscore_interactions_remove_record(interactions, token, token_len);
85 : 0 : zassert_equal(expected_result, result, "");
86 : 0 : }
87 : :
88 : : /**
89 : : * @brief Fill given interactions array with generated records, which will be additionally stored at records_array for later checks.
90 : : */
91 : 0 : static void generate_and_fill(struct oscore_interaction_t * interactions, struct oscore_interaction_t * records_array)
92 : : {
93 : 0 : oscore_interactions_init(interactions);
94 [ # # ]: 0 : for (size_t entry = 0; entry < OSCORE_INTERACTIONS_COUNT; entry++)
95 : : {
96 : 0 : struct oscore_interaction_t * record = &(records_array[entry]);
97 : 0 : memcpy(record, &default_record, sizeof(struct oscore_interaction_t));
98 : : //adding one to make sure that only records other than the default one will be stored
99 : 0 : record->uri_paths[0] += entry + 1;
100 : 0 : record->token[0] += entry + 1;
101 : 0 : record->request_piv[0] += entry;
102 : 0 : record->request_kid[0] += entry;
103 : 0 : set_record_and_expect(interactions, record, ok);
104 : : }
105 : 0 : }
106 : :
107 : : /**
108 : : * @brief Test interactions array initialization.
109 : : */
110 : 0 : void t700_interactions_init_test(void)
111 : : {
112 : 0 : struct oscore_interaction_t interactions[OSCORE_INTERACTIONS_COUNT];
113 : 0 : struct oscore_interaction_t interactions_expected[OSCORE_INTERACTIONS_COUNT] = {0};
114 : :
115 : : /* set random data to all fields */
116 : 0 : memset(interactions, DUMMY_BYTE, INTERACTIONS_ARRAY_SIZE);
117 : :
118 : 0 : enum err result = oscore_interactions_init(NULL);
119 : 0 : zassert_equal(wrong_parameter, result, "");
120 : :
121 : 0 : result = oscore_interactions_init(interactions);
122 : 0 : zassert_equal(ok, result, "");
123 : 0 : zassert_mem_equal(interactions, interactions_expected, INTERACTIONS_ARRAY_SIZE, "");
124 : 0 : }
125 : :
126 : : /**
127 : : * @brief Test setting the record into interactions array.
128 : : */
129 : 0 : void t701_interactions_set_record_test(void)
130 : : {
131 : 0 : struct oscore_interaction_t interactions[OSCORE_INTERACTIONS_COUNT];
132 : 0 : oscore_interactions_init(interactions);
133 : :
134 : : /* Test null pointers. */
135 : 0 : set_record_and_expect(NULL, NULL, wrong_parameter);
136 : 0 : set_record_and_expect(interactions, NULL, wrong_parameter);
137 : 0 : set_record_and_expect(NULL, &default_record, wrong_parameter);
138 : :
139 : : /* Test record with too big buffers. */
140 : 0 : struct oscore_interaction_t wrong_record = default_record;
141 : 0 : wrong_record.token_len = MAX_TOKEN_LEN + 1;
142 : 0 : set_record_and_expect(interactions, &wrong_record, wrong_parameter);
143 : :
144 : 0 : wrong_record = default_record;
145 : 0 : wrong_record.uri_paths_len = OSCORE_MAX_URI_PATH_LEN + 1;
146 : 0 : set_record_and_expect(interactions, &wrong_record, wrong_parameter);
147 : :
148 : 0 : wrong_record = default_record;
149 : 0 : wrong_record.request_piv_len = MAX_PIV_LEN + 1;
150 : 0 : set_record_and_expect(interactions, &wrong_record, wrong_parameter);
151 : :
152 : 0 : wrong_record = default_record;
153 : 0 : wrong_record.request_kid_len = MAX_KID_LEN + 1;
154 : 0 : set_record_and_expect(interactions, &wrong_record, wrong_parameter);
155 : :
156 : : /* Writing record to interactions array. */
157 : 0 : struct oscore_interaction_t interactions_expected[OSCORE_INTERACTIONS_COUNT] = {0};
158 : 0 : struct oscore_interaction_t record_1 = default_record;
159 : 0 : interactions_expected[0] = record_1;
160 : 0 : interactions_expected[0].is_occupied = true;
161 : 0 : set_record_and_compare(interactions, &record_1, ok, interactions_expected);
162 : :
163 : : /* Writing an existing record with the same data should change nothing. */
164 : 0 : set_record_and_compare(interactions, &record_1, ok, interactions_expected);
165 : :
166 : : /* Writing a record with different key (URI paths), but with already used token, should fail. */
167 : 0 : struct oscore_interaction_t record_2 = default_record;
168 : 0 : memcpy(record_2.uri_paths, URI_PATHS_2, sizeof(URI_PATHS_2));
169 : 0 : record_2.uri_paths_len = sizeof(URI_PATHS_2);
170 : 0 : set_record_and_expect(interactions, &record_2, oscore_interaction_duplicated_token);
171 : :
172 : : /* Writing a record with different key (URI paths) and token should pass. */
173 : 0 : memcpy(record_2.token, TOKEN_2, sizeof(TOKEN_2));
174 : 0 : record_2.token_len = sizeof(TOKEN_2);
175 : 0 : interactions_expected[1] = record_2;
176 : 0 : interactions_expected[1].is_occupied = true;
177 : 0 : set_record_and_compare(interactions, &record_2, ok, interactions_expected);
178 : :
179 : : /* Writing an existing record with changed values should change the entry accordingly. */
180 : 0 : record_1.request_piv[3] = 0x04;
181 : 0 : record_1.request_piv_len = 4;
182 : 0 : interactions_expected[0] = record_1;
183 : 0 : interactions_expected[0].is_occupied = true;
184 : 0 : set_record_and_compare(interactions, &record_1, ok, interactions_expected);
185 : :
186 : : /* Reset the array and fill all entries with generated records.
187 : : Adding another one should fail. */
188 : 0 : struct oscore_interaction_t generated_records[OSCORE_INTERACTIONS_COUNT];
189 : 0 : generate_and_fill(interactions, generated_records);
190 : 0 : set_record_and_expect(interactions, &default_record, oscore_max_interactions);
191 : 0 : }
192 : :
193 : : /**
194 : : * @brief Test getting the record from interactions array.
195 : : */
196 : 0 : void t702_interactions_get_record_test(void)
197 : : {
198 : 0 : struct oscore_interaction_t interactions[OSCORE_INTERACTIONS_COUNT];
199 : 0 : oscore_interactions_init(interactions);
200 : :
201 : : /* Test null pointers. Null token is a valid value. */
202 : 0 : struct oscore_interaction_t * received_record;
203 : 0 : get_record_and_expect(NULL, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), &received_record, wrong_parameter);
204 : 0 : get_record_and_expect(interactions, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), NULL, wrong_parameter);
205 : :
206 : : /* Test too big token size. */
207 : 0 : get_record_and_expect(interactions, TOKEN_DEFAULT, MAX_TOKEN_LEN + 1, &received_record, wrong_parameter);
208 : :
209 : : /* Getting a not-stored record should fail. */
210 : 0 : get_record_and_expect(interactions, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), &received_record, oscore_interaction_not_found);
211 : 0 : get_record_and_expect(interactions, NULL, 0, &received_record, oscore_interaction_not_found);
212 : 0 : get_record_and_expect(interactions, NULL, 1, &received_record, oscore_interaction_not_found);
213 : :
214 : : /* Writing a record, then getting it back should return the same data.
215 : : Updating a record, then getting it back should return updated data. */
216 : 0 : struct oscore_interaction_t record = default_record;
217 : 0 : set_record_and_expect(interactions, &record, ok);
218 : 0 : get_record_and_compare(interactions, &record);
219 : 0 : record.request_piv[0] += 10;
220 : 0 : set_record_and_expect(interactions, &record, ok);
221 : 0 : get_record_and_compare(interactions, &record);
222 : :
223 : : /* Reset the array and fill all entries with generated records.
224 : : Reading all records should pass, but reading a non-stored record should fail. */
225 : 0 : struct oscore_interaction_t generated_records[OSCORE_INTERACTIONS_COUNT];
226 : 0 : generate_and_fill(interactions, generated_records);
227 [ # # ]: 0 : for (size_t entry = 0; entry < OSCORE_INTERACTIONS_COUNT; entry++)
228 : : {
229 : 0 : get_record_and_compare(interactions, &generated_records[entry]);
230 : : }
231 : 0 : get_record_and_expect(interactions, default_record.token, default_record.token_len, &received_record, oscore_interaction_not_found);
232 : 0 : }
233 : :
234 : : /**
235 : : * @brief Test removing the record from interactions array.
236 : : */
237 : 0 : void t703_interactions_remove_record_test(void)
238 : : {
239 : 0 : struct oscore_interaction_t interactions[OSCORE_INTERACTIONS_COUNT];
240 : 0 : oscore_interactions_init(interactions);
241 : :
242 : : /* Test null pointers. Null token is a valid value. */
243 : 0 : remove_record_and_expect(NULL, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), wrong_parameter);
244 : :
245 : : /* Test too big token size. */
246 : 0 : remove_record_and_expect(interactions, TOKEN_DEFAULT, MAX_TOKEN_LEN + 1, wrong_parameter);
247 : :
248 : : /* Removing a not-stored record should fail. */
249 : 0 : remove_record_and_expect(interactions, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), oscore_interaction_not_found);
250 : 0 : remove_record_and_expect(interactions, NULL, 0, oscore_interaction_not_found);
251 : 0 : remove_record_and_expect(interactions, NULL, 1, oscore_interaction_not_found);
252 : :
253 : : /* Adding, then removing a record should pass. */
254 : 0 : struct oscore_interaction_t * received_record;
255 : 0 : set_record_and_expect(interactions, &default_record, ok);
256 : 0 : get_record_and_expect(interactions, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), &received_record, ok);
257 : 0 : remove_record_and_expect(interactions, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), ok);
258 : 0 : get_record_and_expect(interactions, TOKEN_DEFAULT, sizeof(TOKEN_DEFAULT), &received_record, oscore_interaction_not_found);
259 : :
260 : : /* Reset the array and fill all entries with generated records.
261 : : Check if all generated records are properly stored.
262 : : Remove the first two records, check if they're gone.
263 : : Add the same two records, check if they're accessible.
264 : : Add another record, it should fail due to lack of free slots.
265 : : Check again if all generated records are properly stored. */
266 : 0 : struct oscore_interaction_t generated_records[OSCORE_INTERACTIONS_COUNT];
267 : 0 : generate_and_fill(interactions, generated_records);
268 [ # # ]: 0 : for (size_t entry = 0; entry < OSCORE_INTERACTIONS_COUNT; entry++)
269 : : {
270 : 0 : get_record_and_compare(interactions, &generated_records[entry]);
271 : : }
272 : 0 : remove_record_and_expect(interactions, generated_records[0].token, generated_records[0].token_len, ok);
273 : 0 : remove_record_and_expect(interactions, generated_records[1].token, generated_records[1].token_len, ok);
274 : 0 : get_record_and_expect(interactions, generated_records[0].token, generated_records[0].token_len, &received_record, oscore_interaction_not_found);
275 : 0 : get_record_and_expect(interactions, generated_records[1].token, generated_records[1].token_len, &received_record, oscore_interaction_not_found);
276 : 0 : set_record_and_expect(interactions, &generated_records[0], ok);
277 : 0 : set_record_and_expect(interactions, &generated_records[1], ok);
278 : 0 : set_record_and_expect(interactions, &default_record, oscore_max_interactions);
279 [ # # ]: 0 : for (size_t entry = 0; entry < OSCORE_INTERACTIONS_COUNT; entry++)
280 : : {
281 : 0 : get_record_and_compare(interactions, &generated_records[entry]);
282 : : }
283 : 0 : }
284 : :
285 : : /**
286 : : * @brief Test specific usecases.
287 : : */
288 : 0 : void t704_interactions_usecases_test(void)
289 : : {
290 : 0 : struct oscore_interaction_t interactions[OSCORE_INTERACTIONS_COUNT];
291 : 0 : oscore_interactions_init(interactions);
292 : 0 : set_record_and_expect(interactions, &default_record, ok);
293 : :
294 : : // Get the record, then set it again using the same pointer (without change).
295 : 0 : struct oscore_interaction_t new_record_1 = default_record;
296 : 0 : struct oscore_interaction_t * record_1;
297 : 0 : get_record_and_expect(interactions, new_record_1.token, new_record_1.token_len, &record_1, ok);
298 : 0 : zassert_mem_equal(record_1, &default_record, sizeof(struct oscore_interaction_t), "");
299 : 0 : set_record_and_expect(interactions, record_1, ok);
300 : : /* set_record call is redundant since record_1 already points to specific entry in interactions array.
301 : : Only called for test purposes. */
302 : :
303 : : // Get the record, then set it again using the same pointer (with change).
304 : 0 : struct oscore_interaction_t new_record_2 = default_record;
305 : 0 : struct oscore_interaction_t * record_2;
306 : 0 : get_record_and_expect(interactions, new_record_1.token, new_record_1.token_len, &record_1, ok);
307 : 0 : zassert_mem_equal(record_1, &default_record, sizeof(struct oscore_interaction_t), "");
308 : 0 : record_1->request_piv[0] += 1;
309 : 0 : new_record_2.request_piv[0] += 1;
310 : 0 : set_record_and_expect(interactions, record_1, ok);
311 : : /* set_record call is redundant since record_1 already points to specific entry in interactions array.
312 : : Only called for test purposes. */
313 : 0 : get_record_and_expect(interactions, new_record_2.token, new_record_2.token_len, &record_2, ok);
314 : 0 : zassert_mem_equal(record_2, &new_record_2, sizeof(struct oscore_interaction_t), "");
315 : 0 : }
|