libcoap 4.3.5-develop-f52fada
Loading...
Searching...
No Matches
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
46
48
49#if COAP_OSCORE_SUPPORT
50
51#include <string.h>
52
53static void
54util_write_byte(uint8_t **buffer, size_t *buf_size, uint8_t value) {
55 assert(*buf_size >= 1);
56 if (*buf_size < 1)
57 return;
58 (*buf_size)--;
59 **buffer = value;
60 (*buffer)++;
61}
62
63size_t
64oscore_cbor_put_nil(uint8_t **buffer, size_t *buf_size) {
65 util_write_byte(buffer, buf_size, 0xF6);
66 return 1;
67}
68
69size_t
70oscore_cbor_put_true(uint8_t **buffer, size_t *buf_size) {
71 util_write_byte(buffer, buf_size, 0xF5);
72 return 1;
73}
74
75size_t
76oscore_cbor_put_false(uint8_t **buffer, size_t *buf_size) {
77 util_write_byte(buffer, buf_size, 0xF4);
78 return 1;
79}
80
81size_t
82oscore_cbor_put_text(uint8_t **buffer,
83 size_t *buf_size,
84 const char *text,
85 size_t text_len) {
86 uint8_t *pt = *buffer;
87 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, text_len);
88 assert(*buf_size >= text_len);
89 if (*buf_size < text_len)
90 return nb;
91 (*buf_size) -= text_len;
92 *pt = (*pt | 0x60);
93 memcpy(*buffer, text, text_len);
94 (*buffer) += text_len;
95 return nb + text_len;
96}
97
98size_t
99oscore_cbor_put_array(uint8_t **buffer, size_t *buf_size, size_t elements) {
100 uint8_t *pt = *buffer;
101 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, elements);
102 *pt = (*pt | 0x80);
103 return nb;
104}
105
106size_t
107oscore_cbor_put_bytes(uint8_t **buffer,
108 size_t *buf_size,
109 const uint8_t *bytes,
110 size_t bytes_len) {
111 uint8_t *pt = *buffer;
112 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, bytes_len);
113 assert(*buf_size >= bytes_len);
114 if (*buf_size < bytes_len)
115 return nb;
116 (*buf_size) -= bytes_len;
117 *pt = (*pt | 0x40);
118 if (bytes_len)
119 memcpy(*buffer, bytes, bytes_len);
120 (*buffer) += bytes_len;
121 return nb + bytes_len;
122}
123
124size_t
125oscore_cbor_put_map(uint8_t **buffer, size_t *buf_size, size_t elements) {
126 uint8_t *pt = *buffer;
127 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, elements);
128 *pt = (*pt | 0xa0);
129 return nb;
130}
131
132size_t
133oscore_cbor_put_number(uint8_t **buffer, size_t *buf_size, int64_t value) {
134 if (value < 0)
135 return oscore_cbor_put_negative(buffer, buf_size, -value);
136 else
137 return oscore_cbor_put_unsigned(buffer, buf_size, value);
138}
139
140size_t
141oscore_cbor_put_simple_value(uint8_t **buffer,
142 size_t *buf_size,
143 uint8_t value) {
144 uint8_t *pt = *buffer;
145 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, value);
146 *pt = (*pt | 0xe0);
147 return nb;
148}
149
150size_t
151oscore_cbor_put_tag(uint8_t **buffer, size_t *buf_size, uint64_t value) {
152 uint8_t *pt = *buffer;
153 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, value);
154 *pt = (*pt | 0xc0);
155 return nb;
156}
157
158size_t
159oscore_cbor_put_negative(uint8_t **buffer, size_t *buf_size, int64_t value) {
160 value--;
161 uint8_t *pt = *buffer;
162 size_t nb = oscore_cbor_put_unsigned(buffer, buf_size, value);
163 *pt = (*pt | 0x20);
164 return nb;
165}
166
167static void
168put_b_f(uint8_t **buffer, uint64_t value, uint8_t nr) {
169 uint8_t *pt = *buffer - 1;
170 uint64_t vv = value;
171 for (int q = nr; q > -1; q--) {
172 (*pt--) = (uint8_t)(vv & 0xff);
173 vv = (vv >> 8);
174 }
175}
176
177size_t
178oscore_cbor_put_unsigned(uint8_t **buffer, size_t *buf_size, uint64_t value) {
179 if (value < 0x18) { /* small value half a byte */
180 assert(*buf_size >= 1);
181 if (*buf_size < 1)
182 return 0;
183 (*buf_size)--;
184 (**buffer) = (uint8_t)value;
185 (*buffer)++;
186 return 1;
187 } else if ((value > 0x17) && (value < 0x100)) {
188 /* one byte uint8_t */
189 assert(*buf_size >= 2);
190 if (*buf_size < 2)
191 return 0;
192 (*buf_size) -= 2;
193 (**buffer) = (0x18);
194 *buffer = (*buffer) + 2;
195 put_b_f(buffer, value, 0);
196 return 2;
197 } else if ((value > 0xff) && (value < 0x10000)) {
198 /* 2 bytes uint16_t */
199 assert(*buf_size >= 3);
200 if (*buf_size < 3)
201 return 0;
202 (*buf_size) -= 3;
203 (**buffer) = (0x19);
204 *buffer = (*buffer) + 3;
205 put_b_f(buffer, value, 1);
206 return 3;
207 } else if ((value > 0xffff) && (value < 0x100000000)) {
208 /* 4 bytes uint32_t */
209 assert(*buf_size >= 5);
210 if (*buf_size < 5)
211 return 0;
212 (*buf_size) -= 5;
213 (**buffer) = (0x1a);
214 *buffer = (*buffer) + 5;
215 put_b_f(buffer, value, 3);
216 return 5;
217 } else { /*if(value > 0xffffffff)*/
218 /* 8 bytes uint64_t */
219 assert(*buf_size >= 9);
220 if (*buf_size < 9)
221 return 0;
222 (*buf_size) -= 9;
223 (**buffer) = (0x1b);
224 *buffer = (*buffer) + 9;
225 put_b_f(buffer, value, 7);
226 return 9;
227 }
228}
229
230static uint8_t
231get_byte(const uint8_t **buffer, size_t *buf_len) {
232 (void)buf_len;
233 if (*buf_len == 0)
234 return 0;
235 return (*buffer)[0];
236}
237
238static uint8_t
239get_byte_inc(const uint8_t **buffer, size_t *buf_len) {
240 if (*buf_len < 1)
241 return 0;
242 (*buf_len)--;
243 return ((*buffer)++)[0];
244}
245
246uint8_t
247oscore_cbor_get_next_element(const uint8_t **buffer, size_t *buf_len) {
248 uint8_t element = get_byte(buffer, buf_len);
249 return element >> 5;
250}
251
252/* oscore_cbor_get_element_size returns
253 * - size of byte strings of character strings
254 * - size of array
255 * - size of map
256 * - value of unsigned integer
257 */
258
259uint64_t
260oscore_cbor_get_element_size(const uint8_t **buffer, size_t *buf_len) {
261 uint8_t control = get_byte_inc(buffer, buf_len) & 0x1f;
262 uint64_t size;
263
264 if (control < 0x18) {
265 size = (uint64_t)control;
266 } else {
267 control = control & 0x3;
268 int num = 1 << control;
269 size = 0;
270 size_t getal;
271 for (int i = 0; i < num; i++) {
272 getal = get_byte_inc(buffer, buf_len);
273 size = (size << 8) + getal;
274 }
275 }
276 return size;
277}
278
279uint8_t
280oscore_cbor_elem_contained(const uint8_t *data, size_t *buf_len, uint8_t *end) {
281 const uint8_t *buf = data;
282 uint64_t size = oscore_cbor_get_element_size(&buf, buf_len);
283
284 if (size > 0xffffffff || data + size > end) {
285 coap_log_err("oscore_cbor_elem_contained returns 1 \n");
286 return 1;
287 } else
288 return 0;
289}
290
291int64_t
292oscore_cbor_get_negative_integer(const uint8_t **buffer, size_t *buf_len) {
293 return (int64_t)((uint64_t)(-1) - oscore_cbor_get_element_size(buffer, buf_len));
294}
295
296uint64_t
297oscore_cbor_get_unsigned_integer(const uint8_t **buffer, size_t *buf_len) {
298 return oscore_cbor_get_element_size(buffer, buf_len);
299}
300
301/*
302 * oscore_cbor_get_number
303 *
304 * gets a negative or positive number from data
305 * OK: return 0 ; NOK: return 1
306 */
307uint8_t
308oscore_cbor_get_number(const uint8_t **data, size_t *buf_len, int64_t *value) {
309 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
310 if (elem == CBOR_UNSIGNED_INTEGER) {
311 *value = oscore_cbor_get_unsigned_integer(data, buf_len);
312 return 0;
313 } else if (elem == CBOR_NEGATIVE_INTEGER) {
314 *value = oscore_cbor_get_negative_integer(data, buf_len);
315 return 0;
316 } else
317 return 1;
318}
319
320/*
321 * oscore_cbor_get_simple_value
322 *
323 * gets a simple value from data
324 * OK: return 0 ; NOK: return 1
325 */
326uint8_t
327oscore_cbor_get_simple_value(const uint8_t **data, size_t *buf_len, uint8_t *value) {
328 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
329 if (elem == CBOR_SIMPLE_VALUE) {
330 *value = get_byte_inc(data, buf_len) & 0x1f;
331 return 0;
332 } else
333 return 1;
334}
335
336void
337oscore_cbor_get_string(const uint8_t **buffer, size_t *buf_len, char *str, size_t size) {
338 (void)buf_len;
339 for (size_t i = 0; i < size; i++) {
340 *str++ = (char)get_byte_inc(buffer, buf_len);
341 }
342}
343
344void
345oscore_cbor_get_array(const uint8_t **buffer, size_t *buf_len, uint8_t *arr, size_t size) {
346 (void)buf_len;
347 for (size_t i = 0; i < size; i++) {
348 *arr++ = get_byte_inc(buffer, buf_len);
349 }
350}
351
352/* oscore_cbor_get_string_array
353 * fills the the size and the array from the cbor element
354 */
355uint8_t
356oscore_cbor_get_string_array(const uint8_t **data, size_t *buf_len,
357 uint8_t **result,
358 size_t *len) {
359
360 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
361 *len = oscore_cbor_get_element_size(data, buf_len);
362 if (*len > *buf_len)
363 return 1;
364 *result = NULL;
365 void *rs = coap_malloc_type(COAP_STRING, *len);
366 *result = (uint8_t *)rs;
367 if (elem == CBOR_TEXT_STRING) {
368 oscore_cbor_get_string(data, buf_len, (char *)*result, *len);
369 return 0;
370 } else if (elem == CBOR_BYTE_STRING) {
371 oscore_cbor_get_array(data, buf_len, *result, *len);
372 return 0; /* all is well */
373 } else {
374 free(*result);
375 *result = NULL;
376 return 1; /* failure */
377 }
378}
379
380/* oscore_cbor_skip value
381 * returns number of CBOR bytes
382 */
383static size_t
384oscore_cbor_skip_value(const uint8_t **data, size_t *buf_len) {
385 uint8_t elem = oscore_cbor_get_next_element(data, buf_len);
386 uint8_t control = get_byte(data, buf_len) & 0x1f;
387 size_t nb = 0; /* number of elements in array or map */
388 size_t num = 0; /* number of bytes of length or number */
389 size_t size = 0; /* size of value to be skipped */
390 if (control < 0x18) {
391 num = 1;
392 } else {
393 control = control & 0x3;
394 num = 1 + (1 << control);
395 }
396 switch (elem) {
399 assert((*buf_len) >= num);
400 if (*buf_len < num)
401 return 0;
402 *buf_len -= num;
403 *data = *data + num;
404 size = num;
405 break;
406 case CBOR_BYTE_STRING:
407 case CBOR_TEXT_STRING:
408 size = num;
409 size += oscore_cbor_get_element_size(data, buf_len);
410 assert((*buf_len) >= (size - num));
411 if (*buf_len < size - num)
412 return 0;
413 *buf_len -= (size - num);
414 (*data) = (*data) + size - num;
415 break;
416 case CBOR_ARRAY:
417 nb = oscore_cbor_get_element_size(data, buf_len);
418 size = num;
419 for (uint16_t qq = 0; qq < nb; qq++)
420 size += oscore_cbor_skip_value(data, buf_len);
421 break;
422 case CBOR_MAP:
423 nb = oscore_cbor_get_element_size(data, buf_len);
424 size = num;
425 for (uint16_t qq = 0; qq < nb; qq++) {
426 size += oscore_cbor_skip_value(data, buf_len);
427 size += oscore_cbor_skip_value(data, buf_len);
428 }
429 break;
430 case CBOR_TAG:
431 assert((*buf_len) >= 1);
432 if (*buf_len < 1)
433 return 0;
434 *buf_len -= 1;
435 (*data)++;
436 size = 1;
437 break;
438 default:
439 return 0;
440 break;
441 } /* switch */
442 return size;
443}
444
445/* oscore_cbor_strip value
446 * strips the value of the cbor element into result
447 * and returns size
448 */
449uint8_t
450oscore_cbor_strip_value(const uint8_t **data, size_t *buf_len, uint8_t **result, size_t *len) {
451 const uint8_t *st_data = *data;
452 size_t size = oscore_cbor_skip_value(data, buf_len);
453 *result = coap_malloc_type(COAP_STRING, size);
454 for (uint16_t qq = 0; qq < size; qq++)
455 (*result)[qq] = st_data[qq];
456 *len = size;
457 return 0;
458}
459
460#else /* ! COAP_OSCORE_SUPPORT */
461
462#ifdef __clang__
463/* Make compilers happy that do not like empty modules. As this function is
464 * never used, we ignore -Wunused-function at the end of compiling this file
465 */
466#pragma GCC diagnostic ignored "-Wunused-function"
467#endif
468static inline void
469dummy(void) {
470}
471
472#endif /* ! COAP_OSCORE_SUPPORT */
Library specific build wrapper for coap_internal.h.
@ COAP_STRING
Definition coap_mem.h:33
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 NULL
Definition coap_option.h:30
#define coap_log_err(...)
Definition coap_debug.h:102
#define CBOR_BYTE_STRING
Definition oscore_cbor.h:64
size_t oscore_cbor_put_text(uint8_t **buffer, size_t *buf_size, const char *text, size_t text_len)
#define CBOR_TAG
Definition oscore_cbor.h:68
#define CBOR_NEGATIVE_INTEGER
Definition oscore_cbor.h:63
uint64_t oscore_cbor_get_element_size(const uint8_t **buffer, size_t *buf_size)
int64_t oscore_cbor_get_negative_integer(const uint8_t **buffer, size_t *buf_size)
#define CBOR_TEXT_STRING
Definition oscore_cbor.h:65
#define CBOR_SIMPLE_VALUE
Definition oscore_cbor.h:69
size_t oscore_cbor_put_number(uint8_t **buffer, size_t *buf_size, int64_t value)
size_t oscore_cbor_put_simple_value(uint8_t **buffer, size_t *buf_size, uint8_t value)
uint8_t oscore_cbor_get_string_array(const uint8_t **data, size_t *buf_size, uint8_t **result, size_t *len)
#define CBOR_UNSIGNED_INTEGER
Definition oscore_cbor.h:62
uint8_t oscore_cbor_strip_value(const uint8_t **data, size_t *buf_size, uint8_t **result, size_t *len)
size_t oscore_cbor_put_nil(uint8_t **buffer, size_t *buf_size)
void oscore_cbor_get_string(const uint8_t **buffer, size_t *buf_size, char *str, size_t size)
uint8_t oscore_cbor_get_simple_value(const uint8_t **data, size_t *buf_size, uint8_t *value)
size_t oscore_cbor_put_false(uint8_t **buffer, size_t *buf_size)
uint8_t oscore_cbor_get_next_element(const uint8_t **buffer, size_t *buf_size)
size_t oscore_cbor_put_negative(uint8_t **buffer, size_t *buf_size, int64_t value)
size_t oscore_cbor_put_true(uint8_t **buffer, size_t *buf_size)
size_t oscore_cbor_put_unsigned(uint8_t **buffer, size_t *buf_size, uint64_t value)
size_t oscore_cbor_put_bytes(uint8_t **buffer, size_t *buf_size, const uint8_t *bytes, size_t bytes_len)
void oscore_cbor_get_array(const uint8_t **buffer, size_t *buf_size, uint8_t *arr, size_t size)
uint64_t oscore_cbor_get_unsigned_integer(const uint8_t **buffer, size_t *buf_size)
uint8_t oscore_cbor_elem_contained(const uint8_t *data, size_t *buf_size, uint8_t *end)
uint8_t oscore_cbor_get_number(const uint8_t **data, size_t *buf_size, int64_t *value)
#define CBOR_MAP
Definition oscore_cbor.h:67
#define CBOR_ARRAY
Definition oscore_cbor.h:66
size_t oscore_cbor_put_array(uint8_t **buffer, size_t *buf_size, size_t elements)
size_t oscore_cbor_put_map(uint8_t **buffer, size_t *buf_size, size_t elements)
size_t oscore_cbor_put_tag(uint8_t **buffer, size_t *buf_size, uint64_t value)
static void dummy(void)