libcoap 4.3.4-develop-15bf66c
oscore_cbor.c
Go to the documentation of this file.
1/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
3/*
4 * Copyright (c) 2018, SICS, RISE AB
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Institute nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 */
32
47#include "coap3/coap_internal.h"
48#include <string.h>
49
50static void
51util_write_byte(uint8_t **buffer, size_t *buf_size, uint8_t value) {
52 assert(*buf_size >= 1);
53 (*buf_size)--;
54 **buffer = value;
55 (*buffer)++;
56}
57
58size_t
59oscore_cbor_put_nil(uint8_t **buffer, size_t *buf_size) {
60 util_write_byte(buffer, buf_size, 0xF6);
61 return 1;
62}
63
64size_t
65oscore_cbor_put_true(uint8_t **buffer, size_t *buf_size) {
66 util_write_byte(buffer, buf_size, 0xF5);
67 return 1;
68}
69
70size_t
71oscore_cbor_put_false(uint8_t **buffer, size_t *buf_size) {
72 util_write_byte(buffer, buf_size, 0xF4);
73 return 1;
74}
75
76size_t
77oscore_cbor_put_text(uint8_t **buffer,
78 size_t *buf_size,
79 const char *text,
80 size_t text_len) {
81 uint8_t *pt = *buffer;
82 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, text_len);
83 assert(*buf_size >= text_len);
84 (*buf_size) -= text_len;
85 *pt = (*pt | 0x60);
86 memcpy(*buffer, text, text_len);
87 (*buffer) += text_len;
88 return nb + text_len;
89}
90
91size_t
92oscore_cbor_put_array(uint8_t **buffer, size_t *buf_size, size_t elements) {
93 uint8_t *pt = *buffer;
94 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, elements);
95 *pt = (*pt | 0x80);
96 return nb;
97}
98
99size_t
100oscore_cbor_put_bytes(uint8_t **buffer,
101 size_t *buf_size,
102 const uint8_t *bytes,
103 size_t bytes_len) {
104 uint8_t *pt = *buffer;
105 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, bytes_len);
106 assert(*buf_size >= bytes_len);
107 (*buf_size) -= bytes_len;
108 *pt = (*pt | 0x40);
109 memcpy(*buffer, bytes, bytes_len);
110 (*buffer) += bytes_len;
111 return nb + bytes_len;
112}
113
114size_t
115oscore_cbor_put_map(uint8_t **buffer, size_t *buf_size, size_t elements) {
116 uint8_t *pt = *buffer;
117 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, elements);
118 *pt = (*pt | 0xa0);
119 return nb;
120}
121
122size_t
123oscore_cbor_put_number(uint8_t **buffer, size_t *buf_size, int64_t value) {
124 if (value < 0)
125 return oscore_cbor_put_negative(buffer, buf_size, -value);
126 else
127 return oscore_cbor_put_unsigned(buffer, buf_size, value);
128}
129
130size_t
132 size_t *buf_size,
133 uint8_t value) {
134 uint8_t *pt = *buffer;
135 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, value);
136 *pt = (*pt | 0xe0);
137 return nb;
138}
139
140size_t
141oscore_cbor_put_tag(uint8_t **buffer, size_t *buf_size, uint64_t value) {
142 uint8_t *pt = *buffer;
143 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, value);
144 *pt = (*pt | 0xc0);
145 return nb;
146}
147
148size_t
149oscore_cbor_put_negative(uint8_t **buffer, size_t *buf_size, int64_t value) {
150 value--;
151 uint8_t *pt = *buffer;
152 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, value);
153 *pt = (*pt | 0x20);
154 return nb;
155}
156
157static void
158put_b_f(uint8_t **buffer, uint64_t value, uint8_t nr) {
159 uint8_t *pt = *buffer - 1;
160 uint64_t vv = value;
161 for (int q = nr; q > -1; q--) {
162 (*pt--) = (uint8_t)(vv & 0xff);
163 vv = (vv >> 8);
164 }
165}
166
167size_t
168oscore_cbor_put_unsigned(uint8_t **buffer, size_t *buf_size, uint64_t value) {
169 if (value < 0x18) { /* small value half a byte */
170 assert(*buf_size >= 1);
171 (*buf_size)--;
172 (**buffer) = (uint8_t)value;
173 (*buffer)++;
174 return 1;
175 } else if ((value > 0x17) && (value < 0x100)) {
176 /* one byte uint8_t */
177 assert(*buf_size >= 2);
178 (*buf_size) -= 2;
179 (**buffer) = (0x18);
180 *buffer = (*buffer) + 2;
181 put_b_f(buffer, value, 0);
182 return 2;
183 } else if ((value > 0xff) && (value < 0x10000)) {
184 /* 2 bytes uint16_t */
185 assert(*buf_size >= 3);
186 (*buf_size) -= 3;
187 (**buffer) = (0x19);
188 *buffer = (*buffer) + 3;
189 put_b_f(buffer, value, 1);
190 return 3;
191 } else if ((value > 0xffff) && (value < 0x100000000)) {
192 /* 4 bytes uint32_t */
193 assert(*buf_size >= 5);
194 (*buf_size) -= 5;
195 (**buffer) = (0x1a);
196 *buffer = (*buffer) + 5;
197 put_b_f(buffer, value, 3);
198 return 5;
199 } else { /*if(value > 0xffffffff)*/
200 /* 8 bytes uint64_t */
201 assert(*buf_size >= 9);
202 (*buf_size) -= 9;
203 (**buffer) = (0x1b);
204 *buffer = (*buffer) + 9;
205 put_b_f(buffer, value, 7);
206 return 9;
207 }
208}
209
210static uint8_t
211get_byte(const uint8_t **buffer, size_t *buf_len) {
212#if NDEBUG
213 (void)buf_len;
214#endif /* NDEBUG */
215 assert((*buf_len) > 0);
216 return (*buffer)[0];
217}
218
219static uint8_t
220get_byte_inc(const uint8_t **buffer, size_t *buf_len) {
221 assert((*buf_len) > 0);
222 (*buf_len)--;
223 return ((*buffer)++)[0];
224}
225
226uint8_t
227oscore_cbor_get_next_element(const uint8_t **buffer, size_t *buf_len) {
228 uint8_t element = get_byte(buffer, buf_len);
229 return element >> 5;
230}
231
232/* oscore_cbor_get_element_size returns
233 * - size of byte strings of character strings
234 * - size of array
235 * - size of map
236 * - value of unsigned integer
237 */
238
239size_t
240oscore_cbor_get_element_size(const uint8_t **buffer, size_t *buf_len) {
241 uint8_t control = get_byte_inc(buffer, buf_len) & 0x1f;
242 size_t size;
243
244 if (control < 0x18) {
245 size = (uint64_t)control;
246 } else {
247 control = control & 0x3;
248 int num = 1 << control;
249 size = 0;
250 size_t getal;
251 for (int i = 0; i < num; i++) {
252 getal = get_byte_inc(buffer, buf_len);
253 size = (size << 8) + getal;
254 }
255 }
256 return size;
257}
258
259uint8_t
260oscore_cbor_elem_contained(const uint8_t *data, size_t *buf_len, uint8_t *end) {
261 const uint8_t *buf = data;
262 const uint8_t *last = data + oscore_cbor_get_element_size(&buf, buf_len);
263 if (last > end) {
264 coap_log_err("oscore_cbor_elem_contained returns 1 \n");
265 return 1;
266 } else
267 return 0;
268}
269
270int64_t
271oscore_cbor_get_negative_integer(const uint8_t **buffer, size_t *buf_len) {
272 return -(int64_t)(oscore_cbor_get_element_size(buffer, buf_len) + 1);
273}
274
275uint64_t
276oscore_cbor_get_unsigned_integer(const uint8_t **buffer, size_t *buf_len) {
277 return oscore_cbor_get_element_size(buffer, buf_len);
278}
279
280/*
281 * oscore_cbor_get_number
282 *
283 * gets a negative or positive number from data
284 * OK: return 0 ; NOK: return 1
285 */
286uint8_t
287oscore_cbor_get_number(const uint8_t **data, size_t *buf_len, int64_t *value) {
288 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
289 if (elem == CBOR_UNSIGNED_INTEGER) {
290 *value = oscore_cbor_get_unsigned_integer(data, buf_len);
291 return 0;
292 } else if (elem == CBOR_NEGATIVE_INTEGER) {
293 *value = oscore_cbor_get_negative_integer(data, buf_len);
294 return 0;
295 } else
296 return 1;
297}
298
299/*
300 * oscore_cbor_get_simple_value
301 *
302 * gets a simple value from data
303 * OK: return 0 ; NOK: return 1
304 */
305uint8_t
306oscore_cbor_get_simple_value(const uint8_t **data, size_t *buf_len, uint8_t *value) {
307 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
308 if (elem == CBOR_SIMPLE_VALUE) {
309 *value = get_byte_inc(data, buf_len) & 0x1f;
310 return 0;
311 } else
312 return 1;
313}
314
315void
316oscore_cbor_get_string(const uint8_t **buffer, size_t *buf_len, char *str, size_t size) {
317 (void)buf_len;
318 for (size_t i = 0; i < size; i++) {
319 *str++ = (char)get_byte_inc(buffer, buf_len);
320 }
321}
322
323void
324oscore_cbor_get_array(const uint8_t **buffer, size_t *buf_len, uint8_t *arr, size_t size) {
325 (void)buf_len;
326 for (size_t i = 0; i < size; i++) {
327 *arr++ = get_byte_inc(buffer, buf_len);
328 }
329}
330
331/* oscore_cbor_get_string_array
332 * fills the the size and the array from the cbor element
333 */
334uint8_t
335oscore_cbor_get_string_array(const uint8_t **data, size_t *buf_len,
336 uint8_t **result,
337 size_t *len) {
338
339 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
340 *len = oscore_cbor_get_element_size(data, buf_len);
341 *result = NULL;
342 void *rs = coap_malloc_type(COAP_STRING, *len);
343 *result = (uint8_t *)rs;
344 if (elem == CBOR_TEXT_STRING) {
345 oscore_cbor_get_string(data, buf_len, (char *)*result, *len);
346 return 0;
347 } else if (elem == CBOR_BYTE_STRING) {
348 oscore_cbor_get_array(data, buf_len, *result, *len);
349 return 0; /* all is well */
350 } else {
351 free(*result);
352 *result = NULL;
353 return 1; /* failure */
354 }
355}
356
357/* oscore_cbor_skip value
358 * returns number of CBOR bytes
359 */
360static size_t
361oscore_cbor_skip_value(const uint8_t **data, size_t *buf_len) {
362 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
363 uint8_t control = get_byte(data, buf_len) & 0x1f;
364 size_t nb = 0; /* number of elements in array or map */
365 size_t num = 0; /* number of bytes of length or number */
366 size_t size = 0; /* size of value to be skipped */
367 if (control < 0x18) {
368 num = 1;
369 } else {
370 control = control & 0x3;
371 num = 1 + (1 << control);
372 }
373 switch (elem) {
376 assert((*buf_len) >= num);
377 *buf_len -= num;
378 *data = *data + num;
379 size = num;
380 break;
381 case CBOR_BYTE_STRING:
382 case CBOR_TEXT_STRING:
383 size = num;
384 size += oscore_cbor_get_element_size(data, buf_len);
385 assert((*buf_len) >= (size - num));
386 *buf_len -= (size - num);
387 (*data) = (*data) + size - num;
388 break;
389 case CBOR_ARRAY:
390 nb = oscore_cbor_get_element_size(data, buf_len);
391 size = num;
392 for (uint16_t qq = 0; qq < nb; qq++)
393 size += oscore_cbor_skip_value(data, buf_len);
394 break;
395 case CBOR_MAP:
396 nb = oscore_cbor_get_element_size(data, buf_len);
397 size = num;
398 for (uint16_t qq = 0; qq < nb; qq++) {
399 size += oscore_cbor_skip_value(data, buf_len);
400 size += oscore_cbor_skip_value(data, buf_len);
401 }
402 break;
403 case CBOR_TAG:
404 assert((*buf_len) >= 1);
405 *buf_len -= 1;
406 (*data)++;
407 size = 1;
408 break;
409 default:
410 return 0;
411 break;
412 } /* switch */
413 return size;
414}
415
416/* oscore_cbor_strip value
417 * strips the value of the cbor element into result
418 * and returns size
419 */
420uint8_t
421oscore_cbor_strip_value(const uint8_t **data, size_t *buf_len, uint8_t **result, size_t *len) {
422 const uint8_t *st_data = *data;
423 size_t size = oscore_cbor_skip_value(data, buf_len);
424 *result = coap_malloc_type(COAP_STRING, size);
425 for (uint16_t qq = 0; qq < size; qq++)
426 (*result)[qq] = st_data[qq];
427 *len = size;
428 return 0;
429}
Pulls together all the internal only header files.
@ COAP_STRING
Definition: coap_mem.h:38
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
#define coap_log_err(...)
Definition: coap_debug.h:96
#define CBOR_BYTE_STRING
Definition: oscore_cbor.h:62
size_t oscore_cbor_put_text(uint8_t **buffer, size_t *buf_size, const char *text, size_t text_len)
Definition: oscore_cbor.c:77
#define CBOR_TAG
Definition: oscore_cbor.h:66
size_t oscore_cbor_get_element_size(const uint8_t **buffer, size_t *buf_len)
Definition: oscore_cbor.c:240
#define CBOR_NEGATIVE_INTEGER
Definition: oscore_cbor.h:61
int64_t oscore_cbor_get_negative_integer(const uint8_t **buffer, size_t *buf_len)
Definition: oscore_cbor.c:271
#define CBOR_TEXT_STRING
Definition: oscore_cbor.h:63
#define CBOR_SIMPLE_VALUE
Definition: oscore_cbor.h:67
size_t oscore_cbor_put_number(uint8_t **buffer, size_t *buf_size, int64_t value)
Definition: oscore_cbor.c:123
size_t oscore_cbor_put_simple_value(uint8_t **buffer, size_t *buf_size, uint8_t value)
Definition: oscore_cbor.c:131
uint8_t oscore_cbor_get_string_array(const uint8_t **data, size_t *buf_len, uint8_t **result, size_t *len)
Definition: oscore_cbor.c:335
#define CBOR_UNSIGNED_INTEGER
Definition: oscore_cbor.h:60
uint8_t oscore_cbor_strip_value(const uint8_t **data, size_t *buf_len, uint8_t **result, size_t *len)
Definition: oscore_cbor.c:421
size_t oscore_cbor_put_nil(uint8_t **buffer, size_t *buf_size)
Definition: oscore_cbor.c:59
void oscore_cbor_get_string(const uint8_t **buffer, size_t *buf_len, char *str, size_t size)
Definition: oscore_cbor.c:316
uint8_t oscore_cbor_get_simple_value(const uint8_t **data, size_t *buf_len, uint8_t *value)
Definition: oscore_cbor.c:306
size_t oscore_cbor_put_false(uint8_t **buffer, size_t *buf_size)
Definition: oscore_cbor.c:71
uint8_t oscore_cbor_get_next_element(const uint8_t **buffer, size_t *buf_len)
Definition: oscore_cbor.c:227
size_t oscore_cbor_put_negative(uint8_t **buffer, size_t *buf_size, int64_t value)
Definition: oscore_cbor.c:149
size_t oscore_cbor_put_true(uint8_t **buffer, size_t *buf_size)
Definition: oscore_cbor.c:65
size_t oscore_cbor_put_unsigned(uint8_t **buffer, size_t *buf_size, uint64_t value)
Definition: oscore_cbor.c:168
size_t oscore_cbor_put_bytes(uint8_t **buffer, size_t *buf_size, const uint8_t *bytes, size_t bytes_len)
Definition: oscore_cbor.c:100
void oscore_cbor_get_array(const uint8_t **buffer, size_t *buf_len, uint8_t *arr, size_t size)
Definition: oscore_cbor.c:324
uint64_t oscore_cbor_get_unsigned_integer(const uint8_t **buffer, size_t *buf_len)
Definition: oscore_cbor.c:276
uint8_t oscore_cbor_elem_contained(const uint8_t *data, size_t *buf_len, uint8_t *end)
Definition: oscore_cbor.c:260
uint8_t oscore_cbor_get_number(const uint8_t **data, size_t *buf_len, int64_t *value)
Definition: oscore_cbor.c:287
#define CBOR_MAP
Definition: oscore_cbor.h:65
#define CBOR_ARRAY
Definition: oscore_cbor.h:64
size_t oscore_cbor_put_array(uint8_t **buffer, size_t *buf_size, size_t elements)
Definition: oscore_cbor.c:92
size_t oscore_cbor_put_map(uint8_t **buffer, size_t *buf_size, size_t elements)
Definition: oscore_cbor.c:115
size_t oscore_cbor_put_tag(uint8_t **buffer, size_t *buf_size, uint64_t value)
Definition: oscore_cbor.c:141
static uint8_t get_byte(const uint8_t **buffer, size_t *buf_len)
Definition: oscore_cbor.c:211
static uint8_t get_byte_inc(const uint8_t **buffer, size_t *buf_len)
Definition: oscore_cbor.c:220
static void util_write_byte(uint8_t **buffer, size_t *buf_size, uint8_t value)
Definition: oscore_cbor.c:51
static void put_b_f(uint8_t **buffer, uint64_t value, uint8_t nr)
Definition: oscore_cbor.c:158
static size_t oscore_cbor_skip_value(const uint8_t **data, size_t *buf_len)
Definition: oscore_cbor.c:361