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