1 /* 2 Copyright (c) 2021 Fraunhofer AISEC. 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 OPTION_H 13 #define OPTION_H 14 15 #include <stdint.h> 16 17 #include "oscore_coap.h" 18 19 #include "common/byte_array.h" 20 #include "common/oscore_edhoc_error.h" 21 22 #define OPT_SERIAL_OVERHEAD 5 23 24 enum o_num { 25 IF_MATCH = 1, 26 URI_HOST = 3, 27 ETAG = 4, 28 IF_NONE_MATCH = 5, 29 OBSERVE = 6, 30 URI_PORT = 7, 31 LOCATION_PATH = 8, 32 OSCORE = 9, 33 URI_PATH = 11, 34 CONTENT_FORMAT = 12, 35 MAX_AGE = 14, 36 URI_QUERY = 15, 37 ACCEPT = 17, 38 LOCATION_QUERY = 20, 39 BLOCK2 = 23, 40 BLOCK1 = 27, 41 SIZE2 = 28, 42 PROXY_URI = 35, 43 PROXY_SCHEME = 39, 44 SIZE1 = 60, 45 ECHO = 252, 46 }; 47 48 enum option_class { 49 CLASS_U, /*unprotected*/ 50 CLASS_I, /*integrity protected only*/ 51 CLASS_E, /*encrypted and integrity protected*/ 52 }; 53 54 /** 55 * @brief Returns whether the CoAP Option with given `code` is a 56 * Class E Option (encrypted) 57 * @param code CoAP Option's code 58 * @return true if the option is a Class E Option 59 */ 60 bool is_class_e(uint16_t code); 61 62 /** 63 * @brief Parses the passed options until the payload marker of end of 64 * array and writes them into @a out. 65 * Returns the number of parsed options and writes the number of 66 * bytes consumed into @a offset_out. If @a out is NULL, this function 67 * doesn't write parsed options, but still returns the number 68 * of options. 69 * @param options 70 * @param out Out-array. Must be at least `num_options(...)` long or NULL. 71 * @param offset_out Pointer to write byte-length of options into. 72 * Can be NULL. 73 * @return err 74 */ 75 enum err decode_options(struct byte_array options, struct o_coap_option *out, 76 uint16_t *offset_out); 77 78 /** 79 * @brief Returns the length in bytes of the serialized options 80 * of given class. 81 * @param options CoAP Option array containing all options 82 * (possibly including ones of other classes) 83 * @param opt_num Number of CoAP options in @a options. 84 * @param class Class of the options to encode 85 * @return length in bytes 86 */ 87 uint32_t encoded_option_len(struct o_coap_option *options, uint16_t opt_num, 88 enum option_class class); 89 90 /** 91 * @brief Encodes all options in given array having given class. 92 * @param options CoAP Option array containing all options 93 * (possibly including ones of other classes) 94 * @param opt_num Number of CoAP options in @a options. 95 * @param class Class of the options to encode 96 * @param out out-pointer. Must be at least `encoded_option_len(...)` 97 * bytes long. 98 * @param out_buf_len the length of of the out buffer 99 * @return err 100 */ 101 enum err encode_options(struct o_coap_option *options, uint16_t opt_num, 102 enum option_class class, uint8_t *out, 103 uint32_t out_buf_len); 104 105 /** 106 * @brief Checks if an array of options contains a observe option 107 * @param options pointer to an array of options. This can be an array 108 * containing all options of an input CoAP packet, the inner or 109 * outer options of an OSCORE packet. This is because the observe 110 * option is contained in all of the above collections 111 * @param options_cnt number of entries in the array 112 */ 113 bool is_observe(struct o_coap_option *options, uint8_t options_cnt); 114 115 /** 116 * @brief Returns the value of OBSERVE option. 117 * @param options Options array. 118 * @param options_cnt Number of entries in the array. 119 * @param output Pointer to byte array which will point to the value buffer. 120 * Set to NULL if not found. 121 * @return true if found, false if not. 122 */ 123 bool get_observe_value(struct o_coap_option *options, uint8_t options_cnt, 124 struct byte_array *output); 125 126 /** 127 * @brief Saves an ECHO option value to be compared later with an ECHO value 128 * received from the client. 129 * @param dest location to save the ECHO value 130 * @param options E options 131 * @param options_cnt the number of the options 132 * @retval error code 133 * 134 */ 135 enum err cache_echo_val(struct byte_array *dest, struct o_coap_option *options, 136 uint8_t options_cnt); 137 138 /** 139 * @brief Checks if an ECHO value is fresh. It takes a decrypted payload and 140 * search in it for an ECHO option. If such is find it compares it 141 * to the cached one. 142 * @param cache_value previously saved ECHO value 143 * @param decrypted_payload the decrypted payload of the message 144 * @retval error code 145 */ 146 enum err echo_val_is_fresh(struct byte_array *cache_val, 147 struct byte_array *decrypted_payload); 148 149 /** 150 * @brief Parse the decrypted OSCORE payload into code, E-options and original unprotected CoAP payload 151 * @param in_payload: input decrypted payload 152 * @param out_code: pointer to code number of the request 153 * @param out_E_options: output pointer to an array of E-options 154 * @param E_options_cnt: count number of E-options 155 * @param out_o_coap_payload: output pointer original unprotected CoAP payload 156 * @return err 157 */ 158 enum err oscore_decrypted_payload_parser(struct byte_array *in_payload, 159 uint8_t *out_code, 160 struct o_coap_option *out_E_options, 161 uint8_t *E_options_cnt, 162 struct byte_array *out_o_coap_payload); 163 164 /** 165 * @brief Compose URI Path (resource name) from given options array. 166 * Implemented based on RFC7252 section 6.5 (partial compliance limited to the library's needs only). 167 * @param options Options array. 168 * @param options_size Options array size (number of items). 169 * @param uri_path Output pointer to write composed URI Path into. 170 * @param uri_path_size Maximum size of the allocated URI Path buffer (input), actual URI Path length (output). 171 * @return ok or error code 172 */ 173 enum err uri_path_create(struct o_coap_option *options, uint32_t options_size, 174 uint8_t *uri_path, uint32_t *uri_path_size); 175 176 #endif 177