LCOV - code coverage report
Current view: top level - src/oscore - option.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 75 78 96.2 %
Date: 2024-09-16 20:15:30 Functions: 8 8 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 48 62 77.4 %

           Branch data     Line data    Source code
       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                 :            : #include <string.h>
      13                 :            : 
      14                 :            : #include "oscore/option.h"
      15                 :            : #include "oscore/oscore_coap.h"
      16                 :            : 
      17                 :            : #include "common/memcpy_s.h"
      18                 :            : 
      19                 :            : /**
      20                 :            :  * @brief Securely append a substring to given buffer.
      21                 :            :  * 
      22                 :            :  * @param buffer Buffer to have the substring appended.
      23                 :            :  * @param current_size Current size of the buffer content. Updated after successfull append.
      24                 :            :  * @param max_size Memory size allocated for the buffer.
      25                 :            :  * @param substring Substring buffer to be appended.
      26                 :            :  * @param substring_size Substring size.
      27                 :            :  * @return ok or error
      28                 :            :  */
      29                 :         28 : static enum err buffer_append(uint8_t *buffer, uint32_t *current_size,
      30                 :            :                               uint32_t max_size, const uint8_t *substring,
      31                 :            :                               uint32_t substring_size)
      32                 :            : {
      33                 :         28 :         uint8_t *destination =
      34                 :         28 :                 &buffer[*current_size]; //pointer to current end of the content
      35                 :         28 :         uint32_t remaining_size =
      36                 :            :                 max_size -
      37                 :         28 :                 (*current_size); //how many bytes in the buffer are still available
      38         [ -  + ]:         28 :         TRY(_memcpy_s(destination, remaining_size, substring, substring_size));
      39                 :         28 :         *current_size += substring_size;
      40                 :         28 :         return ok;
      41                 :            : }
      42                 :            : 
      43                 :         33 : bool is_class_e(uint16_t code)
      44                 :            : {
      45                 :            :         // blacklist, because OSCORE dictates that unknown options SHALL be processed as class E
      46   [ +  +  +  +  :         29 :         return code != URI_HOST && code != URI_PORT && code != OSCORE &&
                   +  + ]
      47   [ +  +  +  + ]:         62 :                code != PROXY_URI && code != PROXY_SCHEME;
      48                 :            : }
      49                 :            : 
      50                 :         24 : bool is_observe(struct o_coap_option *options, uint8_t options_cnt)
      51                 :            : {
      52         [ +  + ]:         32 :         for (uint8_t i = 0; i < options_cnt; i++) {
      53         [ +  + ]:         14 :                 if (options[i].option_number == OBSERVE) {
      54                 :          6 :                         return true;
      55                 :            :                 }
      56                 :            :         }
      57                 :         18 :         return false;
      58                 :            : }
      59                 :            : 
      60                 :         41 : bool get_observe_value(struct o_coap_option *options, uint8_t options_cnt,
      61                 :            :                        struct byte_array *output)
      62                 :            : {
      63   [ +  -  -  + ]:         41 :         if ((NULL == options) || (NULL == output)) {
      64                 :          0 :                 return false;
      65                 :            :         }
      66                 :            : 
      67         [ +  + ]:         79 :         for (uint8_t i = 0; i < options_cnt; i++) {
      68         [ +  + ]:         44 :                 if (OBSERVE != options[i].option_number) {
      69                 :         38 :                         continue;
      70                 :            :                 }
      71                 :            : 
      72                 :          6 :                 output->ptr = options[i].value;
      73                 :          6 :                 output->len = options[i].len;
      74                 :          6 :                 return true;
      75                 :            :         }
      76                 :         35 :         output = NULL;
      77                 :         35 :         return false;
      78                 :            : }
      79                 :            : 
      80                 :          6 : enum err cache_echo_val(struct byte_array *dest, struct o_coap_option *options,
      81                 :            :                         uint8_t options_cnt)
      82                 :            : {
      83         [ +  + ]:         12 :         for (uint8_t i = 0; i < options_cnt; i++) {
      84         [ +  + ]:         10 :                 if (options[i].option_number == ECHO) {
      85                 :          4 :                         PRINT_MSG("Caching the ECHO value!\n");
      86         [ -  + ]:          4 :                         TRY(_memcpy_s(dest->ptr, dest->len, options[i].value,
      87                 :            :                                       options[i].len));
      88                 :          4 :                         dest->len = options[i].len;
      89                 :          4 :                         return ok;
      90                 :            :                 }
      91                 :            :         }
      92                 :          2 :         return no_echo_option;
      93                 :            : }
      94                 :            : 
      95                 :         18 : enum err oscore_decrypted_payload_parser(struct byte_array *in_payload,
      96                 :            :                                          uint8_t *out_code,
      97                 :            :                                          struct o_coap_option *out_E_options,
      98                 :            :                                          uint8_t *E_options_cnt,
      99                 :            :                                          struct byte_array *out_o_coap_payload)
     100                 :            : {
     101                 :         18 :         uint8_t *temp_payload_ptr = in_payload->ptr;
     102                 :         18 :         uint32_t temp_payload_len = in_payload->len;
     103                 :            : 
     104                 :            :         /* Code */
     105                 :         18 :         *out_code = *(temp_payload_ptr++);
     106                 :         18 :         temp_payload_len--;
     107                 :            : 
     108                 :         18 :         struct byte_array remaining_bytes =
     109                 :            :                 BYTE_ARRAY_INIT(temp_payload_ptr, temp_payload_len);
     110         [ -  + ]:         18 :         TRY(options_deserialize(&remaining_bytes, out_E_options, E_options_cnt,
     111                 :            :                                 out_o_coap_payload));
     112                 :            : 
     113                 :         18 :         return ok;
     114                 :            : }
     115                 :            : 
     116                 :          5 : enum err echo_val_is_fresh(struct byte_array *cache_val,
     117                 :            :                            struct byte_array *decrypted_payload)
     118                 :            : {
     119                 :          5 :         uint8_t code = 0;
     120                 :            :         struct byte_array unprotected_o_coap_payload;
     121                 :            : 
     122                 :            :         struct o_coap_option E_options[10];
     123                 :          5 :         uint8_t E_options_cnt = 0;
     124                 :            : 
     125                 :            :         /* Parse decrypted payload: code + options + unprotected CoAP payload*/
     126         [ -  + ]:          5 :         TRY(oscore_decrypted_payload_parser(decrypted_payload, &code, E_options,
     127                 :            :                                             &E_options_cnt,
     128                 :            :                                             &unprotected_o_coap_payload));
     129                 :            : 
     130         [ +  + ]:          7 :         for (uint8_t i = 0; i < E_options_cnt; i++) {
     131         [ +  + ]:          5 :                 if (E_options[i].option_number == ECHO) {
     132         [ +  - ]:          3 :                         if (cache_val->len == E_options[i].len &&
     133         [ +  + ]:          3 :                             0 == memcmp(E_options[i].value, cache_val->ptr, cache_val->len) ) {
     134                 :          1 :                                 PRINT_MSG("ECHO option check -- OK\n");
     135                 :          1 :                                 return ok;
     136                 :            :                         } else {
     137                 :          2 :                                 return echo_val_mismatch;
     138                 :            :                         }
     139                 :            :                 }
     140                 :            :         }
     141                 :            : 
     142                 :          2 :         return no_echo_option;
     143                 :            : }
     144                 :            : 
     145                 :            : 
     146                 :         28 : enum err uri_path_create(struct o_coap_option *options, uint32_t options_size,
     147                 :            :                          uint8_t *uri_path, uint32_t *uri_path_size)
     148                 :            : {
     149   [ +  -  +  -  :         28 :         if ((NULL == options) || (NULL == uri_path) ||
                   -  + ]
     150                 :            :             (NULL == uri_path_size)) {
     151                 :          0 :                 return wrong_parameter;
     152                 :            :         }
     153                 :            : 
     154                 :         28 :         uint32_t current_size = 0;
     155                 :         28 :         uint32_t max_size = *uri_path_size;
     156                 :         28 :         memset(uri_path, 0, max_size);
     157                 :            : 
     158                 :         28 :         const uint8_t delimiter = '/';
     159                 :         28 :         const uint32_t delimiter_size = 1;
     160                 :            : 
     161         [ +  + ]:         60 :         for (uint32_t index = 0; index < options_size; index++) {
     162                 :         32 :                 struct o_coap_option *option = &options[index];
     163         [ +  + ]:         32 :                 if (URI_PATH != option->option_number) {
     164                 :         18 :                         continue;
     165                 :            :                 }
     166   [ +  -  -  + ]:         14 :                 if ((0 != option->len) && (NULL == option->value)) {
     167                 :          0 :                         return oscore_wrong_uri_path;
     168                 :            :                 }
     169                 :            : 
     170         [ -  + ]:         14 :                 TRY(buffer_append(uri_path, &current_size, max_size,
     171                 :            :                                   option->value, option->len));
     172         [ -  + ]:         14 :                 TRY(buffer_append(uri_path, &current_size, max_size, &delimiter,
     173                 :            :                                   delimiter_size));
     174                 :            :         }
     175                 :            : 
     176                 :            :         /* Remove last '/' character, or add a single one if the path is empty */
     177         [ +  + ]:         28 :         if (current_size > 0) {
     178                 :         14 :                 uri_path[current_size] = 0;
     179                 :         14 :                 current_size--;
     180                 :            :         } else {
     181                 :         14 :                 uri_path[0] = delimiter;
     182                 :         14 :                 current_size = delimiter_size;
     183                 :            :         }
     184                 :            : 
     185                 :         28 :         *uri_path_size = current_size;
     186                 :         28 :         return ok;
     187                 :            : }

Generated by: LCOV version 1.14