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 #ifndef OSCORE_INTERACTIONS_H
13 #define OSCORE_INTERACTIONS_H
14 
15 #include <stdint.h>
16 #include "oscore/oscore_coap_defines.h"
17 #include "common/byte_array.h"
18 #include "common/oscore_edhoc_error.h"
19 
20 /**
21  * @brief Number of interactions supported at the same time, per one OSCORE context.
22  */
23 #ifndef OSCORE_INTERACTIONS_COUNT
24 #define OSCORE_INTERACTIONS_COUNT 3
25 #endif
26 
27 /**
28  * @brief Single record of interaction between the server and the client.
29  */
30 struct oscore_interaction_t {
31 	/* Request type, used to distinguish between normal request and resource observations. */
32 	enum o_coap_msg request_type;
33 
34 	/* CoAP token of the subscription request. */
35 	uint8_t token[MAX_TOKEN_LEN];
36 	uint8_t token_len;
37 
38 	/* Full URI path (all options concatenated to single string). */
39 	uint8_t uri_paths[OSCORE_MAX_URI_PATH_LEN];
40 	uint8_t uri_paths_len;
41 
42 	/* PIV of the subscription request. */
43 	uint8_t request_piv[MAX_PIV_LEN];
44 	uint8_t request_piv_len;
45 
46 	/* KID of the subscription request. */
47 	uint8_t request_kid[MAX_KID_LEN];
48 	uint8_t request_kid_len;
49 
50 	/* True if given record is occupied (used in interactions array). */
51 	bool is_occupied;
52 };
53 
54 /**
55  * @brief Initialize interactions array.
56  *
57  * @param interactions Interactions array, MUST have exactly OSCORE_INTERACTIONS_COUNT elements.
58  * @return enum err ok, or error if failed.
59  */
60 enum err oscore_interactions_init(struct oscore_interaction_t *interactions);
61 
62 /**
63  * @brief Add new record to the interactions array, or replace the old one if it exists (URI paths field is used for comparison).
64  * @note To be used while registering to given resource.
65  * @param interactions Interactions array, MUST have exactly OSCORE_INTERACTIONS_COUNT elements.
66  * @param record Single record to be added or updated.
67  * @return enum err ok, or error if failed.
68  */
69 enum err
70 oscore_interactions_set_record(struct oscore_interaction_t *interactions,
71 			       struct oscore_interaction_t *record);
72 
73 /**
74  * @brief Search for the record matching given token and return a pointer to it.
75  * @note To be used while encrypting a notification on the server side, and confirming its AAD on the client side.
76  * @param interactions Interactions array, MUST have exactly OSCORE_INTERACTIONS_COUNT elements.
77  * @param token Token buffer to match.
78  * @param token_len Token buffer size.
79  * @param record [out] Pointer to the matching record.
80  * @return enum err ok, or error if failed.
81  */
82 enum err
83 oscore_interactions_get_record(struct oscore_interaction_t *interactions,
84 			       uint8_t *token, uint8_t token_len,
85 			       struct oscore_interaction_t **record);
86 
87 /**
88  * @brief Remove a record that matches given URI paths field.
89  * @note To be used while de-registering to given resource.
90  * @param interactions Interactions array, MUST have exactly OSCORE_INTERACTIONS_COUNT elements.
91  * @param token Token buffer to match.
92  * @param token_len Token buffer size.
93  * @return enum err ok, or error if failed.
94  */
95 enum err
96 oscore_interactions_remove_record(struct oscore_interaction_t *interactions,
97 				  uint8_t *token, uint8_t token_len);
98 
99 /**
100  * @brief Wrapper for handling OSCORE interactions to be executed before main encryption/decryption logic.
101  *
102  * @param msg_type Message type of the packet.
103  * @param token Token byte array. MUST NOT be NULL, but can be empty.
104  * @param interactions Interactions array, MUST have exactly OSCORE_INTERACTIONS_COUNT elements.
105  * @param request_piv Output request_piv (to be updated if needed).
106  * @param request_kid Output request_kid (to be updated if needed).
107  * @return enum err ok, or error if failed.
108  */
109 enum err oscore_interactions_read_wrapper(
110 	enum o_coap_msg msg_type, struct byte_array *token,
111 	struct oscore_interaction_t *interactions,
112 	struct byte_array *request_piv, struct byte_array *request_kid);
113 
114 /**
115  * @brief Wrapper for handling OSCORE interactions to be executed after main encryption/decryption logic.
116  *
117  * @param msg_type Message type of the packet.
118  * @param token Token byte array. MUST NOT be NULL, but can be empty.
119  * @param uri_paths URI Paths byte array. MUST NOT be null, but can be empty.
120  * @param interactions Interactions array, MUST have exactly OSCORE_INTERACTIONS_COUNT elements.
121  * @param request_piv Current value of request_piv.
122  * @param request_kid Current value of request_kid.
123  * @return enum err ok, or error if failed.
124  */
125 enum err oscore_interactions_update_wrapper(
126 	enum o_coap_msg msg_type, struct byte_array *token,
127 	struct byte_array *uri_paths, struct oscore_interaction_t *interactions,
128 	struct byte_array *request_piv, struct byte_array *request_kid);
129 
130 #endif
131